From 9ac2bf2aa0dddc3ef5d22a1842c92c646454485f Mon Sep 17 00:00:00 2001 From: proelements Date: Thu, 13 Nov 2025 15:18:34 +0200 Subject: [PATCH] v3.33.1 --- .gitattributes | 2 + .github/workflows/release.yaml | 22 + .gitignore | 41 + assets/css/admin.css | 787 + assets/css/admin.min.css | 2 + assets/css/app.css | 363 + assets/css/app.min.css | 2 + assets/css/conditionals/popup.css | 53 + assets/css/conditionals/popup.min.css | 1 + assets/css/conditionals/ribbon.css | 40 + assets/css/conditionals/ribbon.min.css | 1 + assets/css/conditionals/transitions.css | 111 + assets/css/conditionals/transitions.min.css | 1 + assets/css/editor.css | 593 + assets/css/editor.min.css | 2 + assets/css/modules/custom-code.css | 1961 ++ assets/css/modules/custom-code.min.css | 1 + assets/css/modules/loop-grid-cta.css | 164 + assets/css/modules/loop-grid-cta.min.css | 1 + assets/css/modules/motion-fx.css | 37 + assets/css/modules/motion-fx.min.css | 1 + assets/css/modules/notes.css | 24 + assets/css/modules/notes.min.css | 1 + assets/css/modules/sticky.css | 12 + assets/css/modules/sticky.min.css | 1 + assets/css/preview.css | 228 + assets/css/preview.min.css | 2 + .../widget-animated-headline-rtl.min.css | 1 + .../widget-animated-headline.min.css | 1 + .../widget-call-to-action-rtl.min.css | 1 + .../templates/widget-call-to-action.min.css | 1 + .../widget-code-highlight-rtl.min.css | 1 + .../templates/widget-code-highlight.min.css | 1 + .../css/templates/widget-flip-box-rtl.min.css | 1 + assets/css/templates/widget-flip-box.min.css | 1 + .../templates/widget-loop-grid-rtl.min.css | 1 + assets/css/templates/widget-loop-grid.min.css | 1 + .../templates/widget-mega-menu-rtl.min.css | 1 + assets/css/templates/widget-mega-menu.min.css | 1 + .../css/templates/widget-nav-menu-rtl.min.css | 1 + assets/css/templates/widget-nav-menu.min.css | 1 + .../css/templates/widget-slides-rtl.min.css | 1 + assets/css/templates/widget-slides.min.css | 1 + .../widget-testimonial-carousel-rtl.min.css | 1 + .../widget-testimonial-carousel.min.css | 1 + .../widget-video-playlist-rtl.min.css | 1 + .../templates/widget-video-playlist.min.css | 1 + .../widget-woocommerce-cart-rtl.min.css | 1 + .../templates/widget-woocommerce-cart.min.css | 1 + ...dget-woocommerce-checkout-page-rtl.min.css | 1 + .../widget-woocommerce-checkout-page.min.css | 1 + .../widget-woocommerce-menu-cart-rtl.min.css | 1 + .../widget-woocommerce-menu-cart.min.css | 1 + .../widget-woocommerce-my-account-rtl.min.css | 1 + .../widget-woocommerce-my-account.min.css | 1 + ...oocommerce-product-add-to-cart-rtl.min.css | 1 + ...et-woocommerce-product-add-to-cart.min.css | 1 + ...t-woocommerce-products-archive-rtl.min.css | 1 + ...idget-woocommerce-products-archive.min.css | 1 + ...t-woocommerce-purchase-summary-rtl.min.css | 1 + ...idget-woocommerce-purchase-summary.min.css | 1 + assets/css/widget-_compatibility-rtl.min.css | 2 + assets/css/widget-_compatibility.min.css | 2 + .../css/widget-_overlay-animation-rtl.min.css | 2 + assets/css/widget-_overlay-animation.min.css | 2 + assets/css/widget-_sticky-rtl.min.css | 2 + assets/css/widget-_sticky.min.css | 2 + .../css/widget-animated-headline-rtl.min.css | 2 + assets/css/widget-animated-headline.min.css | 2 + assets/css/widget-author-box-rtl.min.css | 2 + assets/css/widget-author-box.min.css | 2 + assets/css/widget-blockquote-rtl.min.css | 2 + assets/css/widget-blockquote.min.css | 2 + assets/css/widget-breadcrumbs-rtl.min.css | 2 + assets/css/widget-breadcrumbs.min.css | 2 + assets/css/widget-call-to-action-rtl.min.css | 2 + assets/css/widget-call-to-action.min.css | 2 + .../widget-carousel-module-base-rtl.min.css | 2 + .../css/widget-carousel-module-base.min.css | 2 + assets/css/widget-code-highlight-rtl.min.css | 2 + assets/css/widget-code-highlight.min.css | 2 + assets/css/widget-countdown-rtl.min.css | 2 + assets/css/widget-countdown.min.css | 2 + assets/css/widget-flip-box-rtl.min.css | 2 + assets/css/widget-flip-box.min.css | 2 + assets/css/widget-form-rtl.min.css | 2 + assets/css/widget-form.min.css | 2 + assets/css/widget-gallery-rtl.min.css | 2 + assets/css/widget-gallery.min.css | 2 + assets/css/widget-hotspot-rtl.min.css | 2 + assets/css/widget-hotspot.min.css | 2 + assets/css/widget-login-rtl.min.css | 2 + assets/css/widget-login.min.css | 2 + assets/css/widget-loop-canvas-rtl.min.css | 2 + assets/css/widget-loop-canvas.min.css | 2 + assets/css/widget-loop-carousel-rtl.min.css | 2 + assets/css/widget-loop-carousel.min.css | 2 + assets/css/widget-loop-common-rtl.min.css | 2 + assets/css/widget-loop-common.min.css | 2 + assets/css/widget-loop-filter-rtl.min.css | 2 + assets/css/widget-loop-filter.min.css | 2 + assets/css/widget-loop-grid-rtl.min.css | 2 + assets/css/widget-loop-grid.min.css | 2 + assets/css/widget-lottie-rtl.min.css | 2 + assets/css/widget-lottie.min.css | 2 + assets/css/widget-media-carousel-rtl.min.css | 2 + assets/css/widget-media-carousel.min.css | 2 + assets/css/widget-mega-menu-rtl.min.css | 2 + assets/css/widget-mega-menu.min.css | 2 + assets/css/widget-nav-menu-rtl.min.css | 2 + assets/css/widget-nav-menu.min.css | 2 + assets/css/widget-nested-carousel-rtl.min.css | 2 + assets/css/widget-nested-carousel.min.css | 2 + assets/css/widget-off-canvas-rtl.min.css | 2 + assets/css/widget-off-canvas.min.css | 2 + assets/css/widget-post-info-rtl.min.css | 2 + assets/css/widget-post-info.min.css | 2 + assets/css/widget-post-navigation-rtl.min.css | 2 + assets/css/widget-post-navigation.min.css | 2 + assets/css/widget-posts-rtl.min.css | 2 + assets/css/widget-posts.min.css | 2 + assets/css/widget-price-list-rtl.min.css | 2 + assets/css/widget-price-list.min.css | 2 + assets/css/widget-price-table-rtl.min.css | 2 + assets/css/widget-price-table.min.css | 2 + .../css/widget-progress-tracker-rtl.min.css | 2 + assets/css/widget-progress-tracker.min.css | 2 + assets/css/widget-reviews-rtl.min.css | 2 + assets/css/widget-reviews.min.css | 2 + assets/css/widget-search-form-rtl.min.css | 2 + assets/css/widget-search-form.min.css | 2 + assets/css/widget-search-rtl.min.css | 2 + assets/css/widget-search.min.css | 2 + assets/css/widget-share-buttons-rtl.min.css | 2 + assets/css/widget-share-buttons.min.css | 2 + assets/css/widget-sitemap-rtl.min.css | 2 + assets/css/widget-sitemap.min.css | 2 + assets/css/widget-slides-rtl.min.css | 2 + assets/css/widget-slides.min.css | 2 + assets/css/widget-social-rtl.min.css | 2 + assets/css/widget-social.min.css | 2 + .../css/widget-table-of-contents-rtl.min.css | 2 + assets/css/widget-table-of-contents.min.css | 2 + .../widget-testimonial-carousel-rtl.min.css | 2 + .../css/widget-testimonial-carousel.min.css | 2 + assets/css/widget-video-playlist-rtl.min.css | 2 + assets/css/widget-video-playlist.min.css | 2 + .../css/widget-woocommerce-cart-rtl.min.css | 2 + assets/css/widget-woocommerce-cart.min.css | 2 + .../widget-woocommerce-categories-rtl.min.css | 2 + .../css/widget-woocommerce-categories.min.css | 2 + ...dget-woocommerce-checkout-page-rtl.min.css | 2 + .../widget-woocommerce-checkout-page.min.css | 2 + .../widget-woocommerce-menu-cart-rtl.min.css | 2 + .../css/widget-woocommerce-menu-cart.min.css | 2 + .../widget-woocommerce-my-account-rtl.min.css | 2 + .../css/widget-woocommerce-my-account.min.css | 2 + .../widget-woocommerce-notices-rtl.min.css | 2 + assets/css/widget-woocommerce-notices.min.css | 2 + ...oocommerce-product-add-to-cart-rtl.min.css | 2 + ...et-woocommerce-product-add-to-cart.min.css | 2 + ...product-additional-information-rtl.min.css | 2 + ...rce-product-additional-information.min.css | 2 + ...-woocommerce-product-data-tabs-rtl.min.css | 2 + ...dget-woocommerce-product-data-tabs.min.css | 2 + ...get-woocommerce-product-images-rtl.min.css | 2 + .../widget-woocommerce-product-images.min.css | 2 + ...idget-woocommerce-product-meta-rtl.min.css | 2 + .../widget-woocommerce-product-meta.min.css | 2 + ...dget-woocommerce-product-price-rtl.min.css | 2 + .../widget-woocommerce-product-price.min.css | 2 + ...get-woocommerce-product-rating-rtl.min.css | 2 + .../widget-woocommerce-product-rating.min.css | 2 + ...t-woocommerce-products-archive-rtl.min.css | 2 + ...idget-woocommerce-products-archive.min.css | 2 + .../widget-woocommerce-products-rtl.min.css | 2 + .../css/widget-woocommerce-products.min.css | 2 + ...t-woocommerce-purchase-summary-rtl.min.css | 2 + ...idget-woocommerce-purchase-summary.min.css | 2 + assets/css/woocommerce-notices.css | 302 + assets/css/woocommerce-notices.min.css | 2 + assets/data/responsive-widgets.json | 1 + .../images/announcements/license-expired.png | Bin 0 -> 15106 bytes assets/images/logo-placeholder.png | Bin 0 -> 4059 bytes assets/js/0726b2d81686a5392236.bundle.min.js | 3 + ...b2d81686a5392236.bundle.min.js.LICENSE.txt | 1 + assets/js/36c2990924ec9596ffad.bundle.js | 178 + assets/js/8b11be0d97d58e135d30.bundle.js | 1364 ++ assets/js/admin.js | 1735 ++ assets/js/admin.min.js | 2 + ...ination.2090b5f4906bcda1dcc2.bundle.min.js | 2 + ...-pagination.2390838f542f1a8d5ed4.bundle.js | 146 + ...ed-headline.32baaa2ad2ea939224d5.bundle.js | 299 + ...eadline.c009d6fa482515df23f8.bundle.min.js | 2 + assets/js/app.js | 10192 ++++++++++ assets/js/app.min.js | 2 + ...e-posts.16a93245d08246e5e540.bundle.min.js | 2 + ...chive-posts.6e398ddd4a81a78bcea3.bundle.js | 401 + .../carousel.298f1fc9c115422aad0e.bundle.js | 294 + ...arousel.3620fca501cb18163600.bundle.min.js | 2 + ...e-highlight.7121ad6fca6bf899bbb5.bundle.js | 32 + ...ghlight.b9addbc842a50347c9ab.bundle.min.js | 2 + ...-var-10.16cf733dc3d3b250fef4.bundle.min.js | 2 + ...tons-var-10.44dafff87cd10dfffc68.bundle.js | 411 + ...act-buttons.23b3f042ed41cf9221f4.bundle.js | 659 + ...buttons.99a987d66bcc2ade0ee6.bundle.min.js | 2 + ...untdown.0e9e688751d29d07a8d3.bundle.min.js | 2 + .../countdown.6e87ca40d36793d92aea.bundle.js | 148 + assets/js/custom-code.js | 2706 +++ assets/js/custom-code.min.js | 2 + assets/js/d241154d3774d66da9eb.bundle.min.js | 2 + assets/js/display-conditions.js | 5598 +++++ assets/js/display-conditions.min.js | 2 + assets/js/e8eba20060a4b0fa29dc.bundle.js | 347 + assets/js/editor.js | 10052 +++++++++ assets/js/editor.min.js | 2 + assets/js/elements-handlers.js | 2791 +++ assets/js/elements-handlers.min.js | 2 + ...s-var-2.75c36e8b0bacbac6105e.bundle.min.js | 2 + ...-bars-var-2.fa9c6b6e6aaeb43504f2.bundle.js | 328 + ...s-var-3.cdf99fd0b063a0032d53.bundle.min.js | 2 + ...-bars-var-3.ce31fbd73759a9439cbf.bundle.js | 323 + assets/js/form-submission-admin.js | 7130 +++++++ assets/js/form-submission-admin.min.js | 2 + assets/js/form.151b991a4cbdda620c22.bundle.js | 984 + .../form.71055747203b48a65a24.bundle.min.js | 2 + assets/js/frontend.js | 1459 ++ assets/js/frontend.min.js | 2 + ...gallery.06be1c07b9901f53d709.bundle.min.js | 2 + .../js/gallery.ac8ddd9e62465c5cdb2d.bundle.js | 230 + ...hotspot.5033ed75928eff79cb95.bundle.min.js | 2 + .../js/hotspot.5e711b7707a884acf3f1.bundle.js | 121 + ...szip.vendor.a3c65615c1de5560962d.bundle.js | 27 + ....vendor.eba4ace24dcc63eadac0.bundle.min.js | 3 + ...ace24dcc63eadac0.bundle.min.js.LICENSE.txt | 11 + ...ad-more.8b46f464e573feab5dd7.bundle.min.js | 2 + .../load-more.f5ecc1c66872d0bd2d17.bundle.js | 226 + ...op-carousel.122d0b9321a9edad91b0.bundle.js | 66 + ...arousel.cd9a95b2e4dd2a239b81.bundle.min.js | 2 + ...lter-editor.46a4c013b80a381a50c9.bundle.js | 191 + ...-editor.be7377d717e2499f4676.bundle.min.js | 2 + assets/js/loop.43307e757bd5a39f14cd.bundle.js | 460 + .../loop.89cc81d2188312a17a17.bundle.min.js | 2 + .../js/lottie.824e2adeeca89f4297c7.bundle.js | 662 + .../lottie.a287ccfe024bea61e651.bundle.min.js | 2 + ...arousel.8d26e5df1a1527329fde.bundle.min.js | 2 + ...ia-carousel.8f7b71d582be9d9410fe.bundle.js | 386 + ...menu-editor.be91c0f96af4174d83d0.bundle.js | 522 + ...-editor.da6571bb00aaa3092eab.bundle.min.js | 2 + ...tch-content.0d76e4a3b7bf65ff6f9b.bundle.js | 51 + ...content.480e081cebe071d683e8.bundle.min.js | 2 + .../mega-menu.595ee0dffef2bd038c6b.bundle.js | 1178 ++ ...ga-menu.82093824ddb3f5531ab4.bundle.min.js | 2 + ...ard-handler.efa6d39b4096f1de6f4d.bundle.js | 321 + ...handler.f0362773c21105d2c65c.bundle.min.js | 2 + ...av-menu.8521a0597c50611efdc6.bundle.min.js | 2 + .../nav-menu.fd37f05286fae9cd6d0c.bundle.js | 244 + ...usel-editor.0df35e0e1a284d4bd18b.bundle.js | 51 + ...-editor.6d7500036d0766bbe2fc.bundle.min.js | 2 + ...ed-carousel.ce414a51f188ccf670ee.bundle.js | 186 + ...arousel.db797a097fdc5532ef4a.bundle.min.js | 2 + assets/js/notes/363.min.js | 2 + assets/js/notes/363.min.js.LICENSE.txt | 27 + assets/js/notes/notes-app-initiator.js | 374 + assets/js/notes/notes-app-initiator.min.js | 1 + assets/js/notes/notes-app.js | 8304 ++++++++ assets/js/notes/notes-app.min.js | 1638 ++ assets/js/notes/notes.js | 4762 +++++ assets/js/notes/notes.min.js | 2 + assets/js/notes/notes.min.js.LICENSE.txt | 17 + ...odule_js-node_modules_radix-ui_r-e4587e.js | 16958 ++++++++++++++++ ...-editor.9d374fa1254f9efc259e.bundle.min.js | 2 + ...nvas-editor.d30e3b4fb19101e5ff36.bundle.js | 157 + ...-canvas.137463f629e2b7cbaf02.bundle.min.js | 2 + .../off-canvas.ff4d0ebaaec46fc178b2.bundle.js | 289 + .../editor-controls-extended.asset.php | 17 + .../editor-controls-extended.js | 1804 ++ .../editor-controls-extended.min.js | 65 + .../editor-controls-extended.strings.js | 73 + .../editor-documents-extended.asset.php | 20 + .../editor-documents-extended.js | 625 + .../editor-documents-extended.min.js | 1 + .../editor-documents-extended.strings.js | 3 + .../editor-editing-panel-extended.asset.php | 19 + .../editor-editing-panel-extended.js | 347 + .../editor-editing-panel-extended.min.js | 1 + .../editor-editing-panel-extended.strings.js | 2 + .../editor-notes/editor-notes.asset.php | 16 + .../js/packages/editor-notes/editor-notes.js | 205 + .../packages/editor-notes/editor-notes.min.js | 1 + .../editor-notes/editor-notes.strings.js | 1 + .../editor-site-navigation-extended.asset.php | 14 + .../editor-site-navigation-extended.js | 162 + .../editor-site-navigation-extended.min.js | 1 + ...editor-site-navigation-extended.strings.js | 0 .../editor-variables-extended.asset.php | 19 + .../editor-variables-extended.js | 611 + .../editor-variables-extended.min.js | 1 + .../editor-variables-extended.strings.js | 0 assets/js/page-transitions.js | 1267 ++ assets/js/page-transitions.min.js | 2 + ...ypal-button.55ffb013a3fe565f55a5.bundle.js | 51 + ...-button.f4f64e46173f50701949.bundle.min.js | 2 + .../js/popup.996738ad83c089bcc0b9.bundle.js | 51 + .../popup.f7b15b2ca565b152bf98.bundle.min.js | 2 + ...rtfolio.4cd5da34009c30cb5d70.bundle.min.js | 2 + .../portfolio.5727b56368be256d0893.bundle.js | 358 + .../posts.aec59265318492b89cb5.bundle.min.js | 2 + .../js/posts.e99f84b83c36d4568ffe.bundle.js | 170 + assets/js/preview.js | 2056 ++ assets/js/preview.min.js | 2 + ...add-to-cart.0c33bb82cd57e51665f9.bundle.js | 196 + ...to-cart.c32f5d5e404511d68720.bundle.min.js | 2 + ...tracker.8cccdda9737c272489fc.bundle.min.js | 2 + ...ess-tracker.fd1d31a26340ed74e10a.bundle.js | 202 + assets/js/screenshot.js | 385 + assets/js/screenshot.min.js | 2 + ...search-form.8941aba5c12cdb05fb7c.bundle.js | 121 + ...ch-form.b7065999d77832a1b764.bundle.min.js | 2 + .../js/search.1a4ea982239b5f5db501.bundle.js | 527 + .../search.5d88e65c03029f91931d.bundle.min.js | 2 + ...buttons.63d984f8c96d1e053bc0.bundle.min.js | 2 + ...are-buttons.fda49c1691f4a352c7ef.bundle.js | 118 + .../js/slides.bcd16bbde90338846bd7.bundle.js | 223 + .../slides.c0029640cbdb48199471.bundle.min.js | 2 + .../js/social.83aec5578e50a413de57.bundle.js | 68 + .../social.d71d263bd937f0906192.bundle.min.js | 2 + ...-button.49130d6eecb5ebc8afbd.bundle.min.js | 2 + ...ripe-button.cb4b1cf19f1c46430f76.bundle.js | 121 + ...ontents.3be1ab725f562d10dd86.bundle.min.js | 2 + ...of-contents.6ac58abccb098fb35213.bundle.js | 409 + ...-filter.a32526f3e4a201b5fce1.bundle.min.js | 2 + ...nomy-filter.f3f2746a00fed7447ff5.bundle.js | 414 + ...eo-playlist.7140c18aeaebfda82118.bundle.js | 1315 ++ ...laylist.909c41acbc73cb741e9d.bundle.min.js | 2 + assets/js/webpack-pro.runtime.js | 317 + assets/js/webpack-pro.runtime.min.js | 2 + ...mmerce-cart.3e38c78b18f28be95e9d.bundle.js | 283 + ...ce-cart.480d117b95956d1f28a5.bundle.min.js | 2 + ...eckout-page.48b0561b8ee895da5af5.bundle.js | 332 + ...ut-page.6ba1f1f2aa99210fa1cf.bundle.min.js | 2 + ...nu-cart.54f2e75f6769dce707e2.bundle.min.js | 2 + ...e-menu-cart.a0d098b5b49cb56bf258.bundle.js | 235 + ...-my-account.7c01b4a03ae07847db06.bundle.js | 290 + ...account.d54826f355f9822b0ec0.bundle.min.js | 2 + ...notices.00f9132bbbd683277a27.bundle.min.js | 2 + ...rce-notices.c1b466cde2ea03db7d6e.bundle.js | 75 + ...ase-summary.2ebf26dca7d446fdd128.bundle.js | 202 + ...summary.88a2d8ca449739e34f9f.bundle.min.js | 2 + assets/lib/dom-to-image/js/dom-to-image.js | 777 + .../lib/dom-to-image/js/dom-to-image.min.js | 9 + assets/lib/font-awesome-pro/brands.js | 467 + assets/lib/font-awesome-pro/duotone.js | 1857 ++ assets/lib/font-awesome-pro/light.js | 1857 ++ assets/lib/font-awesome-pro/regular.js | 1857 ++ assets/lib/font-awesome-pro/solid.js | 1857 ++ assets/lib/html2canvas/js/html2canvas.js | 7033 +++++++ assets/lib/html2canvas/js/html2canvas.min.js | 20 + assets/lib/instant-page/instant-page.js | 232 + assets/lib/instant-page/instant-page.min.js | 2 + assets/lib/lottie/lottie.js | 14561 +++++++++++++ assets/lib/lottie/lottie.min.js | 19 + assets/lib/smartmenus/jquery.smartmenus.js | 1225 ++ .../lib/smartmenus/jquery.smartmenus.min.js | 3 + assets/lib/sticky/jquery.sticky.js | 395 + assets/lib/sticky/jquery.sticky.min.js | 1 + base/base-carousel-trait.php | 1426 ++ base/base-widget-trait.php | 18 + base/base-widget.php | 16 + base/module-base.php | 12 + base/on-import-trait.php | 134 + changelog.txt | 1482 ++ core/admin/action-links.php | 27 + core/admin/admin.php | 121 + core/admin/canary-deployment.php | 25 + core/admin/post-status.php | 9 + core/app/app.php | 142 + core/app/assets/js/hooks/use-feature-lock.js | 22 + core/app/assets/js/index.js | 5 + core/app/assets/js/ui/connect-button.js | 48 + core/app/assets/js/utils.js | 29 + core/app/assets/styles/app-imports.scss | 8 + .../customization-list-setting-section.js | 167 + .../customization-setting-section.js | 87 + .../components/customization-sub-setting.js | 77 + .../assets/js/components/index.js | 3 + .../kit-content-customization-dialog.js | 498 + .../js/components/kit-customization-dialog.js | 67 + .../kit-settings-customization-dialog.js | 245 + .../kit-templates-customization-dialog.js | 196 + .../components/theme-builder-customization.js | 257 + .../js/components/upgrade-notice-banner.js | 49 + .../assets/js/components/upgrade-tooltip.js | 51 + .../js/components/upgrade-version-banner.js | 55 + .../assets/js/hooks/use-custom-post-types.js | 25 + ...use-kit-customization-custom-post-types.js | 47 + .../js/hooks/use-kit-customization-pages.js | 30 + .../hooks/use-kit-customization-taxonomies.js | 39 + .../assets/js/hooks/use-pages.js | 93 + .../assets/js/hooks/use-taxonomies.js | 75 + .../assets/js/hooks/use-tier.js | 8 + .../assets/js/module.js | 38 + .../assets/js/utils/analytics-transformer.js | 41 + .../import-export-customization/module.php | 173 + .../runners/base/export-runner-base.php | 19 + .../runners/base/import-runner-base.php | 20 + .../runners/export/site-settings.php | 75 + .../runners/export/taxonomies.php | 88 + .../runners/export/templates.php | 30 + .../runners/import/elementor-content.php | 37 + .../runners/import/site-settings.php | 107 + .../runners/import/taxonomies.php | 41 + .../runners/import/templates.php | 48 + .../runners/traits/site-settings-helpers.php | 136 + core/app/modules/import-export/module.php | 70 + .../runners/export/templates.php | 65 + .../runners/import/templates.php | 130 + .../runners/revert/templates.php | 62 + core/app/modules/kit-library/module.php | 89 + core/app/modules/onboarding/module.php | 73 + .../assets/js/atoms/indicator-bullet.js | 15 + .../assets/js/atoms/indicator-bullet.scss | 34 + .../assets/js/atoms/preview-iframe.js | 37 + .../assets/js/atoms/preview-iframe.scss | 17 + .../assets/js/context/base-context.js | 48 + .../assets/js/context/conditions.js | 307 + .../assets/js/context/models/condition.js | 72 + .../js/context/services/conditions-config.js | 130 + .../assets/js/context/templates.js | 152 + .../js/data/commands/conditions-config.js | 9 + .../assets/js/data/commands/index.js | 4 + .../templates-conditions-conflicts.js | 9 + .../js/data/commands/templates-conditions.js | 9 + .../assets/js/data/commands/templates.js | 9 + .../site-editor/assets/js/data/component.js | 13 + .../modules/site-editor/assets/js/editor.js | 14 + .../js/hooks/use-templates-screenshot.js | 54 + .../assets/js/molecules/back-button.js | 24 + .../assets/js/molecules/back-button.scss | 8 + .../assets/js/molecules/site-template-body.js | 33 + .../js/molecules/site-template-footer.js | 23 + .../js/molecules/site-template-header.js | 47 + .../js/molecules/site-template-thumbnail.js | 28 + .../assets/js/molecules/site-template.js | 59 + .../assets/js/molecules/site-template.scss | 117 + .../assets/js/organisms/site-templates.js | 97 + .../site-editor/assets/js/pages/add-new.js | 53 + .../site-editor/assets/js/pages/add-new.scss | 7 + .../conditions/condition-button-portal.js | 22 + .../pages/conditions/condition-conflicts.js | 36 + .../js/pages/conditions/condition-name.js | 28 + .../js/pages/conditions/condition-sub-id.js | 85 + .../js/pages/conditions/condition-sub.js | 28 + .../js/pages/conditions/condition-type.js | 40 + .../js/pages/conditions/conditions-api.scss | 96 + .../js/pages/conditions/conditions-rows.js | 102 + .../assets/js/pages/conditions/conditions.js | 44 + .../js/pages/conditions/conditions.scss | 183 + .../site-editor/assets/js/pages/import.js | 119 + .../assets/js/pages/template-type.js | 37 + .../assets/js/pages/template-type.scss | 13 + .../site-editor/assets/js/pages/templates.js | 22 + .../assets/js/part-actions/dialog-delete.js | 38 + .../assets/js/part-actions/dialog-rename.js | 56 + .../js/part-actions/dialogs-and-buttons.js | 79 + .../site-editor/assets/js/site-editor.js | 91 + .../site-editor/assets/js/site-editor.scss | 22 + .../modules/site-editor/data/controller.php | 26 + .../data/endpoints/base-endpoint.php | 23 + .../data/endpoints/conditions-config.php | 23 + .../data/endpoints/template-types.php | 25 + .../templates-conditions-conflicts.php | 27 + .../data/endpoints/templates-conditions.php | 85 + .../site-editor/data/endpoints/templates.php | 238 + .../data/responses/lock-error-response.php | 26 + core/app/modules/site-editor/module.php | 221 + .../render-mode-template-preview.php | 48 + core/behaviors/feature-lock.php | 58 + core/behaviors/temp-lock-behavior.php | 39 + core/compatibility/compatibility.php | 25 + core/connect/apps/activate.php | 20 + core/connect/manager.php | 28 + core/data/controller.php | 33 + core/data/endpoints/base.php | 28 + core/data/endpoints/refresh-base.php | 87 + core/data/interfaces/endpoint.php | 18 + core/database/base-database-updater.php | 127 + core/database/base-migration.php | 182 + core/database/join-clause.php | 78 + core/database/model-base.php | 160 + core/database/model-query-builder.php | 100 + core/database/query-builder.php | 1342 ++ core/editor/editor.php | 189 + core/editor/notice-bar.php | 17 + core/editor/promotion.php | 34 + core/editor/template.php | 16 + core/integrations/actions/action-base.php | 47 + .../actions/email/email-address.php | 50 + .../actions/email/email-message.php | 239 + core/integrations/actions/email/email.php | 128 + .../exceptions/action-failed-exception.php | 18 + .../action-validation-failed-exception.php | 18 + .../exceptions/exception-base.php | 70 + core/integrations/integrations-manager.php | 112 + .../isolation/wordpress-adapter-interface.php | 12 + core/isolation/wordpress-adapter.php | 30 + core/maintenance.php | 19 + core/modules-manager.php | 122 + core/notifications/notification.php | 29 + core/notifications/notifications-manager.php | 30 + core/notifications/traits/notifiable.php | 30 + core/php-api.php | 23 + core/preview/preview.php | 32 + core/security/access-control.php | 39 + core/security/capability.php | 20 + core/upgrade/manager.php | 43 + core/upgrade/upgrades.php | 1263 ++ core/utils.php | 454 + core/utils/abtest.php | 40 + core/utils/collection.php | 79 + core/utils/hints.php | 100 + core/utils/registrar.php | 68 + data/base/controller.php | 13 + data/http-status.php | 23 + license.txt | 26 + license/admin.php | 91 + license/api.php | 391 + license/data/controller.php | 19 + license/data/endpoints/get-tier-features.php | 48 + modules/admin-top-bar/module.php | 53 + modules/animated-headline/module.php | 53 + .../widgets/animated-headline.php | 680 + modules/announcements/module.php | 29 + .../triggers/is-license-expired.php | 37 + .../custom-fonts-menu-item.php | 32 + .../custom-fonts-promotion-menu-item.php | 67 + .../custom-icons-menu-item.php | 33 + .../custom-icons-promotion-menu-item.php | 67 + .../asset-types/fonts-manager.php | 690 + .../asset-types/fonts/custom-fonts.php | 664 + .../export-runner.php | 118 + .../import-export-customization.php | 25 + .../import-runner.php | 136 + .../revert-runner.php | 81 + .../fonts/import-export/export-runner.php | 113 + .../fonts/import-export/import-export.php | 25 + .../fonts/import-export/import-runner.php | 134 + .../fonts/import-export/revert-runner.php | 81 + .../asset-types/fonts/typekit-fonts.php | 262 + .../asset-types/icons-manager.php | 255 + .../asset-types/icons/custom-icons.php | 503 + .../asset-types/icons/font-awesome-pro.php | 161 + .../asset-types/icons/icon-sets/fontastic.php | 76 + .../asset-types/icons/icon-sets/fontello.php | 79 + .../asset-types/icons/icon-sets/icomoon.php | 76 + .../icons/icon-sets/icon-set-base.php | 254 + .../export-runner.php | 102 + .../import-export-customization.php | 25 + .../import-runner.php | 135 + .../revert-runner.php | 85 + .../icons/import-export/export-runner.php | 97 + .../icons/import-export/import-export.php | 25 + .../icons/import-export/import-runner.php | 133 + .../icons/import-export/revert-runner.php | 85 + .../asset-types/icons/templates.php | 21 + .../traits/external-attachment-trait.php | 76 + .../assets-manager/classes/assets-base.php | 394 + modules/assets-manager/classes/font-base.php | 50 + modules/assets-manager/module.php | 53 + modules/attributes/module.php | 77 + modules/blockquote/module.php | 53 + modules/blockquote/widgets/blockquote.php | 1007 + modules/call-to-action/module.php | 76 + .../call-to-action/widgets/call-to-action.php | 2041 ++ modules/carousel/module.php | 75 + modules/carousel/widgets/base.php | 669 + modules/carousel/widgets/media-carousel.php | 865 + modules/carousel/widgets/reviews.php | 921 + .../carousel/widgets/testimonial-carousel.php | 752 + modules/checklist/module.php | 54 + modules/checklist/steps/setup-header.php | 44 + modules/cloud-library/module.php | 54 + modules/code-highlight/module.php | 65 + .../code-highlight/widgets/code-highlight.php | 316 + .../compatibility-tag-component.php | 45 + modules/compatibility-tag/module.php | 39 + modules/countdown/module.php | 53 + modules/countdown/widgets/countdown.php | 878 + modules/custom-attributes/module.php | 185 + .../custom-code-menu-item.php | 36 + modules/custom-code/custom-code-metabox.php | 426 + modules/custom-code/document.php | 101 + .../export-runner.php | 79 + .../import-export-customization.php | 25 + .../import-runner.php | 140 + .../revert-runner.php | 37 + .../import-export/export-runner.php | 78 + .../import-export/import-export.php | 25 + .../import-export/import-runner.php | 139 + .../import-export/revert-runner.php | 38 + modules/custom-code/module.php | 538 + .../settings-custom-css-pro.php | 24 + modules/custom-css/module.php | 185 + .../classes/and-condition.php | 49 + .../classes/cache-notice.php | 22 + .../classes/comparator-provider.php | 58 + .../classes/comparators-checker.php | 127 + .../classes/conditions-manager.php | 203 + .../custom-fields-data-provider.php | 81 + .../classes/dynamic-tags/data-provider.php | 14 + .../dynamic-tags-data-provider.php | 102 + .../classes/or-condition.php | 40 + .../archive-of-author-condition.php | 77 + .../archive-of-category-condition.php | 36 + .../conditions/archive-of-tag-condition.php | 35 + .../base/archive-condition-base.php | 78 + .../conditions/base/condition-base.php | 53 + .../conditions/base/date-condition-base.php | 94 + .../conditions/base/title-condition-base.php | 53 + .../conditions/current-date-condition.php | 37 + .../date-of-modification-condition.php | 41 + .../conditions/date-of-publish-condition.php | 40 + .../conditions/day-of-the-week-condition.php | 78 + .../conditions/dynamic-tags-condition.php | 110 + .../conditions/featured-image-condition.php | 63 + .../conditions/from-url-condition.php | 62 + .../conditions/in-categories-condition.php | 77 + .../conditions/in-tags-condition.php | 73 + .../conditions/login-status-condition.php | 59 + .../conditions/page-author-condition.php | 76 + .../conditions/page-parent-condition.php | 74 + .../conditions/page-title-condition.php | 27 + .../conditions/post-author-condition.php | 13 + .../post-number-of-comments-condition.php | 62 + .../conditions/post-title-condition.php | 26 + .../conditions/time-of-the-day-condition.php | 111 + .../user-registration-date-condition.php | 40 + .../conditions/user-role-condition.php | 70 + modules/display-conditions/module.php | 261 + .../acf/dynamic-value-provider.php | 63 + modules/dynamic-tags/acf/module.php | 240 + modules/dynamic-tags/acf/tags/acf-color.php | 59 + .../dynamic-tags/acf/tags/acf-date-time.php | 97 + modules/dynamic-tags/acf/tags/acf-file.php | 31 + modules/dynamic-tags/acf/tags/acf-gallery.php | 65 + modules/dynamic-tags/acf/tags/acf-image.php | 99 + modules/dynamic-tags/acf/tags/acf-number.php | 58 + modules/dynamic-tags/acf/tags/acf-text.php | 137 + modules/dynamic-tags/acf/tags/acf-url.php | 116 + .../components/author-meta-filter.php | 73 + modules/dynamic-tags/module.php | 162 + .../pods/dynamic-value-provider.php | 59 + modules/dynamic-tags/pods/module.php | 132 + modules/dynamic-tags/pods/tags/pods-base.php | 64 + .../dynamic-tags/pods/tags/pods-date-time.php | 95 + modules/dynamic-tags/pods/tags/pods-date.php | 96 + .../dynamic-tags/pods/tags/pods-gallery.php | 83 + modules/dynamic-tags/pods/tags/pods-image.php | 87 + .../dynamic-tags/pods/tags/pods-numeric.php | 39 + modules/dynamic-tags/pods/tags/pods-text.php | 55 + modules/dynamic-tags/pods/tags/pods-url.php | 95 + .../dynamic-tags/tags/archive-description.php | 46 + modules/dynamic-tags/tags/archive-meta.php | 66 + modules/dynamic-tags/tags/archive-title.php | 77 + modules/dynamic-tags/tags/archive-url.php | 38 + modules/dynamic-tags/tags/author-info.php | 69 + modules/dynamic-tags/tags/author-meta.php | 31 + modules/dynamic-tags/tags/author-name.php | 32 + .../tags/author-profile-picture.php | 41 + modules/dynamic-tags/tags/author-url.php | 64 + modules/dynamic-tags/tags/base/author-tag.php | 77 + modules/dynamic-tags/tags/base/data-tag.php | 14 + modules/dynamic-tags/tags/base/tag-trait.php | 42 + modules/dynamic-tags/tags/base/tag.php | 16 + modules/dynamic-tags/tags/comments-number.php | 102 + modules/dynamic-tags/tags/comments-url.php | 32 + modules/dynamic-tags/tags/contact-url.php | 461 + .../dynamic-tags/tags/current-date-time.php | 120 + .../dynamic-tags/tags/featured-image-data.php | 121 + modules/dynamic-tags/tags/internal-url.php | 143 + modules/dynamic-tags/tags/lightbox.php | 174 + modules/dynamic-tags/tags/page-title.php | 75 + .../dynamic-tags/tags/post-custom-field.php | 118 + modules/dynamic-tags/tags/post-date.php | 102 + modules/dynamic-tags/tags/post-excerpt.php | 107 + .../dynamic-tags/tags/post-featured-image.php | 57 + modules/dynamic-tags/tags/post-gallery.php | 59 + modules/dynamic-tags/tags/post-id.php | 34 + modules/dynamic-tags/tags/post-terms.php | 113 + modules/dynamic-tags/tags/post-time.php | 96 + modules/dynamic-tags/tags/post-title.php | 31 + modules/dynamic-tags/tags/post-url.php | 33 + modules/dynamic-tags/tags/reload-page.php | 40 + .../dynamic-tags/tags/request-parameter.php | 82 + modules/dynamic-tags/tags/shortcode.php | 79 + modules/dynamic-tags/tags/site-logo.php | 42 + modules/dynamic-tags/tags/site-tagline.php | 31 + modules/dynamic-tags/tags/site-title.php | 31 + modules/dynamic-tags/tags/site-url.php | 33 + modules/dynamic-tags/tags/user-info.php | 104 + .../tags/user-profile-picture.php | 21 + modules/dynamic-tags/toolset/module.php | 114 + .../toolset/tags/toolset-base.php | 39 + .../toolset/tags/toolset-date.php | 112 + .../toolset/tags/toolset-gallery.php | 113 + .../toolset/tags/toolset-image.php | 91 + .../toolset/tags/toolset-text.php | 70 + .../dynamic-tags/toolset/tags/toolset-url.php | 97 + modules/element-manager/module.php | 83 + modules/element-manager/options.php | 17 + modules/flip-box/module.php | 57 + modules/flip-box/widgets/flip-box.php | 1790 ++ .../base/widget-contact-button-base-pro.php | 13 + .../base/widget-floating-bars-base-pro.php | 13 + .../render/contact-buttons-var-1-render.php | 62 + .../render/contact-buttons-var-10-render.php | 125 + .../render/contact-buttons-var-3-render.php | 276 + .../render/contact-buttons-var-4-render.php | 230 + .../render/contact-buttons-var-5-render.php | 123 + .../render/contact-buttons-var-6-render.php | 130 + .../render/contact-buttons-var-7-render.php | 178 + .../render/contact-buttons-var-8-render.php | 274 + .../render/contact-buttons-var-9-render.php | 112 + .../render/floating-bars-var-2-render.php | 116 + .../render/floating-bars-var-3-render.php | 106 + .../documents/floating-buttons.php | 199 + modules/floating-buttons/module.php | 109 + .../widgets/contact-buttons-var-1.php | 64 + .../widgets/contact-buttons-var-10.php | 72 + .../widgets/contact-buttons-var-3.php | 133 + .../widgets/contact-buttons-var-4.php | 96 + .../widgets/contact-buttons-var-5.php | 57 + .../widgets/contact-buttons-var-6.php | 78 + .../widgets/contact-buttons-var-7.php | 67 + .../widgets/contact-buttons-var-8.php | 128 + .../widgets/contact-buttons-var-9.php | 70 + .../widgets/floating-bars-var-2.php | 308 + .../widgets/floating-bars-var-3.php | 470 + modules/forms/actions/activecampaign.php | 343 + modules/forms/actions/activity-log.php | 47 + modules/forms/actions/cf7db.php | 33 + modules/forms/actions/convertkit.php | 286 + modules/forms/actions/discord.php | 222 + modules/forms/actions/drip.php | 349 + modules/forms/actions/email.php | 497 + modules/forms/actions/email2.php | 52 + modules/forms/actions/getresponse.php | 334 + modules/forms/actions/mailchimp.php | 490 + modules/forms/actions/mailerlite.php | 303 + modules/forms/actions/mailpoet.php | 129 + modules/forms/actions/mailpoet3.php | 152 + modules/forms/actions/redirect.php | 79 + modules/forms/actions/slack.php | 252 + modules/forms/actions/webhook.php | 123 + modules/forms/classes/action-base.php | 44 + .../forms/classes/activecampaign-handler.php | 149 + modules/forms/classes/ajax-handler.php | 310 + modules/forms/classes/akismet.php | 210 + modules/forms/classes/convertkit-handler.php | 132 + modules/forms/classes/drip-handler.php | 93 + modules/forms/classes/form-base.php | 268 + modules/forms/classes/form-record.php | 347 + modules/forms/classes/getresponse-handler.php | 146 + modules/forms/classes/honeypot-handler.php | 100 + modules/forms/classes/integration-base.php | 75 + modules/forms/classes/mailchimp-handler.php | 179 + modules/forms/classes/mailerlite-handler.php | 123 + modules/forms/classes/recaptcha-handler.php | 301 + .../forms/classes/recaptcha-v3-handler.php | 152 + modules/forms/classes/rest-client.php | 170 + modules/forms/controls/fields-map.php | 45 + modules/forms/controls/fields-repeater.php | 18 + modules/forms/fields/acceptance.php | 82 + modules/forms/fields/date.php | 119 + modules/forms/fields/field-base.php | 112 + modules/forms/fields/number.php | 95 + modules/forms/fields/step.php | 133 + modules/forms/fields/tel.php | 38 + modules/forms/fields/time.php | 91 + modules/forms/fields/upload.php | 543 + modules/forms/module.php | 278 + .../registrars/form-actions-registrar.php | 96 + .../registrars/form-fields-registrar.php | 55 + .../submissions/actions/save-to-database.php | 197 + .../submissions-menu-item.php | 140 + .../submissions-promotion-menu-item.php | 71 + modules/forms/submissions/component.php | 220 + modules/forms/submissions/data/controller.php | 364 + .../submissions/data/endpoints/export.php | 134 + .../data/endpoints/forms-index.php | 35 + .../submissions/data/endpoints/index.php | 146 + .../submissions/data/endpoints/referer.php | 70 + .../submissions/data/endpoints/restore.php | 136 + .../submissions/data/forms-controller.php | 44 + .../data/responses/query-failed-response.php | 28 + .../database/entities/form-snapshot.php | 92 + .../forms/submissions/database/migration.php | 50 + .../database/migrations/base-migration.php | 47 + .../database/migrations/fix-indexes.php | 101 + .../database/migrations/initial.php | 98 + .../database/migrations/referer-extra.php | 21 + modules/forms/submissions/database/query.php | 904 + .../repositories/form-snapshot-repository.php | 168 + .../forms/submissions/export/csv-export.php | 186 + modules/forms/submissions/personal-data.php | 179 + modules/forms/widgets/form.php | 2795 +++ modules/forms/widgets/login.php | 1116 + modules/gallery/module.php | 71 + modules/gallery/widgets/gallery.php | 1669 ++ modules/global-widget/data/controller.php | 61 + modules/global-widget/documents/widget.php | 65 + .../import-export-customization/export.php | 75 + .../import-export-customization/import.php | 107 + modules/global-widget/module.php | 279 + .../global-widget/views/panel-template.php | 33 + .../global-widget/widgets/global-widget.php | 255 + modules/hotspot/module.php | 53 + modules/hotspot/widgets/hotspot.php | 1297 ++ modules/library/classes/shortcode.php | 73 + modules/library/module.php | 149 + modules/library/widgets/template.php | 108 + .../library/wp-widgets/elementor-library.php | 158 + .../base/widget-link-in-bio-base-pro.php | 8 + .../classes/render/icons-below-cta-render.php | 33 + .../render/single-button-cta-render.php | 27 + modules/link-in-bio/module.php | 30 + .../link-in-bio/widgets/link-in-bio-var-2.php | 107 + .../link-in-bio/widgets/link-in-bio-var-3.php | 34 + .../link-in-bio/widgets/link-in-bio-var-4.php | 86 + .../link-in-bio/widgets/link-in-bio-var-5.php | 49 + .../link-in-bio/widgets/link-in-bio-var-6.php | 55 + .../link-in-bio/widgets/link-in-bio-var-7.php | 594 + .../loop-builder/assets/images/loop-item.svg | 163 + modules/loop-builder/documents/loop.php | 547 + .../loop-builder/files/css/loop-css-trait.php | 175 + .../files/css/loop-dynamic-css.php | 23 + .../loop-builder/files/css/loop-preview.php | 27 + modules/loop-builder/files/css/loop.php | 66 + modules/loop-builder/module.php | 344 + .../providers/taxonomy-loop-provider.php | 388 + modules/loop-builder/skins/skin-loop-base.php | 259 + .../skins/skin-loop-post-taxonomy.php | 35 + modules/loop-builder/skins/skin-loop-post.php | 19 + .../skins/skin-loop-taxonomy-base.php | 205 + .../traits/alternate-templates-trait.php | 560 + modules/loop-builder/views/cta-template.php | 78 + modules/loop-builder/widgets/base.php | 370 + .../loop-builder/widgets/loop-carousel.php | 266 + modules/loop-builder/widgets/loop-grid.php | 603 + modules/loop-filter/data/controller.php | 19 + .../endpoints/get-post-type-taxonomies.php | 58 + .../data/endpoints/refresh-loop.php | 119 + modules/loop-filter/module.php | 413 + .../query/data/query-constants.php | 44 + .../query/interfaces/query-interface.php | 10 + .../query/query-types/hierarchy-and-query.php | 93 + .../query/query-types/hierarchy-or-query.php | 90 + .../query/query-types/single-terms-query.php | 88 + .../loop-filter/query/taxonomy-manager.php | 260 + .../query/taxonomy-query-builder.php | 81 + .../traits/hierarchical-taxonomy-trait.php | 80 + .../traits/taxonomy-filter-trait.php | 202 + .../loop-filter/widgets/taxonomy-filter.php | 828 + modules/lottie/assets/animations/default.json | 1 + modules/lottie/classes/caption-helper.php | 103 + modules/lottie/module.php | 103 + modules/lottie/widgets/lottie.php | 885 + .../control-menu-dropdown-animation.php | 19 + modules/mega-menu/module.php | 103 + modules/mega-menu/traits/url-helper-trait.php | 44 + modules/mega-menu/widgets/mega-menu.php | 2649 +++ modules/motion-fx/controls-group.php | 577 + modules/motion-fx/module.php | 222 + modules/nav-menu/module.php | 57 + modules/nav-menu/widgets/nav-menu.php | 1718 ++ modules/nested-carousel/module.php | 61 + .../widgets/nested-carousel.php | 511 + modules/notes/admin-bar.php | 31 + modules/notes/admin-page.php | 146 + modules/notes/data/controller.php | 768 + .../data/endpoints/read-status-endpoint.php | 131 + .../notes/data/endpoints/summary-endpoint.php | 67 + .../notes/data/endpoints/users-endpoint.php | 131 + .../migrations/add-author-display-name.php | 27 + .../database/migrations/add-capabilities.php | 41 + .../database/migrations/add-note-position.php | 27 + .../database/migrations/add-route-post-id.php | 27 + modules/notes/database/migrations/initial.php | 72 + modules/notes/database/models/document.php | 97 + .../notes/database/models/note-summary.php | 81 + modules/notes/database/models/note.php | 471 + modules/notes/database/models/user.php | 130 + .../notes/database/notes-database-updater.php | 45 + .../database/query/note-query-builder.php | 542 + .../database/query/user-query-builder.php | 61 + .../transformers/user-transformer.php | 61 + modules/notes/document-events.php | 122 + modules/notes/module.php | 234 + .../notifications/base-notes-notification.php | 94 + .../user-mentioned-notification.php | 35 + .../user-replied-notification.php | 35 + .../user-resolved-notification.php | 35 + modules/notes/notifications/views/email.php | 90 + modules/notes/usage.php | 317 + modules/notes/user/capabilities.php | 282 + modules/notes/user/delete-user.php | 76 + modules/notes/user/personal-data.php | 122 + modules/notes/user/preferences.php | 113 + modules/notes/utils.php | 114 + modules/off-canvas/module.php | 67 + modules/off-canvas/tag.php | 89 + modules/off-canvas/widgets/off-canvas.php | 608 + modules/page-transitions/module.php | 877 + modules/payments/classes/payment-button.php | 612 + modules/payments/classes/stripe-handler.php | 41 + modules/payments/module.php | 479 + modules/payments/widgets/paypal-button.php | 350 + modules/payments/widgets/stripe-button.php | 538 + .../admin-menu-items/popups-menu-item.php | 32 + .../popups-promotion-menu-item.php | 85 + modules/popup/assets/images/timing-tab.svg | 5 + .../popup/assets/images/timing/browsers.svg | 15 + .../popup/assets/images/timing/devices.svg | 18 + .../popup/assets/images/timing/logged_in.svg | 11 + .../popup/assets/images/timing/page_views.svg | 15 + .../popup/assets/images/timing/schedule.svg | 24 + .../popup/assets/images/timing/sessions.svg | 14 + .../popup/assets/images/timing/sources.svg | 14 + modules/popup/assets/images/timing/times.svg | 11 + modules/popup/assets/images/timing/url.svg | 14 + modules/popup/assets/images/triggers-tab.svg | 9 + .../images/triggers/adblock_detection.svg | 15 + .../popup/assets/images/triggers/click.svg | 9 + .../assets/images/triggers/exit_intent.svg | 11 + .../assets/images/triggers/inactivity.svg | 9 + .../assets/images/triggers/page_load.svg | 10 + .../assets/images/triggers/scrolling.svg | 8 + .../assets/images/triggers/scrolling_to.svg | 9 + modules/popup/display-settings/base.php | 62 + modules/popup/display-settings/timing.php | 310 + modules/popup/display-settings/triggers.php | 200 + modules/popup/document.php | 865 + modules/popup/form-action.php | 143 + modules/popup/module.php | 304 + modules/popup/tag.php | 134 + modules/posts/data/controller.php | 61 + modules/posts/module.php | 91 + modules/posts/skins/skin-base.php | 1416 ++ modules/posts/skins/skin-cards.php | 649 + modules/posts/skins/skin-classic.php | 194 + modules/posts/skins/skin-content-base.php | 333 + modules/posts/skins/skin-full-content.php | 14 + modules/posts/traits/button-widget-trait.php | 597 + modules/posts/traits/pagination-trait.php | 154 + modules/posts/traits/query-note-trait.php | 46 + modules/posts/widgets/portfolio.php | 727 + modules/posts/widgets/posts-base.php | 924 + modules/posts/widgets/posts.php | 134 + modules/pricing/module.php | 77 + modules/pricing/widgets/price-list.php | 765 + modules/pricing/widgets/price-table.php | 2031 ++ modules/progress-tracker/module.php | 53 + .../widgets/progress-tracker.php | 676 + .../classes/elementor-post-query.php | 440 + .../classes/elementor-related-query.php | 169 + .../controls/group-control-posts.php | 315 + .../controls/group-control-query.php | 568 + .../controls/group-control-related.php | 122 + .../controls/group-control-taxonomy.php | 38 + modules/query-control/controls/query.php | 63 + .../query-control/controls/template-query.php | 75 + modules/query-control/module.php | 1045 + modules/role-manager/module.php | 133 + modules/screenshots/module.php | 275 + .../screenshots/render-mode-screenshot.php | 76 + modules/screenshots/screenshot.php | 251 + modules/scroll-snap/module.php | 133 + modules/search/data/controller.php | 19 + .../search/data/endpoints/refresh-search.php | 102 + modules/search/module.php | 103 + modules/search/widgets/search.php | 2214 ++ modules/share-buttons/module.php | 143 + .../share-buttons/widgets/share-buttons.php | 726 + .../controls/control-slides-animation.php | 23 + modules/slides/module.php | 63 + modules/slides/widgets/slides.php | 1614 ++ .../social/classes/facebook-sdk-manager.php | 180 + modules/social/module.php | 63 + modules/social/widgets/facebook-button.php | 235 + modules/social/widgets/facebook-comments.php | 170 + modules/social/widgets/facebook-embed.php | 259 + modules/social/widgets/facebook-page.php | 205 + modules/sticky/module.php | 267 + modules/table-of-contents/module.php | 54 + .../widgets/table-of-contents.php | 965 + .../theme-builder-menu-item.php | 31 + modules/theme-builder/api.php | 21 + .../assets/images/conditions-tab.svg | 19 + .../classes/conditions-cache.php | 143 + .../classes/conditions-manager.php | 563 + .../classes/conditions-repeater.php | 78 + .../classes/control-media-preview.php | 35 + .../classes/locations-manager.php | 674 + .../theme-builder/classes/preview-manager.php | 78 + .../classes/template-conditions.php | 27 + .../classes/templates-types-manager.php | 51 + .../theme-builder/classes/theme-support.php | 130 + .../conditions/any-child-of-term.php | 46 + .../theme-builder/conditions/any-child-of.php | 28 + modules/theme-builder/conditions/archive.php | 64 + modules/theme-builder/conditions/author.php | 47 + .../theme-builder/conditions/by-author.php | 47 + .../conditions/child-of-term.php | 39 + modules/theme-builder/conditions/child-of.php | 62 + .../conditions/condition-base.php | 68 + modules/theme-builder/conditions/date.php | 29 + .../theme-builder/conditions/front-page.php | 29 + modules/theme-builder/conditions/general.php | 34 + .../theme-builder/conditions/in-sub-term.php | 39 + .../theme-builder/conditions/in-taxonomy.php | 65 + .../theme-builder/conditions/not-found404.php | 29 + .../conditions/post-type-archive.php | 73 + .../conditions/post-type-by-author.php | 56 + modules/theme-builder/conditions/post.php | 95 + modules/theme-builder/conditions/search.php | 29 + modules/theme-builder/conditions/singular.php | 62 + modules/theme-builder/conditions/taxonomy.php | 70 + .../documents/archive-single-base.php | 60 + modules/theme-builder/documents/archive.php | 105 + modules/theme-builder/documents/error-404.php | 53 + modules/theme-builder/documents/footer.php | 47 + .../documents/header-footer-base.php | 67 + modules/theme-builder/documents/header.php | 48 + .../documents/search-results.php | 68 + modules/theme-builder/documents/section.php | 113 + .../theme-builder/documents/single-base.php | 189 + .../theme-builder/documents/single-page.php | 46 + .../theme-builder/documents/single-post.php | 43 + modules/theme-builder/documents/single.php | 46 + .../documents/theme-document.php | 736 + .../documents/theme-page-document.php | 131 + .../documents/theme-section-document.php | 43 + .../import-export-customization/export.php | 87 + .../import-export-customization/import.php | 154 + .../import-export-customization/revert.php | 20 + modules/theme-builder/module.php | 505 + .../skins/post-comments-skin-classic.php | 490 + .../skins/posts-archive-skin-base.php | 56 + .../skins/posts-archive-skin-cards.php | 34 + .../skins/posts-archive-skin-classic.php | 33 + .../skins/posts-archive-skin-full-content.php | 21 + .../generate-press-theme-support.php | 63 + .../theme-support/safe-mode-theme-support.php | 34 + .../theme-builder/views/comments-template.php | 53 + .../theme-builder/views/panel-template.php | 96 + .../views/theme-support-footer.php | 14 + .../views/theme-support-header.php | 33 + .../theme-builder/widgets/archive-posts.php | 166 + .../theme-builder/widgets/archive-title.php | 40 + modules/theme-builder/widgets/page-title.php | 40 + .../theme-builder/widgets/post-content.php | 120 + .../theme-builder/widgets/post-excerpt.php | 232 + .../widgets/post-featured-image.php | 60 + modules/theme-builder/widgets/post-title.php | 48 + modules/theme-builder/widgets/site-logo.php | 216 + modules/theme-builder/widgets/site-title.php | 93 + .../widgets/title-widget-base.php | 62 + modules/theme-elements/module.php | 86 + modules/theme-elements/widgets/author-box.php | 1607 ++ modules/theme-elements/widgets/base.php | 17 + .../theme-elements/widgets/breadcrumbs.php | 214 + .../theme-elements/widgets/post-comments.php | 129 + modules/theme-elements/widgets/post-info.php | 1104 + .../widgets/post-navigation.php | 731 + .../theme-elements/widgets/search-form.php | 978 + modules/theme-elements/widgets/sitemap.php | 755 + .../admin-menu-items/base-promotion-item.php | 71 + .../base-promotion-template.php | 105 + modules/tiers/module.php | 53 + modules/usage/features-reporter.php | 34 + modules/usage/integrations-reporter.php | 49 + modules/usage/module.php | 190 + modules/variables/classes/style-schema.php | 104 + modules/variables/hooks.php | 59 + modules/variables/module.php | 59 + .../prop-types/size-variable-prop-type.php | 15 + modules/video-playlist/module.php | 58 + .../video-playlist/widgets/video-playlist.php | 2332 +++ .../classes/base-products-renderer.php | 24 + .../classes/current-query-renderer.php | 85 + .../woocommerce/classes/products-renderer.php | 350 + .../conditions/product-archive.php | 61 + .../woocommerce/conditions/product-search.php | 32 + modules/woocommerce/conditions/shop-page.php | 31 + .../woocommerce/conditions/woocommerce.php | 43 + .../woocommerce/documents/product-archive.php | 170 + .../woocommerce/documents/product-post.php | 77 + modules/woocommerce/documents/product.php | 198 + modules/woocommerce/module.php | 1690 ++ .../settings/settings-woocommerce.php | 898 + modules/woocommerce/skins/skin-classic.php | 89 + .../skins/skin-loop-product-taxonomy.php | 31 + .../woocommerce/skins/skin-loop-product.php | 66 + modules/woocommerce/tags/base-data-tag.php | 29 + modules/woocommerce/tags/base-tag.php | 33 + modules/woocommerce/tags/category-image.php | 63 + modules/woocommerce/tags/product-content.php | 30 + modules/woocommerce/tags/product-gallery.php | 46 + modules/woocommerce/tags/product-image.php | 57 + modules/woocommerce/tags/product-price.php | 60 + modules/woocommerce/tags/product-rating.php | 60 + modules/woocommerce/tags/product-sale.php | 46 + .../tags/product-short-description.php | 30 + modules/woocommerce/tags/product-sku.php | 36 + modules/woocommerce/tags/product-stock.php | 52 + modules/woocommerce/tags/product-terms.php | 79 + modules/woocommerce/tags/product-title.php | 36 + .../tags/traits/tag-product-id.php | 28 + .../tags/woocommerce-add-to-cart.php | 93 + .../woocommerce/traits/product-id-trait.php | 43 + modules/woocommerce/traits/products-trait.php | 202 + .../woocommerce/traits/send-app-plg-trait.php | 43 + .../wc-templates/cart/mini-cart.php | 101 + modules/woocommerce/widgets/add-to-cart.php | 335 + .../widgets/archive-description.php | 119 + .../widgets/archive-products-deprecated.php | 166 + .../woocommerce/widgets/archive-products.php | 204 + modules/woocommerce/widgets/base-widget.php | 153 + modules/woocommerce/widgets/breadcrumb.php | 124 + modules/woocommerce/widgets/cart.php | 2665 +++ modules/woocommerce/widgets/categories.php | 426 + .../woocommerce/widgets/category-image.php | 63 + modules/woocommerce/widgets/checkout.php | 4340 ++++ modules/woocommerce/widgets/elements.php | 163 + modules/woocommerce/widgets/menu-cart.php | 2282 +++ modules/woocommerce/widgets/my-account.php | 2182 ++ modules/woocommerce/widgets/notices.php | 147 + .../widgets/product-add-to-cart.php | 847 + .../product-additional-information.php | 129 + .../woocommerce/widgets/product-content.php | 36 + .../woocommerce/widgets/product-data-tabs.php | 303 + .../woocommerce/widgets/product-images.php | 220 + modules/woocommerce/widgets/product-meta.php | 478 + modules/woocommerce/widgets/product-price.php | 201 + .../woocommerce/widgets/product-rating.php | 211 + .../woocommerce/widgets/product-related.php | 276 + .../widgets/product-short-description.php | 120 + modules/woocommerce/widgets/product-stock.php | 92 + modules/woocommerce/widgets/product-title.php | 92 + .../woocommerce/widgets/product-upsell.php | 254 + modules/woocommerce/widgets/products-base.php | 1119 + .../widgets/products-deprecated.php | 292 + modules/woocommerce/widgets/products.php | 400 + .../woocommerce/widgets/purchase-summary.php | 1737 ++ .../woocommerce/widgets/single-elements.php | 144 + modules/wp-cli/license-command.php | 37 + modules/wp-cli/module.php | 38 + modules/wp-cli/theme-builder.php | 36 + modules/wp-cli/update.php | 18 + plugin.php | 529 + pro-elements.php | 187 + run-on-linux.js | 44 + sample-data/acf-extra-post-fields.json | 71 + sample-data/acf-fields-products.json | 68 + sample-data/sample_products_with_acf_meta.xml | 4904 +++++ .../simple-taxonomy-loop-template.json | 1 + updater/updater.php | 403 + vendor/autoload.php | 22 + vendor/composer/ClassLoader.php | 579 + vendor/composer/InstalledVersions.php | 396 + vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 10 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 9 + vendor/composer/autoload_real.php | 36 + vendor/composer/autoload_static.php | 20 + vendor/composer/installed.json | 5 + vendor/composer/installed.php | 23 + 1178 files changed, 296944 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/release.yaml create mode 100644 .gitignore create mode 100644 assets/css/admin.css create mode 100644 assets/css/admin.min.css create mode 100644 assets/css/app.css create mode 100644 assets/css/app.min.css create mode 100644 assets/css/conditionals/popup.css create mode 100644 assets/css/conditionals/popup.min.css create mode 100644 assets/css/conditionals/ribbon.css create mode 100644 assets/css/conditionals/ribbon.min.css create mode 100644 assets/css/conditionals/transitions.css create mode 100644 assets/css/conditionals/transitions.min.css create mode 100644 assets/css/editor.css create mode 100644 assets/css/editor.min.css create mode 100644 assets/css/modules/custom-code.css create mode 100644 assets/css/modules/custom-code.min.css create mode 100644 assets/css/modules/loop-grid-cta.css create mode 100644 assets/css/modules/loop-grid-cta.min.css create mode 100644 assets/css/modules/motion-fx.css create mode 100644 assets/css/modules/motion-fx.min.css create mode 100644 assets/css/modules/notes.css create mode 100644 assets/css/modules/notes.min.css create mode 100644 assets/css/modules/sticky.css create mode 100644 assets/css/modules/sticky.min.css create mode 100644 assets/css/preview.css create mode 100644 assets/css/preview.min.css create mode 100644 assets/css/templates/widget-animated-headline-rtl.min.css create mode 100644 assets/css/templates/widget-animated-headline.min.css create mode 100644 assets/css/templates/widget-call-to-action-rtl.min.css create mode 100644 assets/css/templates/widget-call-to-action.min.css create mode 100644 assets/css/templates/widget-code-highlight-rtl.min.css create mode 100644 assets/css/templates/widget-code-highlight.min.css create mode 100644 assets/css/templates/widget-flip-box-rtl.min.css create mode 100644 assets/css/templates/widget-flip-box.min.css create mode 100644 assets/css/templates/widget-loop-grid-rtl.min.css create mode 100644 assets/css/templates/widget-loop-grid.min.css create mode 100644 assets/css/templates/widget-mega-menu-rtl.min.css create mode 100644 assets/css/templates/widget-mega-menu.min.css create mode 100644 assets/css/templates/widget-nav-menu-rtl.min.css create mode 100644 assets/css/templates/widget-nav-menu.min.css create mode 100644 assets/css/templates/widget-slides-rtl.min.css create mode 100644 assets/css/templates/widget-slides.min.css create mode 100644 assets/css/templates/widget-testimonial-carousel-rtl.min.css create mode 100644 assets/css/templates/widget-testimonial-carousel.min.css create mode 100644 assets/css/templates/widget-video-playlist-rtl.min.css create mode 100644 assets/css/templates/widget-video-playlist.min.css create mode 100644 assets/css/templates/widget-woocommerce-cart-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-cart.min.css create mode 100644 assets/css/templates/widget-woocommerce-checkout-page-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-checkout-page.min.css create mode 100644 assets/css/templates/widget-woocommerce-menu-cart-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-menu-cart.min.css create mode 100644 assets/css/templates/widget-woocommerce-my-account-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-my-account.min.css create mode 100644 assets/css/templates/widget-woocommerce-product-add-to-cart-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-product-add-to-cart.min.css create mode 100644 assets/css/templates/widget-woocommerce-products-archive-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-products-archive.min.css create mode 100644 assets/css/templates/widget-woocommerce-purchase-summary-rtl.min.css create mode 100644 assets/css/templates/widget-woocommerce-purchase-summary.min.css create mode 100644 assets/css/widget-_compatibility-rtl.min.css create mode 100644 assets/css/widget-_compatibility.min.css create mode 100644 assets/css/widget-_overlay-animation-rtl.min.css create mode 100644 assets/css/widget-_overlay-animation.min.css create mode 100644 assets/css/widget-_sticky-rtl.min.css create mode 100644 assets/css/widget-_sticky.min.css create mode 100644 assets/css/widget-animated-headline-rtl.min.css create mode 100644 assets/css/widget-animated-headline.min.css create mode 100644 assets/css/widget-author-box-rtl.min.css create mode 100644 assets/css/widget-author-box.min.css create mode 100644 assets/css/widget-blockquote-rtl.min.css create mode 100644 assets/css/widget-blockquote.min.css create mode 100644 assets/css/widget-breadcrumbs-rtl.min.css create mode 100644 assets/css/widget-breadcrumbs.min.css create mode 100644 assets/css/widget-call-to-action-rtl.min.css create mode 100644 assets/css/widget-call-to-action.min.css create mode 100644 assets/css/widget-carousel-module-base-rtl.min.css create mode 100644 assets/css/widget-carousel-module-base.min.css create mode 100644 assets/css/widget-code-highlight-rtl.min.css create mode 100644 assets/css/widget-code-highlight.min.css create mode 100644 assets/css/widget-countdown-rtl.min.css create mode 100644 assets/css/widget-countdown.min.css create mode 100644 assets/css/widget-flip-box-rtl.min.css create mode 100644 assets/css/widget-flip-box.min.css create mode 100644 assets/css/widget-form-rtl.min.css create mode 100644 assets/css/widget-form.min.css create mode 100644 assets/css/widget-gallery-rtl.min.css create mode 100644 assets/css/widget-gallery.min.css create mode 100644 assets/css/widget-hotspot-rtl.min.css create mode 100644 assets/css/widget-hotspot.min.css create mode 100644 assets/css/widget-login-rtl.min.css create mode 100644 assets/css/widget-login.min.css create mode 100644 assets/css/widget-loop-canvas-rtl.min.css create mode 100644 assets/css/widget-loop-canvas.min.css create mode 100644 assets/css/widget-loop-carousel-rtl.min.css create mode 100644 assets/css/widget-loop-carousel.min.css create mode 100644 assets/css/widget-loop-common-rtl.min.css create mode 100644 assets/css/widget-loop-common.min.css create mode 100644 assets/css/widget-loop-filter-rtl.min.css create mode 100644 assets/css/widget-loop-filter.min.css create mode 100644 assets/css/widget-loop-grid-rtl.min.css create mode 100644 assets/css/widget-loop-grid.min.css create mode 100644 assets/css/widget-lottie-rtl.min.css create mode 100644 assets/css/widget-lottie.min.css create mode 100644 assets/css/widget-media-carousel-rtl.min.css create mode 100644 assets/css/widget-media-carousel.min.css create mode 100644 assets/css/widget-mega-menu-rtl.min.css create mode 100644 assets/css/widget-mega-menu.min.css create mode 100644 assets/css/widget-nav-menu-rtl.min.css create mode 100644 assets/css/widget-nav-menu.min.css create mode 100644 assets/css/widget-nested-carousel-rtl.min.css create mode 100644 assets/css/widget-nested-carousel.min.css create mode 100644 assets/css/widget-off-canvas-rtl.min.css create mode 100644 assets/css/widget-off-canvas.min.css create mode 100644 assets/css/widget-post-info-rtl.min.css create mode 100644 assets/css/widget-post-info.min.css create mode 100644 assets/css/widget-post-navigation-rtl.min.css create mode 100644 assets/css/widget-post-navigation.min.css create mode 100644 assets/css/widget-posts-rtl.min.css create mode 100644 assets/css/widget-posts.min.css create mode 100644 assets/css/widget-price-list-rtl.min.css create mode 100644 assets/css/widget-price-list.min.css create mode 100644 assets/css/widget-price-table-rtl.min.css create mode 100644 assets/css/widget-price-table.min.css create mode 100644 assets/css/widget-progress-tracker-rtl.min.css create mode 100644 assets/css/widget-progress-tracker.min.css create mode 100644 assets/css/widget-reviews-rtl.min.css create mode 100644 assets/css/widget-reviews.min.css create mode 100644 assets/css/widget-search-form-rtl.min.css create mode 100644 assets/css/widget-search-form.min.css create mode 100644 assets/css/widget-search-rtl.min.css create mode 100644 assets/css/widget-search.min.css create mode 100644 assets/css/widget-share-buttons-rtl.min.css create mode 100644 assets/css/widget-share-buttons.min.css create mode 100644 assets/css/widget-sitemap-rtl.min.css create mode 100644 assets/css/widget-sitemap.min.css create mode 100644 assets/css/widget-slides-rtl.min.css create mode 100644 assets/css/widget-slides.min.css create mode 100644 assets/css/widget-social-rtl.min.css create mode 100644 assets/css/widget-social.min.css create mode 100644 assets/css/widget-table-of-contents-rtl.min.css create mode 100644 assets/css/widget-table-of-contents.min.css create mode 100644 assets/css/widget-testimonial-carousel-rtl.min.css create mode 100644 assets/css/widget-testimonial-carousel.min.css create mode 100644 assets/css/widget-video-playlist-rtl.min.css create mode 100644 assets/css/widget-video-playlist.min.css create mode 100644 assets/css/widget-woocommerce-cart-rtl.min.css create mode 100644 assets/css/widget-woocommerce-cart.min.css create mode 100644 assets/css/widget-woocommerce-categories-rtl.min.css create mode 100644 assets/css/widget-woocommerce-categories.min.css create mode 100644 assets/css/widget-woocommerce-checkout-page-rtl.min.css create mode 100644 assets/css/widget-woocommerce-checkout-page.min.css create mode 100644 assets/css/widget-woocommerce-menu-cart-rtl.min.css create mode 100644 assets/css/widget-woocommerce-menu-cart.min.css create mode 100644 assets/css/widget-woocommerce-my-account-rtl.min.css create mode 100644 assets/css/widget-woocommerce-my-account.min.css create mode 100644 assets/css/widget-woocommerce-notices-rtl.min.css create mode 100644 assets/css/widget-woocommerce-notices.min.css create mode 100644 assets/css/widget-woocommerce-product-add-to-cart-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-add-to-cart.min.css create mode 100644 assets/css/widget-woocommerce-product-additional-information-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-additional-information.min.css create mode 100644 assets/css/widget-woocommerce-product-data-tabs-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-data-tabs.min.css create mode 100644 assets/css/widget-woocommerce-product-images-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-images.min.css create mode 100644 assets/css/widget-woocommerce-product-meta-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-meta.min.css create mode 100644 assets/css/widget-woocommerce-product-price-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-price.min.css create mode 100644 assets/css/widget-woocommerce-product-rating-rtl.min.css create mode 100644 assets/css/widget-woocommerce-product-rating.min.css create mode 100644 assets/css/widget-woocommerce-products-archive-rtl.min.css create mode 100644 assets/css/widget-woocommerce-products-archive.min.css create mode 100644 assets/css/widget-woocommerce-products-rtl.min.css create mode 100644 assets/css/widget-woocommerce-products.min.css create mode 100644 assets/css/widget-woocommerce-purchase-summary-rtl.min.css create mode 100644 assets/css/widget-woocommerce-purchase-summary.min.css create mode 100644 assets/css/woocommerce-notices.css create mode 100644 assets/css/woocommerce-notices.min.css create mode 100644 assets/data/responsive-widgets.json create mode 100644 assets/images/announcements/license-expired.png create mode 100644 assets/images/logo-placeholder.png create mode 100644 assets/js/0726b2d81686a5392236.bundle.min.js create mode 100644 assets/js/0726b2d81686a5392236.bundle.min.js.LICENSE.txt create mode 100644 assets/js/36c2990924ec9596ffad.bundle.js create mode 100644 assets/js/8b11be0d97d58e135d30.bundle.js create mode 100644 assets/js/admin.js create mode 100644 assets/js/admin.min.js create mode 100644 assets/js/ajax-pagination.2090b5f4906bcda1dcc2.bundle.min.js create mode 100644 assets/js/ajax-pagination.2390838f542f1a8d5ed4.bundle.js create mode 100644 assets/js/animated-headline.32baaa2ad2ea939224d5.bundle.js create mode 100644 assets/js/animated-headline.c009d6fa482515df23f8.bundle.min.js create mode 100644 assets/js/app.js create mode 100644 assets/js/app.min.js create mode 100644 assets/js/archive-posts.16a93245d08246e5e540.bundle.min.js create mode 100644 assets/js/archive-posts.6e398ddd4a81a78bcea3.bundle.js create mode 100644 assets/js/carousel.298f1fc9c115422aad0e.bundle.js create mode 100644 assets/js/carousel.3620fca501cb18163600.bundle.min.js create mode 100644 assets/js/code-highlight.7121ad6fca6bf899bbb5.bundle.js create mode 100644 assets/js/code-highlight.b9addbc842a50347c9ab.bundle.min.js create mode 100644 assets/js/contact-buttons-var-10.16cf733dc3d3b250fef4.bundle.min.js create mode 100644 assets/js/contact-buttons-var-10.44dafff87cd10dfffc68.bundle.js create mode 100644 assets/js/contact-buttons.23b3f042ed41cf9221f4.bundle.js create mode 100644 assets/js/contact-buttons.99a987d66bcc2ade0ee6.bundle.min.js create mode 100644 assets/js/countdown.0e9e688751d29d07a8d3.bundle.min.js create mode 100644 assets/js/countdown.6e87ca40d36793d92aea.bundle.js create mode 100644 assets/js/custom-code.js create mode 100644 assets/js/custom-code.min.js create mode 100644 assets/js/d241154d3774d66da9eb.bundle.min.js create mode 100644 assets/js/display-conditions.js create mode 100644 assets/js/display-conditions.min.js create mode 100644 assets/js/e8eba20060a4b0fa29dc.bundle.js create mode 100644 assets/js/editor.js create mode 100644 assets/js/editor.min.js create mode 100644 assets/js/elements-handlers.js create mode 100644 assets/js/elements-handlers.min.js create mode 100644 assets/js/floating-bars-var-2.75c36e8b0bacbac6105e.bundle.min.js create mode 100644 assets/js/floating-bars-var-2.fa9c6b6e6aaeb43504f2.bundle.js create mode 100644 assets/js/floating-bars-var-3.cdf99fd0b063a0032d53.bundle.min.js create mode 100644 assets/js/floating-bars-var-3.ce31fbd73759a9439cbf.bundle.js create mode 100644 assets/js/form-submission-admin.js create mode 100644 assets/js/form-submission-admin.min.js create mode 100644 assets/js/form.151b991a4cbdda620c22.bundle.js create mode 100644 assets/js/form.71055747203b48a65a24.bundle.min.js create mode 100644 assets/js/frontend.js create mode 100644 assets/js/frontend.min.js create mode 100644 assets/js/gallery.06be1c07b9901f53d709.bundle.min.js create mode 100644 assets/js/gallery.ac8ddd9e62465c5cdb2d.bundle.js create mode 100644 assets/js/hotspot.5033ed75928eff79cb95.bundle.min.js create mode 100644 assets/js/hotspot.5e711b7707a884acf3f1.bundle.js create mode 100644 assets/js/jszip.vendor.a3c65615c1de5560962d.bundle.js create mode 100644 assets/js/jszip.vendor.eba4ace24dcc63eadac0.bundle.min.js create mode 100644 assets/js/jszip.vendor.eba4ace24dcc63eadac0.bundle.min.js.LICENSE.txt create mode 100644 assets/js/load-more.8b46f464e573feab5dd7.bundle.min.js create mode 100644 assets/js/load-more.f5ecc1c66872d0bd2d17.bundle.js create mode 100644 assets/js/loop-carousel.122d0b9321a9edad91b0.bundle.js create mode 100644 assets/js/loop-carousel.cd9a95b2e4dd2a239b81.bundle.min.js create mode 100644 assets/js/loop-filter-editor.46a4c013b80a381a50c9.bundle.js create mode 100644 assets/js/loop-filter-editor.be7377d717e2499f4676.bundle.min.js create mode 100644 assets/js/loop.43307e757bd5a39f14cd.bundle.js create mode 100644 assets/js/loop.89cc81d2188312a17a17.bundle.min.js create mode 100644 assets/js/lottie.824e2adeeca89f4297c7.bundle.js create mode 100644 assets/js/lottie.a287ccfe024bea61e651.bundle.min.js create mode 100644 assets/js/media-carousel.8d26e5df1a1527329fde.bundle.min.js create mode 100644 assets/js/media-carousel.8f7b71d582be9d9410fe.bundle.js create mode 100644 assets/js/mega-menu-editor.be91c0f96af4174d83d0.bundle.js create mode 100644 assets/js/mega-menu-editor.da6571bb00aaa3092eab.bundle.min.js create mode 100644 assets/js/mega-menu-stretch-content.0d76e4a3b7bf65ff6f9b.bundle.js create mode 100644 assets/js/mega-menu-stretch-content.480e081cebe071d683e8.bundle.min.js create mode 100644 assets/js/mega-menu.595ee0dffef2bd038c6b.bundle.js create mode 100644 assets/js/mega-menu.82093824ddb3f5531ab4.bundle.min.js create mode 100644 assets/js/menu-title-keyboard-handler.efa6d39b4096f1de6f4d.bundle.js create mode 100644 assets/js/menu-title-keyboard-handler.f0362773c21105d2c65c.bundle.min.js create mode 100644 assets/js/nav-menu.8521a0597c50611efdc6.bundle.min.js create mode 100644 assets/js/nav-menu.fd37f05286fae9cd6d0c.bundle.js create mode 100644 assets/js/nested-carousel-editor.0df35e0e1a284d4bd18b.bundle.js create mode 100644 assets/js/nested-carousel-editor.6d7500036d0766bbe2fc.bundle.min.js create mode 100644 assets/js/nested-carousel.ce414a51f188ccf670ee.bundle.js create mode 100644 assets/js/nested-carousel.db797a097fdc5532ef4a.bundle.min.js create mode 100644 assets/js/notes/363.min.js create mode 100644 assets/js/notes/363.min.js.LICENSE.txt create mode 100644 assets/js/notes/notes-app-initiator.js create mode 100644 assets/js/notes/notes-app-initiator.min.js create mode 100644 assets/js/notes/notes-app.js create mode 100644 assets/js/notes/notes-app.min.js create mode 100644 assets/js/notes/notes.js create mode 100644 assets/js/notes/notes.min.js create mode 100644 assets/js/notes/notes.min.js.LICENSE.txt create mode 100644 assets/js/notes/vendors-node_modules_radix-ui_react-alert-dialog_dist_index_module_js-node_modules_radix-ui_r-e4587e.js create mode 100644 assets/js/off-canvas-editor.9d374fa1254f9efc259e.bundle.min.js create mode 100644 assets/js/off-canvas-editor.d30e3b4fb19101e5ff36.bundle.js create mode 100644 assets/js/off-canvas.137463f629e2b7cbaf02.bundle.min.js create mode 100644 assets/js/off-canvas.ff4d0ebaaec46fc178b2.bundle.js create mode 100644 assets/js/packages/editor-controls-extended/editor-controls-extended.asset.php create mode 100644 assets/js/packages/editor-controls-extended/editor-controls-extended.js create mode 100644 assets/js/packages/editor-controls-extended/editor-controls-extended.min.js create mode 100644 assets/js/packages/editor-controls-extended/editor-controls-extended.strings.js create mode 100644 assets/js/packages/editor-documents-extended/editor-documents-extended.asset.php create mode 100644 assets/js/packages/editor-documents-extended/editor-documents-extended.js create mode 100644 assets/js/packages/editor-documents-extended/editor-documents-extended.min.js create mode 100644 assets/js/packages/editor-documents-extended/editor-documents-extended.strings.js create mode 100644 assets/js/packages/editor-editing-panel-extended/editor-editing-panel-extended.asset.php create mode 100644 assets/js/packages/editor-editing-panel-extended/editor-editing-panel-extended.js create mode 100644 assets/js/packages/editor-editing-panel-extended/editor-editing-panel-extended.min.js create mode 100644 assets/js/packages/editor-editing-panel-extended/editor-editing-panel-extended.strings.js create mode 100644 assets/js/packages/editor-notes/editor-notes.asset.php create mode 100644 assets/js/packages/editor-notes/editor-notes.js create mode 100644 assets/js/packages/editor-notes/editor-notes.min.js create mode 100644 assets/js/packages/editor-notes/editor-notes.strings.js create mode 100644 assets/js/packages/editor-site-navigation-extended/editor-site-navigation-extended.asset.php create mode 100644 assets/js/packages/editor-site-navigation-extended/editor-site-navigation-extended.js create mode 100644 assets/js/packages/editor-site-navigation-extended/editor-site-navigation-extended.min.js create mode 100644 assets/js/packages/editor-site-navigation-extended/editor-site-navigation-extended.strings.js create mode 100644 assets/js/packages/editor-variables-extended/editor-variables-extended.asset.php create mode 100644 assets/js/packages/editor-variables-extended/editor-variables-extended.js create mode 100644 assets/js/packages/editor-variables-extended/editor-variables-extended.min.js create mode 100644 assets/js/packages/editor-variables-extended/editor-variables-extended.strings.js create mode 100644 assets/js/page-transitions.js create mode 100644 assets/js/page-transitions.min.js create mode 100644 assets/js/paypal-button.55ffb013a3fe565f55a5.bundle.js create mode 100644 assets/js/paypal-button.f4f64e46173f50701949.bundle.min.js create mode 100644 assets/js/popup.996738ad83c089bcc0b9.bundle.js create mode 100644 assets/js/popup.f7b15b2ca565b152bf98.bundle.min.js create mode 100644 assets/js/portfolio.4cd5da34009c30cb5d70.bundle.min.js create mode 100644 assets/js/portfolio.5727b56368be256d0893.bundle.js create mode 100644 assets/js/posts.aec59265318492b89cb5.bundle.min.js create mode 100644 assets/js/posts.e99f84b83c36d4568ffe.bundle.js create mode 100644 assets/js/preview.js create mode 100644 assets/js/preview.min.js create mode 100644 assets/js/product-add-to-cart.0c33bb82cd57e51665f9.bundle.js create mode 100644 assets/js/product-add-to-cart.c32f5d5e404511d68720.bundle.min.js create mode 100644 assets/js/progress-tracker.8cccdda9737c272489fc.bundle.min.js create mode 100644 assets/js/progress-tracker.fd1d31a26340ed74e10a.bundle.js create mode 100644 assets/js/screenshot.js create mode 100644 assets/js/screenshot.min.js create mode 100644 assets/js/search-form.8941aba5c12cdb05fb7c.bundle.js create mode 100644 assets/js/search-form.b7065999d77832a1b764.bundle.min.js create mode 100644 assets/js/search.1a4ea982239b5f5db501.bundle.js create mode 100644 assets/js/search.5d88e65c03029f91931d.bundle.min.js create mode 100644 assets/js/share-buttons.63d984f8c96d1e053bc0.bundle.min.js create mode 100644 assets/js/share-buttons.fda49c1691f4a352c7ef.bundle.js create mode 100644 assets/js/slides.bcd16bbde90338846bd7.bundle.js create mode 100644 assets/js/slides.c0029640cbdb48199471.bundle.min.js create mode 100644 assets/js/social.83aec5578e50a413de57.bundle.js create mode 100644 assets/js/social.d71d263bd937f0906192.bundle.min.js create mode 100644 assets/js/stripe-button.49130d6eecb5ebc8afbd.bundle.min.js create mode 100644 assets/js/stripe-button.cb4b1cf19f1c46430f76.bundle.js create mode 100644 assets/js/table-of-contents.3be1ab725f562d10dd86.bundle.min.js create mode 100644 assets/js/table-of-contents.6ac58abccb098fb35213.bundle.js create mode 100644 assets/js/taxonomy-filter.a32526f3e4a201b5fce1.bundle.min.js create mode 100644 assets/js/taxonomy-filter.f3f2746a00fed7447ff5.bundle.js create mode 100644 assets/js/video-playlist.7140c18aeaebfda82118.bundle.js create mode 100644 assets/js/video-playlist.909c41acbc73cb741e9d.bundle.min.js create mode 100644 assets/js/webpack-pro.runtime.js create mode 100644 assets/js/webpack-pro.runtime.min.js create mode 100644 assets/js/woocommerce-cart.3e38c78b18f28be95e9d.bundle.js create mode 100644 assets/js/woocommerce-cart.480d117b95956d1f28a5.bundle.min.js create mode 100644 assets/js/woocommerce-checkout-page.48b0561b8ee895da5af5.bundle.js create mode 100644 assets/js/woocommerce-checkout-page.6ba1f1f2aa99210fa1cf.bundle.min.js create mode 100644 assets/js/woocommerce-menu-cart.54f2e75f6769dce707e2.bundle.min.js create mode 100644 assets/js/woocommerce-menu-cart.a0d098b5b49cb56bf258.bundle.js create mode 100644 assets/js/woocommerce-my-account.7c01b4a03ae07847db06.bundle.js create mode 100644 assets/js/woocommerce-my-account.d54826f355f9822b0ec0.bundle.min.js create mode 100644 assets/js/woocommerce-notices.00f9132bbbd683277a27.bundle.min.js create mode 100644 assets/js/woocommerce-notices.c1b466cde2ea03db7d6e.bundle.js create mode 100644 assets/js/woocommerce-purchase-summary.2ebf26dca7d446fdd128.bundle.js create mode 100644 assets/js/woocommerce-purchase-summary.88a2d8ca449739e34f9f.bundle.min.js create mode 100644 assets/lib/dom-to-image/js/dom-to-image.js create mode 100644 assets/lib/dom-to-image/js/dom-to-image.min.js create mode 100644 assets/lib/font-awesome-pro/brands.js create mode 100644 assets/lib/font-awesome-pro/duotone.js create mode 100644 assets/lib/font-awesome-pro/light.js create mode 100644 assets/lib/font-awesome-pro/regular.js create mode 100644 assets/lib/font-awesome-pro/solid.js create mode 100644 assets/lib/html2canvas/js/html2canvas.js create mode 100644 assets/lib/html2canvas/js/html2canvas.min.js create mode 100644 assets/lib/instant-page/instant-page.js create mode 100644 assets/lib/instant-page/instant-page.min.js create mode 100644 assets/lib/lottie/lottie.js create mode 100644 assets/lib/lottie/lottie.min.js create mode 100644 assets/lib/smartmenus/jquery.smartmenus.js create mode 100644 assets/lib/smartmenus/jquery.smartmenus.min.js create mode 100644 assets/lib/sticky/jquery.sticky.js create mode 100644 assets/lib/sticky/jquery.sticky.min.js create mode 100644 base/base-carousel-trait.php create mode 100644 base/base-widget-trait.php create mode 100644 base/base-widget.php create mode 100644 base/module-base.php create mode 100644 base/on-import-trait.php create mode 100644 changelog.txt create mode 100644 core/admin/action-links.php create mode 100644 core/admin/admin.php create mode 100644 core/admin/canary-deployment.php create mode 100644 core/admin/post-status.php create mode 100644 core/app/app.php create mode 100644 core/app/assets/js/hooks/use-feature-lock.js create mode 100644 core/app/assets/js/index.js create mode 100644 core/app/assets/js/ui/connect-button.js create mode 100644 core/app/assets/js/utils.js create mode 100644 core/app/assets/styles/app-imports.scss create mode 100644 core/app/modules/import-export-customization/assets/js/components/customization-list-setting-section.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/customization-sub-setting.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/index.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/kit-content-customization-dialog.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/kit-settings-customization-dialog.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/kit-templates-customization-dialog.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/theme-builder-customization.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js create mode 100644 core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-custom-post-types.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-custom-post-types.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-pages.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-taxonomies.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-pages.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-taxonomies.js create mode 100644 core/app/modules/import-export-customization/assets/js/hooks/use-tier.js create mode 100644 core/app/modules/import-export-customization/assets/js/module.js create mode 100644 core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js create mode 100644 core/app/modules/import-export-customization/module.php create mode 100644 core/app/modules/import-export-customization/runners/base/export-runner-base.php create mode 100644 core/app/modules/import-export-customization/runners/base/import-runner-base.php create mode 100644 core/app/modules/import-export-customization/runners/export/site-settings.php create mode 100644 core/app/modules/import-export-customization/runners/export/taxonomies.php create mode 100644 core/app/modules/import-export-customization/runners/export/templates.php create mode 100644 core/app/modules/import-export-customization/runners/import/elementor-content.php create mode 100644 core/app/modules/import-export-customization/runners/import/site-settings.php create mode 100644 core/app/modules/import-export-customization/runners/import/taxonomies.php create mode 100644 core/app/modules/import-export-customization/runners/import/templates.php create mode 100644 core/app/modules/import-export-customization/runners/traits/site-settings-helpers.php create mode 100644 core/app/modules/import-export/module.php create mode 100644 core/app/modules/import-export/runners/export/templates.php create mode 100644 core/app/modules/import-export/runners/import/templates.php create mode 100644 core/app/modules/import-export/runners/revert/templates.php create mode 100644 core/app/modules/kit-library/module.php create mode 100644 core/app/modules/onboarding/module.php create mode 100644 core/app/modules/site-editor/assets/js/atoms/indicator-bullet.js create mode 100644 core/app/modules/site-editor/assets/js/atoms/indicator-bullet.scss create mode 100644 core/app/modules/site-editor/assets/js/atoms/preview-iframe.js create mode 100644 core/app/modules/site-editor/assets/js/atoms/preview-iframe.scss create mode 100644 core/app/modules/site-editor/assets/js/context/base-context.js create mode 100644 core/app/modules/site-editor/assets/js/context/conditions.js create mode 100644 core/app/modules/site-editor/assets/js/context/models/condition.js create mode 100644 core/app/modules/site-editor/assets/js/context/services/conditions-config.js create mode 100644 core/app/modules/site-editor/assets/js/context/templates.js create mode 100644 core/app/modules/site-editor/assets/js/data/commands/conditions-config.js create mode 100644 core/app/modules/site-editor/assets/js/data/commands/index.js create mode 100644 core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js create mode 100644 core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js create mode 100644 core/app/modules/site-editor/assets/js/data/commands/templates.js create mode 100644 core/app/modules/site-editor/assets/js/data/component.js create mode 100644 core/app/modules/site-editor/assets/js/editor.js create mode 100644 core/app/modules/site-editor/assets/js/hooks/use-templates-screenshot.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/back-button.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/back-button.scss create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template-body.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template-footer.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template-header.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template-thumbnail.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template.js create mode 100644 core/app/modules/site-editor/assets/js/molecules/site-template.scss create mode 100644 core/app/modules/site-editor/assets/js/organisms/site-templates.js create mode 100644 core/app/modules/site-editor/assets/js/pages/add-new.js create mode 100644 core/app/modules/site-editor/assets/js/pages/add-new.scss create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/conditions-api.scss create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/conditions.js create mode 100644 core/app/modules/site-editor/assets/js/pages/conditions/conditions.scss create mode 100644 core/app/modules/site-editor/assets/js/pages/import.js create mode 100644 core/app/modules/site-editor/assets/js/pages/template-type.js create mode 100644 core/app/modules/site-editor/assets/js/pages/template-type.scss create mode 100644 core/app/modules/site-editor/assets/js/pages/templates.js create mode 100644 core/app/modules/site-editor/assets/js/part-actions/dialog-delete.js create mode 100644 core/app/modules/site-editor/assets/js/part-actions/dialog-rename.js create mode 100644 core/app/modules/site-editor/assets/js/part-actions/dialogs-and-buttons.js create mode 100644 core/app/modules/site-editor/assets/js/site-editor.js create mode 100644 core/app/modules/site-editor/assets/js/site-editor.scss create mode 100644 core/app/modules/site-editor/data/controller.php create mode 100644 core/app/modules/site-editor/data/endpoints/base-endpoint.php create mode 100644 core/app/modules/site-editor/data/endpoints/conditions-config.php create mode 100644 core/app/modules/site-editor/data/endpoints/template-types.php create mode 100644 core/app/modules/site-editor/data/endpoints/templates-conditions-conflicts.php create mode 100644 core/app/modules/site-editor/data/endpoints/templates-conditions.php create mode 100644 core/app/modules/site-editor/data/endpoints/templates.php create mode 100644 core/app/modules/site-editor/data/responses/lock-error-response.php create mode 100644 core/app/modules/site-editor/module.php create mode 100644 core/app/modules/site-editor/render-mode-template-preview.php create mode 100644 core/behaviors/feature-lock.php create mode 100644 core/behaviors/temp-lock-behavior.php create mode 100644 core/compatibility/compatibility.php create mode 100644 core/connect/apps/activate.php create mode 100644 core/connect/manager.php create mode 100644 core/data/controller.php create mode 100644 core/data/endpoints/base.php create mode 100644 core/data/endpoints/refresh-base.php create mode 100644 core/data/interfaces/endpoint.php create mode 100644 core/database/base-database-updater.php create mode 100644 core/database/base-migration.php create mode 100644 core/database/join-clause.php create mode 100644 core/database/model-base.php create mode 100644 core/database/model-query-builder.php create mode 100644 core/database/query-builder.php create mode 100644 core/editor/editor.php create mode 100644 core/editor/notice-bar.php create mode 100644 core/editor/promotion.php create mode 100644 core/editor/template.php create mode 100644 core/integrations/actions/action-base.php create mode 100644 core/integrations/actions/email/email-address.php create mode 100644 core/integrations/actions/email/email-message.php create mode 100644 core/integrations/actions/email/email.php create mode 100644 core/integrations/exceptions/action-failed-exception.php create mode 100644 core/integrations/exceptions/action-validation-failed-exception.php create mode 100644 core/integrations/exceptions/exception-base.php create mode 100644 core/integrations/integrations-manager.php create mode 100644 core/isolation/wordpress-adapter-interface.php create mode 100644 core/isolation/wordpress-adapter.php create mode 100644 core/maintenance.php create mode 100644 core/modules-manager.php create mode 100644 core/notifications/notification.php create mode 100644 core/notifications/notifications-manager.php create mode 100644 core/notifications/traits/notifiable.php create mode 100644 core/php-api.php create mode 100644 core/preview/preview.php create mode 100644 core/security/access-control.php create mode 100644 core/security/capability.php create mode 100644 core/upgrade/manager.php create mode 100644 core/upgrade/upgrades.php create mode 100644 core/utils.php create mode 100644 core/utils/abtest.php create mode 100644 core/utils/collection.php create mode 100644 core/utils/hints.php create mode 100644 core/utils/registrar.php create mode 100644 data/base/controller.php create mode 100644 data/http-status.php create mode 100644 license.txt create mode 100644 license/admin.php create mode 100644 license/api.php create mode 100644 license/data/controller.php create mode 100644 license/data/endpoints/get-tier-features.php create mode 100644 modules/admin-top-bar/module.php create mode 100644 modules/animated-headline/module.php create mode 100644 modules/animated-headline/widgets/animated-headline.php create mode 100644 modules/announcements/module.php create mode 100644 modules/announcements/triggers/is-license-expired.php create mode 100644 modules/assets-manager/asset-types/admin-menu-items/custom-fonts-menu-item.php create mode 100644 modules/assets-manager/asset-types/admin-menu-items/custom-fonts-promotion-menu-item.php create mode 100644 modules/assets-manager/asset-types/admin-menu-items/custom-icons-menu-item.php create mode 100644 modules/assets-manager/asset-types/admin-menu-items/custom-icons-promotion-menu-item.php create mode 100644 modules/assets-manager/asset-types/fonts-manager.php create mode 100644 modules/assets-manager/asset-types/fonts/custom-fonts.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export-customization/export-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export-customization/import-export-customization.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export-customization/import-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export-customization/revert-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export/export-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export/import-export.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export/import-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/import-export/revert-runner.php create mode 100644 modules/assets-manager/asset-types/fonts/typekit-fonts.php create mode 100644 modules/assets-manager/asset-types/icons-manager.php create mode 100644 modules/assets-manager/asset-types/icons/custom-icons.php create mode 100644 modules/assets-manager/asset-types/icons/font-awesome-pro.php create mode 100644 modules/assets-manager/asset-types/icons/icon-sets/fontastic.php create mode 100644 modules/assets-manager/asset-types/icons/icon-sets/fontello.php create mode 100644 modules/assets-manager/asset-types/icons/icon-sets/icomoon.php create mode 100644 modules/assets-manager/asset-types/icons/icon-sets/icon-set-base.php create mode 100644 modules/assets-manager/asset-types/icons/import-export-customization/export-runner.php create mode 100644 modules/assets-manager/asset-types/icons/import-export-customization/import-export-customization.php create mode 100644 modules/assets-manager/asset-types/icons/import-export-customization/import-runner.php create mode 100644 modules/assets-manager/asset-types/icons/import-export-customization/revert-runner.php create mode 100644 modules/assets-manager/asset-types/icons/import-export/export-runner.php create mode 100644 modules/assets-manager/asset-types/icons/import-export/import-export.php create mode 100644 modules/assets-manager/asset-types/icons/import-export/import-runner.php create mode 100644 modules/assets-manager/asset-types/icons/import-export/revert-runner.php create mode 100644 modules/assets-manager/asset-types/icons/templates.php create mode 100644 modules/assets-manager/asset-types/import-export/traits/external-attachment-trait.php create mode 100644 modules/assets-manager/classes/assets-base.php create mode 100644 modules/assets-manager/classes/font-base.php create mode 100644 modules/assets-manager/module.php create mode 100644 modules/attributes/module.php create mode 100644 modules/blockquote/module.php create mode 100644 modules/blockquote/widgets/blockquote.php create mode 100644 modules/call-to-action/module.php create mode 100644 modules/call-to-action/widgets/call-to-action.php create mode 100644 modules/carousel/module.php create mode 100644 modules/carousel/widgets/base.php create mode 100644 modules/carousel/widgets/media-carousel.php create mode 100644 modules/carousel/widgets/reviews.php create mode 100644 modules/carousel/widgets/testimonial-carousel.php create mode 100644 modules/checklist/module.php create mode 100644 modules/checklist/steps/setup-header.php create mode 100644 modules/cloud-library/module.php create mode 100644 modules/code-highlight/module.php create mode 100644 modules/code-highlight/widgets/code-highlight.php create mode 100644 modules/compatibility-tag/compatibility-tag-component.php create mode 100644 modules/compatibility-tag/module.php create mode 100644 modules/countdown/module.php create mode 100644 modules/countdown/widgets/countdown.php create mode 100644 modules/custom-attributes/module.php create mode 100644 modules/custom-code/admin-menu-items/custom-code-menu-item.php create mode 100644 modules/custom-code/custom-code-metabox.php create mode 100644 modules/custom-code/document.php create mode 100644 modules/custom-code/import-export-customization/export-runner.php create mode 100644 modules/custom-code/import-export-customization/import-export-customization.php create mode 100644 modules/custom-code/import-export-customization/import-runner.php create mode 100644 modules/custom-code/import-export-customization/revert-runner.php create mode 100644 modules/custom-code/import-export/export-runner.php create mode 100644 modules/custom-code/import-export/import-export.php create mode 100644 modules/custom-code/import-export/import-runner.php create mode 100644 modules/custom-code/import-export/revert-runner.php create mode 100644 modules/custom-code/module.php create mode 100644 modules/custom-css/admin-menu-items/settings-custom-css-pro.php create mode 100644 modules/custom-css/module.php create mode 100644 modules/display-conditions/classes/and-condition.php create mode 100644 modules/display-conditions/classes/cache-notice.php create mode 100644 modules/display-conditions/classes/comparator-provider.php create mode 100644 modules/display-conditions/classes/comparators-checker.php create mode 100644 modules/display-conditions/classes/conditions-manager.php create mode 100644 modules/display-conditions/classes/dynamic-tags/custom-fields-data-provider.php create mode 100644 modules/display-conditions/classes/dynamic-tags/data-provider.php create mode 100644 modules/display-conditions/classes/dynamic-tags/dynamic-tags-data-provider.php create mode 100644 modules/display-conditions/classes/or-condition.php create mode 100644 modules/display-conditions/conditions/archive-of-author-condition.php create mode 100644 modules/display-conditions/conditions/archive-of-category-condition.php create mode 100644 modules/display-conditions/conditions/archive-of-tag-condition.php create mode 100644 modules/display-conditions/conditions/base/archive-condition-base.php create mode 100644 modules/display-conditions/conditions/base/condition-base.php create mode 100644 modules/display-conditions/conditions/base/date-condition-base.php create mode 100644 modules/display-conditions/conditions/base/title-condition-base.php create mode 100644 modules/display-conditions/conditions/current-date-condition.php create mode 100644 modules/display-conditions/conditions/date-of-modification-condition.php create mode 100644 modules/display-conditions/conditions/date-of-publish-condition.php create mode 100644 modules/display-conditions/conditions/day-of-the-week-condition.php create mode 100644 modules/display-conditions/conditions/dynamic-tags-condition.php create mode 100644 modules/display-conditions/conditions/featured-image-condition.php create mode 100644 modules/display-conditions/conditions/from-url-condition.php create mode 100644 modules/display-conditions/conditions/in-categories-condition.php create mode 100644 modules/display-conditions/conditions/in-tags-condition.php create mode 100644 modules/display-conditions/conditions/login-status-condition.php create mode 100644 modules/display-conditions/conditions/page-author-condition.php create mode 100644 modules/display-conditions/conditions/page-parent-condition.php create mode 100644 modules/display-conditions/conditions/page-title-condition.php create mode 100644 modules/display-conditions/conditions/post-author-condition.php create mode 100644 modules/display-conditions/conditions/post-number-of-comments-condition.php create mode 100644 modules/display-conditions/conditions/post-title-condition.php create mode 100644 modules/display-conditions/conditions/time-of-the-day-condition.php create mode 100644 modules/display-conditions/conditions/user-registration-date-condition.php create mode 100644 modules/display-conditions/conditions/user-role-condition.php create mode 100644 modules/display-conditions/module.php create mode 100644 modules/dynamic-tags/acf/dynamic-value-provider.php create mode 100644 modules/dynamic-tags/acf/module.php create mode 100644 modules/dynamic-tags/acf/tags/acf-color.php create mode 100644 modules/dynamic-tags/acf/tags/acf-date-time.php create mode 100644 modules/dynamic-tags/acf/tags/acf-file.php create mode 100644 modules/dynamic-tags/acf/tags/acf-gallery.php create mode 100644 modules/dynamic-tags/acf/tags/acf-image.php create mode 100644 modules/dynamic-tags/acf/tags/acf-number.php create mode 100644 modules/dynamic-tags/acf/tags/acf-text.php create mode 100644 modules/dynamic-tags/acf/tags/acf-url.php create mode 100644 modules/dynamic-tags/components/author-meta-filter.php create mode 100644 modules/dynamic-tags/module.php create mode 100644 modules/dynamic-tags/pods/dynamic-value-provider.php create mode 100644 modules/dynamic-tags/pods/module.php create mode 100644 modules/dynamic-tags/pods/tags/pods-base.php create mode 100644 modules/dynamic-tags/pods/tags/pods-date-time.php create mode 100644 modules/dynamic-tags/pods/tags/pods-date.php create mode 100644 modules/dynamic-tags/pods/tags/pods-gallery.php create mode 100644 modules/dynamic-tags/pods/tags/pods-image.php create mode 100644 modules/dynamic-tags/pods/tags/pods-numeric.php create mode 100644 modules/dynamic-tags/pods/tags/pods-text.php create mode 100644 modules/dynamic-tags/pods/tags/pods-url.php create mode 100644 modules/dynamic-tags/tags/archive-description.php create mode 100644 modules/dynamic-tags/tags/archive-meta.php create mode 100644 modules/dynamic-tags/tags/archive-title.php create mode 100644 modules/dynamic-tags/tags/archive-url.php create mode 100644 modules/dynamic-tags/tags/author-info.php create mode 100644 modules/dynamic-tags/tags/author-meta.php create mode 100644 modules/dynamic-tags/tags/author-name.php create mode 100644 modules/dynamic-tags/tags/author-profile-picture.php create mode 100644 modules/dynamic-tags/tags/author-url.php create mode 100644 modules/dynamic-tags/tags/base/author-tag.php create mode 100644 modules/dynamic-tags/tags/base/data-tag.php create mode 100644 modules/dynamic-tags/tags/base/tag-trait.php create mode 100644 modules/dynamic-tags/tags/base/tag.php create mode 100644 modules/dynamic-tags/tags/comments-number.php create mode 100644 modules/dynamic-tags/tags/comments-url.php create mode 100644 modules/dynamic-tags/tags/contact-url.php create mode 100644 modules/dynamic-tags/tags/current-date-time.php create mode 100644 modules/dynamic-tags/tags/featured-image-data.php create mode 100644 modules/dynamic-tags/tags/internal-url.php create mode 100644 modules/dynamic-tags/tags/lightbox.php create mode 100644 modules/dynamic-tags/tags/page-title.php create mode 100644 modules/dynamic-tags/tags/post-custom-field.php create mode 100644 modules/dynamic-tags/tags/post-date.php create mode 100644 modules/dynamic-tags/tags/post-excerpt.php create mode 100644 modules/dynamic-tags/tags/post-featured-image.php create mode 100644 modules/dynamic-tags/tags/post-gallery.php create mode 100644 modules/dynamic-tags/tags/post-id.php create mode 100644 modules/dynamic-tags/tags/post-terms.php create mode 100644 modules/dynamic-tags/tags/post-time.php create mode 100644 modules/dynamic-tags/tags/post-title.php create mode 100644 modules/dynamic-tags/tags/post-url.php create mode 100644 modules/dynamic-tags/tags/reload-page.php create mode 100644 modules/dynamic-tags/tags/request-parameter.php create mode 100644 modules/dynamic-tags/tags/shortcode.php create mode 100644 modules/dynamic-tags/tags/site-logo.php create mode 100644 modules/dynamic-tags/tags/site-tagline.php create mode 100644 modules/dynamic-tags/tags/site-title.php create mode 100644 modules/dynamic-tags/tags/site-url.php create mode 100644 modules/dynamic-tags/tags/user-info.php create mode 100644 modules/dynamic-tags/tags/user-profile-picture.php create mode 100644 modules/dynamic-tags/toolset/module.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-base.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-date.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-gallery.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-image.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-text.php create mode 100644 modules/dynamic-tags/toolset/tags/toolset-url.php create mode 100644 modules/element-manager/module.php create mode 100644 modules/element-manager/options.php create mode 100644 modules/flip-box/module.php create mode 100644 modules/flip-box/widgets/flip-box.php create mode 100644 modules/floating-buttons/base/widget-contact-button-base-pro.php create mode 100644 modules/floating-buttons/base/widget-floating-bars-base-pro.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-1-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-10-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-3-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-4-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-5-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-6-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-7-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-8-render.php create mode 100644 modules/floating-buttons/classes/render/contact-buttons-var-9-render.php create mode 100644 modules/floating-buttons/classes/render/floating-bars-var-2-render.php create mode 100644 modules/floating-buttons/classes/render/floating-bars-var-3-render.php create mode 100644 modules/floating-buttons/documents/floating-buttons.php create mode 100644 modules/floating-buttons/module.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-1.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-10.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-3.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-4.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-5.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-6.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-7.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-8.php create mode 100644 modules/floating-buttons/widgets/contact-buttons-var-9.php create mode 100644 modules/floating-buttons/widgets/floating-bars-var-2.php create mode 100644 modules/floating-buttons/widgets/floating-bars-var-3.php create mode 100644 modules/forms/actions/activecampaign.php create mode 100644 modules/forms/actions/activity-log.php create mode 100644 modules/forms/actions/cf7db.php create mode 100644 modules/forms/actions/convertkit.php create mode 100644 modules/forms/actions/discord.php create mode 100644 modules/forms/actions/drip.php create mode 100644 modules/forms/actions/email.php create mode 100644 modules/forms/actions/email2.php create mode 100644 modules/forms/actions/getresponse.php create mode 100644 modules/forms/actions/mailchimp.php create mode 100644 modules/forms/actions/mailerlite.php create mode 100644 modules/forms/actions/mailpoet.php create mode 100644 modules/forms/actions/mailpoet3.php create mode 100644 modules/forms/actions/redirect.php create mode 100644 modules/forms/actions/slack.php create mode 100644 modules/forms/actions/webhook.php create mode 100644 modules/forms/classes/action-base.php create mode 100644 modules/forms/classes/activecampaign-handler.php create mode 100644 modules/forms/classes/ajax-handler.php create mode 100644 modules/forms/classes/akismet.php create mode 100644 modules/forms/classes/convertkit-handler.php create mode 100644 modules/forms/classes/drip-handler.php create mode 100644 modules/forms/classes/form-base.php create mode 100644 modules/forms/classes/form-record.php create mode 100644 modules/forms/classes/getresponse-handler.php create mode 100644 modules/forms/classes/honeypot-handler.php create mode 100644 modules/forms/classes/integration-base.php create mode 100644 modules/forms/classes/mailchimp-handler.php create mode 100644 modules/forms/classes/mailerlite-handler.php create mode 100644 modules/forms/classes/recaptcha-handler.php create mode 100644 modules/forms/classes/recaptcha-v3-handler.php create mode 100644 modules/forms/classes/rest-client.php create mode 100644 modules/forms/controls/fields-map.php create mode 100644 modules/forms/controls/fields-repeater.php create mode 100644 modules/forms/fields/acceptance.php create mode 100644 modules/forms/fields/date.php create mode 100644 modules/forms/fields/field-base.php create mode 100644 modules/forms/fields/number.php create mode 100644 modules/forms/fields/step.php create mode 100644 modules/forms/fields/tel.php create mode 100644 modules/forms/fields/time.php create mode 100644 modules/forms/fields/upload.php create mode 100644 modules/forms/module.php create mode 100644 modules/forms/registrars/form-actions-registrar.php create mode 100644 modules/forms/registrars/form-fields-registrar.php create mode 100644 modules/forms/submissions/actions/save-to-database.php create mode 100644 modules/forms/submissions/admin-menu-items/submissions-menu-item.php create mode 100644 modules/forms/submissions/admin-menu-items/submissions-promotion-menu-item.php create mode 100644 modules/forms/submissions/component.php create mode 100644 modules/forms/submissions/data/controller.php create mode 100644 modules/forms/submissions/data/endpoints/export.php create mode 100644 modules/forms/submissions/data/endpoints/forms-index.php create mode 100644 modules/forms/submissions/data/endpoints/index.php create mode 100644 modules/forms/submissions/data/endpoints/referer.php create mode 100644 modules/forms/submissions/data/endpoints/restore.php create mode 100644 modules/forms/submissions/data/forms-controller.php create mode 100644 modules/forms/submissions/data/responses/query-failed-response.php create mode 100644 modules/forms/submissions/database/entities/form-snapshot.php create mode 100644 modules/forms/submissions/database/migration.php create mode 100644 modules/forms/submissions/database/migrations/base-migration.php create mode 100644 modules/forms/submissions/database/migrations/fix-indexes.php create mode 100644 modules/forms/submissions/database/migrations/initial.php create mode 100644 modules/forms/submissions/database/migrations/referer-extra.php create mode 100644 modules/forms/submissions/database/query.php create mode 100644 modules/forms/submissions/database/repositories/form-snapshot-repository.php create mode 100644 modules/forms/submissions/export/csv-export.php create mode 100644 modules/forms/submissions/personal-data.php create mode 100644 modules/forms/widgets/form.php create mode 100644 modules/forms/widgets/login.php create mode 100644 modules/gallery/module.php create mode 100644 modules/gallery/widgets/gallery.php create mode 100644 modules/global-widget/data/controller.php create mode 100644 modules/global-widget/documents/widget.php create mode 100644 modules/global-widget/import-export-customization/export.php create mode 100644 modules/global-widget/import-export-customization/import.php create mode 100644 modules/global-widget/module.php create mode 100644 modules/global-widget/views/panel-template.php create mode 100644 modules/global-widget/widgets/global-widget.php create mode 100644 modules/hotspot/module.php create mode 100644 modules/hotspot/widgets/hotspot.php create mode 100644 modules/library/classes/shortcode.php create mode 100644 modules/library/module.php create mode 100644 modules/library/widgets/template.php create mode 100644 modules/library/wp-widgets/elementor-library.php create mode 100644 modules/link-in-bio/base/widget-link-in-bio-base-pro.php create mode 100644 modules/link-in-bio/classes/render/icons-below-cta-render.php create mode 100644 modules/link-in-bio/classes/render/single-button-cta-render.php create mode 100644 modules/link-in-bio/module.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-2.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-3.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-4.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-5.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-6.php create mode 100644 modules/link-in-bio/widgets/link-in-bio-var-7.php create mode 100644 modules/loop-builder/assets/images/loop-item.svg create mode 100644 modules/loop-builder/documents/loop.php create mode 100644 modules/loop-builder/files/css/loop-css-trait.php create mode 100644 modules/loop-builder/files/css/loop-dynamic-css.php create mode 100644 modules/loop-builder/files/css/loop-preview.php create mode 100644 modules/loop-builder/files/css/loop.php create mode 100644 modules/loop-builder/module.php create mode 100644 modules/loop-builder/providers/taxonomy-loop-provider.php create mode 100644 modules/loop-builder/skins/skin-loop-base.php create mode 100644 modules/loop-builder/skins/skin-loop-post-taxonomy.php create mode 100644 modules/loop-builder/skins/skin-loop-post.php create mode 100644 modules/loop-builder/skins/skin-loop-taxonomy-base.php create mode 100644 modules/loop-builder/traits/alternate-templates-trait.php create mode 100644 modules/loop-builder/views/cta-template.php create mode 100644 modules/loop-builder/widgets/base.php create mode 100644 modules/loop-builder/widgets/loop-carousel.php create mode 100644 modules/loop-builder/widgets/loop-grid.php create mode 100644 modules/loop-filter/data/controller.php create mode 100644 modules/loop-filter/data/endpoints/get-post-type-taxonomies.php create mode 100644 modules/loop-filter/data/endpoints/refresh-loop.php create mode 100644 modules/loop-filter/module.php create mode 100644 modules/loop-filter/query/data/query-constants.php create mode 100644 modules/loop-filter/query/interfaces/query-interface.php create mode 100644 modules/loop-filter/query/query-types/hierarchy-and-query.php create mode 100644 modules/loop-filter/query/query-types/hierarchy-or-query.php create mode 100644 modules/loop-filter/query/query-types/single-terms-query.php create mode 100644 modules/loop-filter/query/taxonomy-manager.php create mode 100644 modules/loop-filter/query/taxonomy-query-builder.php create mode 100644 modules/loop-filter/traits/hierarchical-taxonomy-trait.php create mode 100644 modules/loop-filter/traits/taxonomy-filter-trait.php create mode 100644 modules/loop-filter/widgets/taxonomy-filter.php create mode 100644 modules/lottie/assets/animations/default.json create mode 100644 modules/lottie/classes/caption-helper.php create mode 100644 modules/lottie/module.php create mode 100644 modules/lottie/widgets/lottie.php create mode 100644 modules/mega-menu/controls/control-menu-dropdown-animation.php create mode 100644 modules/mega-menu/module.php create mode 100644 modules/mega-menu/traits/url-helper-trait.php create mode 100644 modules/mega-menu/widgets/mega-menu.php create mode 100644 modules/motion-fx/controls-group.php create mode 100644 modules/motion-fx/module.php create mode 100644 modules/nav-menu/module.php create mode 100644 modules/nav-menu/widgets/nav-menu.php create mode 100644 modules/nested-carousel/module.php create mode 100644 modules/nested-carousel/widgets/nested-carousel.php create mode 100644 modules/notes/admin-bar.php create mode 100644 modules/notes/admin-page.php create mode 100644 modules/notes/data/controller.php create mode 100644 modules/notes/data/endpoints/read-status-endpoint.php create mode 100644 modules/notes/data/endpoints/summary-endpoint.php create mode 100644 modules/notes/data/endpoints/users-endpoint.php create mode 100644 modules/notes/database/migrations/add-author-display-name.php create mode 100644 modules/notes/database/migrations/add-capabilities.php create mode 100644 modules/notes/database/migrations/add-note-position.php create mode 100644 modules/notes/database/migrations/add-route-post-id.php create mode 100644 modules/notes/database/migrations/initial.php create mode 100644 modules/notes/database/models/document.php create mode 100644 modules/notes/database/models/note-summary.php create mode 100644 modules/notes/database/models/note.php create mode 100644 modules/notes/database/models/user.php create mode 100644 modules/notes/database/notes-database-updater.php create mode 100644 modules/notes/database/query/note-query-builder.php create mode 100644 modules/notes/database/query/user-query-builder.php create mode 100644 modules/notes/database/transformers/user-transformer.php create mode 100644 modules/notes/document-events.php create mode 100644 modules/notes/module.php create mode 100644 modules/notes/notifications/base-notes-notification.php create mode 100644 modules/notes/notifications/user-mentioned-notification.php create mode 100644 modules/notes/notifications/user-replied-notification.php create mode 100644 modules/notes/notifications/user-resolved-notification.php create mode 100644 modules/notes/notifications/views/email.php create mode 100644 modules/notes/usage.php create mode 100644 modules/notes/user/capabilities.php create mode 100644 modules/notes/user/delete-user.php create mode 100644 modules/notes/user/personal-data.php create mode 100644 modules/notes/user/preferences.php create mode 100644 modules/notes/utils.php create mode 100644 modules/off-canvas/module.php create mode 100644 modules/off-canvas/tag.php create mode 100644 modules/off-canvas/widgets/off-canvas.php create mode 100644 modules/page-transitions/module.php create mode 100644 modules/payments/classes/payment-button.php create mode 100644 modules/payments/classes/stripe-handler.php create mode 100644 modules/payments/module.php create mode 100644 modules/payments/widgets/paypal-button.php create mode 100644 modules/payments/widgets/stripe-button.php create mode 100644 modules/popup/admin-menu-items/popups-menu-item.php create mode 100644 modules/popup/admin-menu-items/popups-promotion-menu-item.php create mode 100644 modules/popup/assets/images/timing-tab.svg create mode 100644 modules/popup/assets/images/timing/browsers.svg create mode 100644 modules/popup/assets/images/timing/devices.svg create mode 100644 modules/popup/assets/images/timing/logged_in.svg create mode 100644 modules/popup/assets/images/timing/page_views.svg create mode 100644 modules/popup/assets/images/timing/schedule.svg create mode 100644 modules/popup/assets/images/timing/sessions.svg create mode 100644 modules/popup/assets/images/timing/sources.svg create mode 100644 modules/popup/assets/images/timing/times.svg create mode 100644 modules/popup/assets/images/timing/url.svg create mode 100644 modules/popup/assets/images/triggers-tab.svg create mode 100644 modules/popup/assets/images/triggers/adblock_detection.svg create mode 100644 modules/popup/assets/images/triggers/click.svg create mode 100644 modules/popup/assets/images/triggers/exit_intent.svg create mode 100644 modules/popup/assets/images/triggers/inactivity.svg create mode 100644 modules/popup/assets/images/triggers/page_load.svg create mode 100644 modules/popup/assets/images/triggers/scrolling.svg create mode 100644 modules/popup/assets/images/triggers/scrolling_to.svg create mode 100644 modules/popup/display-settings/base.php create mode 100644 modules/popup/display-settings/timing.php create mode 100644 modules/popup/display-settings/triggers.php create mode 100644 modules/popup/document.php create mode 100644 modules/popup/form-action.php create mode 100644 modules/popup/module.php create mode 100644 modules/popup/tag.php create mode 100644 modules/posts/data/controller.php create mode 100644 modules/posts/module.php create mode 100644 modules/posts/skins/skin-base.php create mode 100644 modules/posts/skins/skin-cards.php create mode 100644 modules/posts/skins/skin-classic.php create mode 100644 modules/posts/skins/skin-content-base.php create mode 100644 modules/posts/skins/skin-full-content.php create mode 100644 modules/posts/traits/button-widget-trait.php create mode 100644 modules/posts/traits/pagination-trait.php create mode 100644 modules/posts/traits/query-note-trait.php create mode 100644 modules/posts/widgets/portfolio.php create mode 100644 modules/posts/widgets/posts-base.php create mode 100644 modules/posts/widgets/posts.php create mode 100644 modules/pricing/module.php create mode 100644 modules/pricing/widgets/price-list.php create mode 100644 modules/pricing/widgets/price-table.php create mode 100644 modules/progress-tracker/module.php create mode 100644 modules/progress-tracker/widgets/progress-tracker.php create mode 100644 modules/query-control/classes/elementor-post-query.php create mode 100644 modules/query-control/classes/elementor-related-query.php create mode 100644 modules/query-control/controls/group-control-posts.php create mode 100644 modules/query-control/controls/group-control-query.php create mode 100644 modules/query-control/controls/group-control-related.php create mode 100644 modules/query-control/controls/group-control-taxonomy.php create mode 100644 modules/query-control/controls/query.php create mode 100644 modules/query-control/controls/template-query.php create mode 100644 modules/query-control/module.php create mode 100644 modules/role-manager/module.php create mode 100644 modules/screenshots/module.php create mode 100644 modules/screenshots/render-mode-screenshot.php create mode 100644 modules/screenshots/screenshot.php create mode 100644 modules/scroll-snap/module.php create mode 100644 modules/search/data/controller.php create mode 100644 modules/search/data/endpoints/refresh-search.php create mode 100644 modules/search/module.php create mode 100644 modules/search/widgets/search.php create mode 100644 modules/share-buttons/module.php create mode 100644 modules/share-buttons/widgets/share-buttons.php create mode 100644 modules/slides/controls/control-slides-animation.php create mode 100644 modules/slides/module.php create mode 100644 modules/slides/widgets/slides.php create mode 100644 modules/social/classes/facebook-sdk-manager.php create mode 100644 modules/social/module.php create mode 100644 modules/social/widgets/facebook-button.php create mode 100644 modules/social/widgets/facebook-comments.php create mode 100644 modules/social/widgets/facebook-embed.php create mode 100644 modules/social/widgets/facebook-page.php create mode 100644 modules/sticky/module.php create mode 100644 modules/table-of-contents/module.php create mode 100644 modules/table-of-contents/widgets/table-of-contents.php create mode 100644 modules/theme-builder/admin-menu-items/theme-builder-menu-item.php create mode 100644 modules/theme-builder/api.php create mode 100644 modules/theme-builder/assets/images/conditions-tab.svg create mode 100644 modules/theme-builder/classes/conditions-cache.php create mode 100644 modules/theme-builder/classes/conditions-manager.php create mode 100644 modules/theme-builder/classes/conditions-repeater.php create mode 100644 modules/theme-builder/classes/control-media-preview.php create mode 100644 modules/theme-builder/classes/locations-manager.php create mode 100644 modules/theme-builder/classes/preview-manager.php create mode 100644 modules/theme-builder/classes/template-conditions.php create mode 100644 modules/theme-builder/classes/templates-types-manager.php create mode 100644 modules/theme-builder/classes/theme-support.php create mode 100644 modules/theme-builder/conditions/any-child-of-term.php create mode 100644 modules/theme-builder/conditions/any-child-of.php create mode 100644 modules/theme-builder/conditions/archive.php create mode 100644 modules/theme-builder/conditions/author.php create mode 100644 modules/theme-builder/conditions/by-author.php create mode 100644 modules/theme-builder/conditions/child-of-term.php create mode 100644 modules/theme-builder/conditions/child-of.php create mode 100644 modules/theme-builder/conditions/condition-base.php create mode 100644 modules/theme-builder/conditions/date.php create mode 100644 modules/theme-builder/conditions/front-page.php create mode 100644 modules/theme-builder/conditions/general.php create mode 100644 modules/theme-builder/conditions/in-sub-term.php create mode 100644 modules/theme-builder/conditions/in-taxonomy.php create mode 100644 modules/theme-builder/conditions/not-found404.php create mode 100644 modules/theme-builder/conditions/post-type-archive.php create mode 100644 modules/theme-builder/conditions/post-type-by-author.php create mode 100644 modules/theme-builder/conditions/post.php create mode 100644 modules/theme-builder/conditions/search.php create mode 100644 modules/theme-builder/conditions/singular.php create mode 100644 modules/theme-builder/conditions/taxonomy.php create mode 100644 modules/theme-builder/documents/archive-single-base.php create mode 100644 modules/theme-builder/documents/archive.php create mode 100644 modules/theme-builder/documents/error-404.php create mode 100644 modules/theme-builder/documents/footer.php create mode 100644 modules/theme-builder/documents/header-footer-base.php create mode 100644 modules/theme-builder/documents/header.php create mode 100644 modules/theme-builder/documents/search-results.php create mode 100644 modules/theme-builder/documents/section.php create mode 100644 modules/theme-builder/documents/single-base.php create mode 100644 modules/theme-builder/documents/single-page.php create mode 100644 modules/theme-builder/documents/single-post.php create mode 100644 modules/theme-builder/documents/single.php create mode 100644 modules/theme-builder/documents/theme-document.php create mode 100644 modules/theme-builder/documents/theme-page-document.php create mode 100644 modules/theme-builder/documents/theme-section-document.php create mode 100644 modules/theme-builder/import-export-customization/export.php create mode 100644 modules/theme-builder/import-export-customization/import.php create mode 100644 modules/theme-builder/import-export-customization/revert.php create mode 100644 modules/theme-builder/module.php create mode 100644 modules/theme-builder/skins/post-comments-skin-classic.php create mode 100644 modules/theme-builder/skins/posts-archive-skin-base.php create mode 100644 modules/theme-builder/skins/posts-archive-skin-cards.php create mode 100644 modules/theme-builder/skins/posts-archive-skin-classic.php create mode 100644 modules/theme-builder/skins/posts-archive-skin-full-content.php create mode 100644 modules/theme-builder/theme-support/generate-press-theme-support.php create mode 100644 modules/theme-builder/theme-support/safe-mode-theme-support.php create mode 100644 modules/theme-builder/views/comments-template.php create mode 100644 modules/theme-builder/views/panel-template.php create mode 100644 modules/theme-builder/views/theme-support-footer.php create mode 100644 modules/theme-builder/views/theme-support-header.php create mode 100644 modules/theme-builder/widgets/archive-posts.php create mode 100644 modules/theme-builder/widgets/archive-title.php create mode 100644 modules/theme-builder/widgets/page-title.php create mode 100644 modules/theme-builder/widgets/post-content.php create mode 100644 modules/theme-builder/widgets/post-excerpt.php create mode 100644 modules/theme-builder/widgets/post-featured-image.php create mode 100644 modules/theme-builder/widgets/post-title.php create mode 100644 modules/theme-builder/widgets/site-logo.php create mode 100644 modules/theme-builder/widgets/site-title.php create mode 100644 modules/theme-builder/widgets/title-widget-base.php create mode 100644 modules/theme-elements/module.php create mode 100644 modules/theme-elements/widgets/author-box.php create mode 100644 modules/theme-elements/widgets/base.php create mode 100644 modules/theme-elements/widgets/breadcrumbs.php create mode 100644 modules/theme-elements/widgets/post-comments.php create mode 100644 modules/theme-elements/widgets/post-info.php create mode 100644 modules/theme-elements/widgets/post-navigation.php create mode 100644 modules/theme-elements/widgets/search-form.php create mode 100644 modules/theme-elements/widgets/sitemap.php create mode 100644 modules/tiers/admin-menu-items/base-promotion-item.php create mode 100644 modules/tiers/admin-menu-items/base-promotion-template.php create mode 100644 modules/tiers/module.php create mode 100644 modules/usage/features-reporter.php create mode 100644 modules/usage/integrations-reporter.php create mode 100644 modules/usage/module.php create mode 100644 modules/variables/classes/style-schema.php create mode 100644 modules/variables/hooks.php create mode 100644 modules/variables/module.php create mode 100644 modules/variables/prop-types/size-variable-prop-type.php create mode 100644 modules/video-playlist/module.php create mode 100644 modules/video-playlist/widgets/video-playlist.php create mode 100644 modules/woocommerce/classes/base-products-renderer.php create mode 100644 modules/woocommerce/classes/current-query-renderer.php create mode 100644 modules/woocommerce/classes/products-renderer.php create mode 100644 modules/woocommerce/conditions/product-archive.php create mode 100644 modules/woocommerce/conditions/product-search.php create mode 100644 modules/woocommerce/conditions/shop-page.php create mode 100644 modules/woocommerce/conditions/woocommerce.php create mode 100644 modules/woocommerce/documents/product-archive.php create mode 100644 modules/woocommerce/documents/product-post.php create mode 100644 modules/woocommerce/documents/product.php create mode 100644 modules/woocommerce/module.php create mode 100644 modules/woocommerce/settings/settings-woocommerce.php create mode 100644 modules/woocommerce/skins/skin-classic.php create mode 100644 modules/woocommerce/skins/skin-loop-product-taxonomy.php create mode 100644 modules/woocommerce/skins/skin-loop-product.php create mode 100644 modules/woocommerce/tags/base-data-tag.php create mode 100644 modules/woocommerce/tags/base-tag.php create mode 100644 modules/woocommerce/tags/category-image.php create mode 100644 modules/woocommerce/tags/product-content.php create mode 100644 modules/woocommerce/tags/product-gallery.php create mode 100644 modules/woocommerce/tags/product-image.php create mode 100644 modules/woocommerce/tags/product-price.php create mode 100644 modules/woocommerce/tags/product-rating.php create mode 100644 modules/woocommerce/tags/product-sale.php create mode 100644 modules/woocommerce/tags/product-short-description.php create mode 100644 modules/woocommerce/tags/product-sku.php create mode 100644 modules/woocommerce/tags/product-stock.php create mode 100644 modules/woocommerce/tags/product-terms.php create mode 100644 modules/woocommerce/tags/product-title.php create mode 100644 modules/woocommerce/tags/traits/tag-product-id.php create mode 100644 modules/woocommerce/tags/woocommerce-add-to-cart.php create mode 100644 modules/woocommerce/traits/product-id-trait.php create mode 100644 modules/woocommerce/traits/products-trait.php create mode 100644 modules/woocommerce/traits/send-app-plg-trait.php create mode 100644 modules/woocommerce/wc-templates/cart/mini-cart.php create mode 100644 modules/woocommerce/widgets/add-to-cart.php create mode 100644 modules/woocommerce/widgets/archive-description.php create mode 100644 modules/woocommerce/widgets/archive-products-deprecated.php create mode 100644 modules/woocommerce/widgets/archive-products.php create mode 100644 modules/woocommerce/widgets/base-widget.php create mode 100644 modules/woocommerce/widgets/breadcrumb.php create mode 100644 modules/woocommerce/widgets/cart.php create mode 100644 modules/woocommerce/widgets/categories.php create mode 100644 modules/woocommerce/widgets/category-image.php create mode 100644 modules/woocommerce/widgets/checkout.php create mode 100644 modules/woocommerce/widgets/elements.php create mode 100644 modules/woocommerce/widgets/menu-cart.php create mode 100644 modules/woocommerce/widgets/my-account.php create mode 100644 modules/woocommerce/widgets/notices.php create mode 100644 modules/woocommerce/widgets/product-add-to-cart.php create mode 100644 modules/woocommerce/widgets/product-additional-information.php create mode 100644 modules/woocommerce/widgets/product-content.php create mode 100644 modules/woocommerce/widgets/product-data-tabs.php create mode 100644 modules/woocommerce/widgets/product-images.php create mode 100644 modules/woocommerce/widgets/product-meta.php create mode 100644 modules/woocommerce/widgets/product-price.php create mode 100644 modules/woocommerce/widgets/product-rating.php create mode 100644 modules/woocommerce/widgets/product-related.php create mode 100644 modules/woocommerce/widgets/product-short-description.php create mode 100644 modules/woocommerce/widgets/product-stock.php create mode 100644 modules/woocommerce/widgets/product-title.php create mode 100644 modules/woocommerce/widgets/product-upsell.php create mode 100644 modules/woocommerce/widgets/products-base.php create mode 100644 modules/woocommerce/widgets/products-deprecated.php create mode 100644 modules/woocommerce/widgets/products.php create mode 100644 modules/woocommerce/widgets/purchase-summary.php create mode 100644 modules/woocommerce/widgets/single-elements.php create mode 100644 modules/wp-cli/license-command.php create mode 100644 modules/wp-cli/module.php create mode 100644 modules/wp-cli/theme-builder.php create mode 100644 modules/wp-cli/update.php create mode 100644 plugin.php create mode 100644 pro-elements.php create mode 100644 run-on-linux.js create mode 100644 sample-data/acf-extra-post-fields.json create mode 100644 sample-data/acf-fields-products.json create mode 100644 sample-data/sample_products_with_acf_meta.xml create mode 100644 sample-data/simple-taxonomy-loop-template.json create mode 100644 updater/updater.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/composer/installed.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..d8d60efe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Do not export git service files. +.* export-ignore \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..d8116840 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,22 @@ +name: Publish +on: + push: + tags: + - '*' +jobs: + build: + name: Publish plugin + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build + shell: bash + run: git archive --format=zip --prefix="pro-elements/" HEAD > pro-elements.zip + - name: Upload binaries to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: pro-elements.zip + tag: ${{ github.ref }} + overwrite: true + body: "Release" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e3a4ff1e --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Codekit # +########### +*.codekit + +# Node # +######## +node_modules/* + +# Ide # +####### +.idea/* + +# Build # +######### +build/prod/* + +# Deploy # +########## +servers.yml + + +# Project files # +################# + +**/.env \ No newline at end of file diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 00000000..f1969839 --- /dev/null +++ b/assets/css/admin.css @@ -0,0 +1,787 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.wrap.elementor-admin-page-license .elementor-license-box { + max-width: 600px; + background: white; + margin: 20px 0; + padding: 20px; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0; + padding: 0; + padding-block-end: 20px; + border-block-end: 1px solid #eee; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 span { + flex-grow: 1; + padding-inline-start: 5px; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 small { + font-size: 13px; + font-weight: normal; +} +.wrap.elementor-admin-page-license .elementor-license-box label { + display: block; + font-size: 1.3em; + font-weight: 600; + margin: 1em 0; +} +.wrap.elementor-admin-page-license .elementor-license-box .button { + height: 30px; + margin-inline-start: 15px; + margin-block-end: 0; +} +.wrap.elementor-admin-page-license .elementor-license-box p.description { + margin: 10px 0; +} +.wrap.elementor-admin-page-license .elementor-license-box .e-row-stretch, .wrap.elementor-admin-page-license .elementor-license-box.e-row-stretch { + display: flex; + align-items: center; + justify-content: space-between; +} +.wrap.elementor-admin-page-license .elementor-license-box .e-row-divider-bottom { + padding-block-end: 15px; + border-block-end: 1px solid #eee; +} +.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link { + color: #93003f; + border-color: #93003f; +} +.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link:hover { + color: #fff; + background-color: #93003f; +} +.wrap.elementor-admin-page-license .elementor-box-action { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block-start: 30px; +} +.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link { + color: #72777c; + margin-inline-end: 15px; +} +.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link:hover { + color: inherit; +} + +#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link] { + font-weight: 600; + font-size: 12px; + line-height: 1.5; + background-color: #93003f; + color: #ffffff; + margin: 3px 10px 0; + padding: 5px 0; + display: block; + text-align: center; + border-radius: 3px; + transition: all 0.3s; +} +#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:hover, #adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:focus { + background-color: rgb(198, 0, 84.8571428571); + box-shadow: none; +} + +.fixed .column-elementor_library_type, +.fixed .column-instances { + width: 10%; +} +.fixed .elementor-shortcode-input { + min-width: 235px; +} +@media (min-width: 768px) and (max-width: 1440px) { + .fixed .column-shortcode { + width: 25%; + } + .fixed .elementor-shortcode-input { + min-width: 100%; + } +} + +#available-widgets [class*=elementor-template] .widget-title:before { + content: "\e801"; + font-family: eicon; + font-size: 17px; +} + +#elementor-widget-template-empty-templates { + margin-block-start: 15px; + text-align: center; +} + +.elementor-widget-template-empty-templates-title { + padding: 25px 0 30px; +} + +.elementor-widget-template-empty-templates-icon { + font-size: 96px; +} + +.elementor-widget-template-empty-templates-footer { + color: var(--e-a-color-txt-muted); + font-size: 13px; + font-style: italic; + margin-block-end: 15px; +} + +.elementor-button-spinner.error:before { + content: "\f335"; + color: #ff0000; +} + +@media screen and (max-width: 782px) { + .e-form-submissions-list-table { + /* Don't judge me... (need to override WordPress style). */ + } + .e-form-submissions-list-table.wp-list-table tr:not(.inline-edit-row):not(.no-items) > td.bulk-checkbox-column:not(.check-column) { + width: 2.2em !important; + } +} +.e-form-submissions-list-table .bulk-checkbox-column { + padding: 9px 0 0 3px; + width: 2.2em; +} +.e-form-submissions-list-table .column-actions { + width: 11%; +} +.e-form-submissions-list-table .column-actions i { + font-size: 15px; +} +.e-form-submissions-list-table .column-id { + width: 7%; +} +.e-form-submissions-list-table .column-page { + width: 17%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +.e-form-submissions-list-table .column-date { + width: 17%; +} +.e-form-submissions-list-table .column-form { + width: 20%; +} + +.e-form-submissions-referer-icon { + font-size: 18px; +} + +.e-form-submissions-main .postbox { + border: none; +} +.e-form-submissions-main .postbox-header { + border: 1px solid #D5D8DC; + border-block-end: none; + padding: 8px; +} +.e-form-submissions-main__header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +#e-form-submissions .eicon-success { + color: #5cb85c; +} +#e-form-submissions .eicon-error { + color: #d9534f; +} +#e-form-submissions .misc-pub-section { + line-height: 1.3rem; +} + +#e-form-submissions .e-form-submissions-item-table { + border: none; + border-collapse: collapse; +} +#e-form-submissions .e-form-submissions-item-table td:first-child { + width: 150px; + background: #F9FAFA; + font-weight: 700; +} +@media screen and (max-width: 782px) { + #e-form-submissions .e-form-submissions-item-table td:first-child { + /* Must set !important because wordpress set also !important. */ + width: 90px !important; + } +} +#e-form-submissions .e-form-submissions-item-table td { + border: 1px solid #D5D8DC; + padding: 15px; +} +#e-form-submissions .e-form-submissions-item-table input:not([type=checkbox]):not([type=radio]), #e-form-submissions .e-form-submissions-item-table textarea, #e-form-submissions .e-form-submissions-item-table select { + width: 100%; + max-width: 400px; +} + +#e-form-submissions .e-export-button { + margin-inline-start: 15px; +} +@media screen and (max-width: 782px) { + #e-form-submissions .e-export-button { + display: none; + } +} +#e-form-submissions .tablenav .actions select { + width: 10rem; +} +#e-form-submissions .tablenav .actions .select2-container { + float: left; + margin-right: 6px; +} +#e-form-submissions .tablenav .actions .select2-container .select2-selection__arrow { + height: 30px; +} +#e-form-submissions .tablenav .actions .select2-container .select2-selection--single { + height: 30px; + border: 1px solid #7e8993; +} + +input[type=search].select2-search__field { + line-height: 1; +} + +.e-form-submissions-search { + position: relative; +} +.e-form-submissions-search__spinner { + position: absolute; + inset-inline-end: 12px; + font-size: 11px; + height: 100%; + display: flex; + align-items: center; + color: var(--wp-admin-theme-color-darker-20, #005a87); +} +.e-form-submissions-search:focus-within .e-form-submissions-search__spinner, .e-form-submissions-search:hover .e-form-submissions-search__spinner { + inset-inline-end: 30px; +} + +.e-form-submissions-action-log--success .e-form-submissions-action-log__message { + background: #dff0d8; + border-color: #5cb85c; +} +.e-form-submissions-action-log--error .e-form-submissions-action-log__message { + background: #f2dede; + border-color: #d9534f; +} +.e-form-submissions-action-log:not(:last-child) { + border-block-end: 1px solid #D5D8DC; +} +.e-form-submissions-action-log__label { + display: inline-block; + padding-inline-end: 15px; +} +.e-form-submissions-action-log__icon { + display: inline-block; + padding-inline-end: 3px; +} +.e-form-submissions-action-log__date { + font-size: 12px; + color: #69727D; +} +.e-form-submissions-action-log__message { + padding: 10px; + font-size: 12px; + color: #1f2124; + background: #F1F2F3; + border-inline-start: 4px solid #69727D; +} + +.e-form-submissions-value-label:not(:last-child) { + display: block; + margin-block-end: 10px; +} + +span.font-variations-count { + display: inline-block; + vertical-align: top; + margin: 1px 0 0 5px; + padding: 0 5px; + min-width: 7px; + height: 17px; + border-radius: 11px; + background-color: #d4dffb; + color: #4278b2; + font-size: 9px; + line-height: 17px; + text-align: center; + z-index: 26; +} + +.post-type-elementor_font #elementor-font-custommetabox { + background: none; + border: 0; +} +.post-type-elementor_font #elementor-font-custommetabox button.handlediv { + display: none; +} +.post-type-elementor_font #elementor-font-custommetabox .inside { + margin-block-start: 15px; +} +.post-type-elementor_font #elementor-font-custommetabox h2.hndle { + padding-inline: 0; + font-size: 16px; +} +.post-type-elementor_font #elementor-font-custommetabox .handle-actions { + display: none; +} +.post-type-elementor_font #elementor-font-custommetabox .elementor-metabox-content:not(.has-font-variable):not(.has-font-static) { + display: flex; +} +.post-type-elementor_font #tagsdiv-elementor_font_type, +.post-type-elementor_font #minor-publishing-actions, +.post-type-elementor_font #misc-publishing-actions { + display: none; +} + +.elementor-metabox-content #add-variable-font { + margin-block-start: 18px; + margin-inline-start: 18px; +} +.elementor-metabox-content.has-font-variable .repeater-content-bottom { + display: flex; + flex-direction: column; +} +.elementor-metabox-content.has-font-variable .variable-width-wrap, +.elementor-metabox-content.has-font-variable .variable-weight-wrap { + display: flex; + gap: 20px; + margin-block: 10px; + min-height: 30px; + order: 1; +} +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_min, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_max, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_min, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_max, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_min, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_max, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_min, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_max { + display: none; +} +.elementor-metabox-content.has-font-variable #add-variable-font, +.elementor-metabox-content.has-font-variable .add-repeater-row, +.elementor-metabox-content.has-font-variable .font_weight, +.elementor-metabox-content.has-font-variable .font_style, +.elementor-metabox-content.has-font-variable .row-font-weight, +.elementor-metabox-content.has-font-variable .row-font-style, +.elementor-metabox-content.has-font-variable .repeater-block .elementor-field-file:not(.ttf) { + display: none; +} +.elementor-metabox-content.has-font-variable .elementor-field-input { + display: flex; + align-items: center; + min-width: 80px; +} +.elementor-metabox-content.has-font-variable .variable-description { + order: 1; + margin-block: 20px 10px; +} +.elementor-metabox-content.has-font-variable .variable_width .elementor-field-label, +.elementor-metabox-content.has-font-variable .variable_weight .elementor-field-label { + order: 1; +} +.elementor-metabox-content.has-font-variable .variable_width_min label, +.elementor-metabox-content.has-font-variable .variable_width_max label, +.elementor-metabox-content.has-font-variable .variable_weight_min label, +.elementor-metabox-content.has-font-variable .variable_weight_max label { + min-width: 80px; +} +.elementor-metabox-content.has-font-variable .variable_width_min input, +.elementor-metabox-content.has-font-variable .variable_width_max input, +.elementor-metabox-content.has-font-variable .variable_weight_min input, +.elementor-metabox-content.has-font-variable .variable_weight_max input { + max-width: 80px; +} +.elementor-metabox-content.has-font-static .variable-width-wrap, +.elementor-metabox-content.has-font-static .variable-weight-wrap, +.elementor-metabox-content.has-font-static .variable-description, +.elementor-metabox-content.has-font-static #add-variable-font { + display: none; +} +.elementor-metabox-content .repeater-block { + background: #fff; + color: #3f444b; + padding: 20px; + margin-block-end: 2px; +} +.elementor-metabox-content .repeater-block span.elementor-repeater-tool-btn.close-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block.block-visible { + padding-block-end: 0; + margin-block-end: 0; +} +.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.toggle-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.close-repeater-row { + display: inline-block; +} +.elementor-metabox-content .repeater-block:not(.block-visible) .close-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block .repeater-title { + cursor: pointer; +} +.elementor-metabox-content .repeater-block .elementor-field-file { + display: flex; + align-items: center; + background-color: #fff; + padding: 10px 20px; + margin-block-end: 10px; + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.05); +} +.elementor-metabox-content .repeater-block .elementor-field-file:last-child { + margin-block-end: 0; +} +.elementor-metabox-content .repeater-block .elementor-field-file p, +.elementor-metabox-content .repeater-block .elementor-field-file input { + box-sizing: border-box; + flex-grow: 1; + width: 100%; + margin: 0; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-label { + font-weight: 500; + max-width: 120px; + width: 100%; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input { + padding: 5px 8px; + margin: 0 15px; + border-radius: 3px; + font-size: 12px; + width: 100%; + background: none; + box-shadow: none; + color: #0C0D0E; + border: 1px solid; + outline: none; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:not(:focus) { + border-color: #D5D8DC; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:focus { + border-color: #9DA5AE; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-btn, +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn { + max-width: 100px; + font-size: 11px; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn { + transition: all 0.3s; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn:hover { + background-color: #DC2626; + border-color: #DC2626; + box-shadow: none; + color: white; +} +.elementor-metabox-content .row-font-label { + padding: 0; + margin: 0; + display: flex; + text-transform: capitalize; + justify-content: space-between; + align-items: center; +} +.elementor-metabox-content .row-font-label li { + box-sizing: border-box; + flex-grow: 1; + width: 100%; + margin: 0; +} +.elementor-metabox-content .row-font-label li span.label { + font-weight: 500; + padding-inline-end: 10px; +} +.elementor-metabox-content .row-font-label li.row-font-weight, .elementor-metabox-content .row-font-label li.row-font-style { + max-width: 180px; +} +.elementor-metabox-content .row-font-label li.row-font-actions { + max-width: 200px; + text-align: end; +} +.elementor-metabox-content .repeater-content { + margin: 0; +} +.elementor-metabox-content .repeater-content .repeater-content-top { + display: flex; + justify-content: space-between; + align-items: center; + margin-block-end: 20px; + line-height: 28px; +} +.elementor-metabox-content .repeater-content .repeater-content-top > div { + box-sizing: border-box; + flex-grow: 1; +} +.elementor-metabox-content .repeater-content .repeater-content-top p { + margin: 0; + display: inline-block; +} +.elementor-metabox-content .repeater-content .repeater-content-top p label { + font-weight: 500; + padding-inline-end: 10px; +} +.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-select { + max-width: 180px; +} +.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-toolbar { + max-width: 200px; + text-align: end; +} +.elementor-metabox-content .repeater-content .repeater-content-bottom { + background-color: #F9FAFA; + padding: 20px 40px; + margin: 0 -20px; +} +.elementor-metabox-content input.button.add-repeater-row { + margin-block-start: 18px; +} +.elementor-metabox-content .elementor-repeater-tool-btn { + cursor: pointer; + padding: 0 20px; + font-size: 12px; + transition: all 0.3s; +} +.elementor-metabox-content .elementor-repeater-tool-btn i { + padding-inline-end: 5px; +} +.elementor-metabox-content .elementor-repeater-tool-btn:hover { + color: #3f444b; +} +.elementor-metabox-content .elementor-repeater-tool-btn.remove-repeater-row:hover { + color: #DC2626; +} + +.row-font-preview, +.inline-preview, +.widefat td.column-font_preview { + font-size: 30px; + text-transform: capitalize; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 600px; + line-height: 1.5; +} + +.post-type-elementor_icons .elementor-metabox-content .elementor-button:not([disabled]) { + margin-block-start: 10px; +} +.post-type-elementor_icons div#postbox-container-1 { + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox { + display: none; + border: 1px solid #F1F2F3; + border-radius: 1px; + background-color: #fff; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .inside { + margin-block: 10px 20px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-metabox-content { + background-color: #fff; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox { + padding-block: 4px 10px; + padding-inline: 10px; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox { + padding: 0; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox h4 { + color: #1f2124; + font-size: 22px; + font-weight: 500; + letter-spacing: 0.7px; + line-height: 28px; + margin: 0 0 4px 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox h5 { + color: #9DA5AE; + font-size: 16px; + font-weight: 500; + letter-spacing: 0.5px; + line-height: 21px; + margin: 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor--dropzone--upload__icon i { + font-size: 64px; + color: #0A875A; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__uploading, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__success, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__error, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__file { + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .is-dragover { + background-color: grey; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__input { + padding: 180px 0; + display: flex; + flex-direction: column; + align-items: center; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-field-dropzone { + outline: 2px dashed #D5D8DC; + outline-offset: -3px; + background-color: #fff; + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons { + background-color: #F9FAFA; + border: 1px solid #F1F2F3; + border-radius: 1px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content { + background-color: #F9FAFA; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content .elementor-custom-icons-metabox { + padding-block: 4px 0; + padding-inline: 10px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header { + height: 50px; + color: #3f444b; + background-color: #fff; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.06); + padding: 0 35px; + display: flex; + align-items: center; + justify-content: flex-start; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header { + padding: 0 6px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div { + padding-inline: 10px; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div { + line-height: 1; + } + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div.remove { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div:nth-of-type(2) { + border: 1px solid #9DA5AE; + border-block-start: 0; + border-block-end: 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta { + color: #1f2124; + font-size: 14px; + line-height: 1; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value { + font-weight: bold; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove { + margin-inline-start: auto; + color: #1f2124; + opacity: 0.6; + cursor: pointer; + transition: all 0.3s; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove i { + color: #3f444b; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove:hover { + opacity: 1; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-footer { + color: #BABFC5; + font-family: Roboto, Arial, Helvetica, sans-serif; + border-block-start: 1px solid #F1F2F3; + font-size: 11px; + font-weight: 500; + line-height: 1; + text-align: end; + padding-block: 10px; + padding-inline-end: 35px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(105px, 1fr)); + grid-gap: 20px; + padding-block: 15px 0; + padding-inline: 35px; + overflow-y: auto; + max-height: 575px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li { + position: relative; + height: 0; + padding-block-end: 100%; + background-color: #fff; + box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05); + border-radius: 3px; + overflow: hidden; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 1px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name { + color: #BABFC5; + font-size: 11px; + padding: 18px 20px 0; + white-space: nowrap; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; +} +@media (max-width: 479px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name { + display: none; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li i { + font-size: 32px; +} +.post-type-elementor_icons #tagsdiv-elementor_icon_type, +.post-type-elementor_icons #minor-publishing-actions, +.post-type-elementor_icons #misc-publishing-actions { + display: none; +} + +.column-icons_prefix { + width: 65%; +} +/*# sourceMappingURL=admin.css.map */ \ No newline at end of file diff --git a/assets/css/admin.min.css b/assets/css/admin.min.css new file mode 100644 index 00000000..4ea07cc1 --- /dev/null +++ b/assets/css/admin.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.wrap.elementor-admin-page-license .elementor-license-box{background:#fff;margin:20px 0;max-width:600px;padding:20px}.wrap.elementor-admin-page-license .elementor-license-box h3{align-items:center;border-block-end:1px solid #eee;display:flex;justify-content:space-between;margin:0;padding:0;padding-block-end:20px}.wrap.elementor-admin-page-license .elementor-license-box h3 span{flex-grow:1;padding-inline-start:5px}.wrap.elementor-admin-page-license .elementor-license-box h3 small{font-size:13px;font-weight:400}.wrap.elementor-admin-page-license .elementor-license-box label{display:block;font-size:1.3em;font-weight:600;margin:1em 0}.wrap.elementor-admin-page-license .elementor-license-box .button{height:30px;margin-block-end:0;margin-inline-start:15px}.wrap.elementor-admin-page-license .elementor-license-box p.description{margin:10px 0}.wrap.elementor-admin-page-license .elementor-license-box .e-row-stretch,.wrap.elementor-admin-page-license .elementor-license-box.e-row-stretch{align-items:center;display:flex;justify-content:space-between}.wrap.elementor-admin-page-license .elementor-license-box .e-row-divider-bottom{border-block-end:1px solid #eee;padding-block-end:15px}.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link{border-color:#93003f;color:#93003f}.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link:hover{background-color:#93003f;color:#fff}.wrap.elementor-admin-page-license .elementor-box-action{align-items:flex-end;display:flex;justify-content:flex-end;margin-block-start:30px}.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link{color:#72777c;margin-inline-end:15px}.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link:hover{color:inherit}#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]{background-color:#93003f;border-radius:3px;color:#fff;display:block;font-size:12px;font-weight:600;line-height:1.5;margin:3px 10px 0;padding:5px 0;text-align:center;transition:all .3s}#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:focus,#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:hover{background-color:#c60055;box-shadow:none}.fixed .column-elementor_library_type,.fixed .column-instances{width:10%}.fixed .elementor-shortcode-input{min-width:235px}@media (min-width:768px) and (max-width:1440px){.fixed .column-shortcode{width:25%}.fixed .elementor-shortcode-input{min-width:100%}}#available-widgets [class*=elementor-template] .widget-title:before{content:"\e801";font-family:eicon;font-size:17px}#elementor-widget-template-empty-templates{margin-block-start:15px;text-align:center}.elementor-widget-template-empty-templates-title{padding:25px 0 30px}.elementor-widget-template-empty-templates-icon{font-size:96px}.elementor-widget-template-empty-templates-footer{color:var(--e-a-color-txt-muted);font-size:13px;font-style:italic;margin-block-end:15px}.elementor-button-spinner.error:before{color:red;content:"\f335"}@media screen and (max-width:782px){.e-form-submissions-list-table.wp-list-table tr:not(.inline-edit-row):not(.no-items)>td.bulk-checkbox-column:not(.check-column){width:2.2em!important}}.e-form-submissions-list-table .bulk-checkbox-column{padding:9px 0 0 3px;width:2.2em}.e-form-submissions-list-table .column-actions{width:11%}.e-form-submissions-list-table .column-actions i{font-size:15px}.e-form-submissions-list-table .column-id{width:7%}.e-form-submissions-list-table .column-page{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:17%}.e-form-submissions-list-table .column-date{width:17%}.e-form-submissions-list-table .column-form{width:20%}.e-form-submissions-referer-icon{font-size:18px}.e-form-submissions-main .postbox{border:none}.e-form-submissions-main .postbox-header{border:1px solid #d5d8dc;border-block-end:none;padding:8px}.e-form-submissions-main__header{align-items:center;display:flex;justify-content:space-between;width:100%}#e-form-submissions .eicon-success{color:#5cb85c}#e-form-submissions .eicon-error{color:#d9534f}#e-form-submissions .misc-pub-section{line-height:1.3rem}#e-form-submissions .e-form-submissions-item-table{border:none;border-collapse:collapse}#e-form-submissions .e-form-submissions-item-table td:first-child{background:#f9fafa;font-weight:700;width:150px}@media screen and (max-width:782px){#e-form-submissions .e-form-submissions-item-table td:first-child{width:90px!important}}#e-form-submissions .e-form-submissions-item-table td{border:1px solid #d5d8dc;padding:15px}#e-form-submissions .e-form-submissions-item-table input:not([type=checkbox]):not([type=radio]),#e-form-submissions .e-form-submissions-item-table select,#e-form-submissions .e-form-submissions-item-table textarea{max-width:400px;width:100%}#e-form-submissions .e-export-button{margin-inline-start:15px}@media screen and (max-width:782px){#e-form-submissions .e-export-button{display:none}}#e-form-submissions .tablenav .actions select{width:10rem}#e-form-submissions .tablenav .actions .select2-container{float:left;margin-right:6px}#e-form-submissions .tablenav .actions .select2-container .select2-selection__arrow{height:30px}#e-form-submissions .tablenav .actions .select2-container .select2-selection--single{border:1px solid #7e8993;height:30px}input[type=search].select2-search__field{line-height:1}.e-form-submissions-search{position:relative}.e-form-submissions-search__spinner{align-items:center;color:var(--wp-admin-theme-color-darker-20,#005a87);display:flex;font-size:11px;height:100%;inset-inline-end:12px;position:absolute}.e-form-submissions-search:focus-within .e-form-submissions-search__spinner,.e-form-submissions-search:hover .e-form-submissions-search__spinner{inset-inline-end:30px}.e-form-submissions-action-log--success .e-form-submissions-action-log__message{background:#dff0d8;border-color:#5cb85c}.e-form-submissions-action-log--error .e-form-submissions-action-log__message{background:#f2dede;border-color:#d9534f}.e-form-submissions-action-log:not(:last-child){border-block-end:1px solid #d5d8dc}.e-form-submissions-action-log__label{display:inline-block;padding-inline-end:15px}.e-form-submissions-action-log__icon{display:inline-block;padding-inline-end:3px}.e-form-submissions-action-log__date{color:#69727d;font-size:12px}.e-form-submissions-action-log__message{background:#f1f2f3;border-inline-start:4px solid #69727d;color:#1f2124;font-size:12px;padding:10px}.e-form-submissions-value-label:not(:last-child){display:block;margin-block-end:10px}span.font-variations-count{background-color:#d4dffb;border-radius:11px;color:#4278b2;display:inline-block;font-size:9px;height:17px;line-height:17px;margin:1px 0 0 5px;min-width:7px;padding:0 5px;text-align:center;vertical-align:top;z-index:26}.post-type-elementor_font #elementor-font-custommetabox{background:none;border:0}.post-type-elementor_font #elementor-font-custommetabox button.handlediv{display:none}.post-type-elementor_font #elementor-font-custommetabox .inside{margin-block-start:15px}.post-type-elementor_font #elementor-font-custommetabox h2.hndle{font-size:16px;padding-inline:0}.post-type-elementor_font #elementor-font-custommetabox .handle-actions{display:none}.post-type-elementor_font #elementor-font-custommetabox .elementor-metabox-content:not(.has-font-variable):not(.has-font-static){display:flex}.post-type-elementor_font #minor-publishing-actions,.post-type-elementor_font #misc-publishing-actions,.post-type-elementor_font #tagsdiv-elementor_font_type{display:none}.elementor-metabox-content #add-variable-font{margin-block-start:18px;margin-inline-start:18px}.elementor-metabox-content.has-font-variable .repeater-content-bottom{display:flex;flex-direction:column}.elementor-metabox-content.has-font-variable .variable-weight-wrap,.elementor-metabox-content.has-font-variable .variable-width-wrap{display:flex;gap:20px;margin-block:10px;min-height:30px;order:1}.elementor-metabox-content.has-font-variable #add-variable-font,.elementor-metabox-content.has-font-variable .add-repeater-row,.elementor-metabox-content.has-font-variable .font_style,.elementor-metabox-content.has-font-variable .font_weight,.elementor-metabox-content.has-font-variable .repeater-block .elementor-field-file:not(.ttf),.elementor-metabox-content.has-font-variable .row-font-style,.elementor-metabox-content.has-font-variable .row-font-weight,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_max,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_min,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_max,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_min,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_max,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_min,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_max,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_min{display:none}.elementor-metabox-content.has-font-variable .elementor-field-input{align-items:center;display:flex;min-width:80px}.elementor-metabox-content.has-font-variable .variable-description{margin-block:20px 10px;order:1}.elementor-metabox-content.has-font-variable .variable_weight .elementor-field-label,.elementor-metabox-content.has-font-variable .variable_width .elementor-field-label{order:1}.elementor-metabox-content.has-font-variable .variable_weight_max label,.elementor-metabox-content.has-font-variable .variable_weight_min label,.elementor-metabox-content.has-font-variable .variable_width_max label,.elementor-metabox-content.has-font-variable .variable_width_min label{min-width:80px}.elementor-metabox-content.has-font-variable .variable_weight_max input,.elementor-metabox-content.has-font-variable .variable_weight_min input,.elementor-metabox-content.has-font-variable .variable_width_max input,.elementor-metabox-content.has-font-variable .variable_width_min input{max-width:80px}.elementor-metabox-content.has-font-static #add-variable-font,.elementor-metabox-content.has-font-static .variable-description,.elementor-metabox-content.has-font-static .variable-weight-wrap,.elementor-metabox-content.has-font-static .variable-width-wrap{display:none}.elementor-metabox-content .repeater-block{background:#fff;color:#3f444b;margin-block-end:2px;padding:20px}.elementor-metabox-content .repeater-block span.elementor-repeater-tool-btn.close-repeater-row{display:none}.elementor-metabox-content .repeater-block.block-visible{margin-block-end:0;padding-block-end:0}.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.toggle-repeater-row{display:none}.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.close-repeater-row{display:inline-block}.elementor-metabox-content .repeater-block:not(.block-visible) .close-repeater-row{display:none}.elementor-metabox-content .repeater-block .repeater-title{cursor:pointer}.elementor-metabox-content .repeater-block .elementor-field-file{align-items:center;background-color:#fff;box-shadow:0 3px 5px rgba(0,0,0,.05);display:flex;margin-block-end:10px;padding:10px 20px}.elementor-metabox-content .repeater-block .elementor-field-file:last-child{margin-block-end:0}.elementor-metabox-content .repeater-block .elementor-field-file input,.elementor-metabox-content .repeater-block .elementor-field-file p{box-sizing:border-box;flex-grow:1;margin:0;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-label{font-weight:500;max-width:120px;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input{background:none;border:1px solid;border-radius:3px;box-shadow:none;color:#0c0d0e;font-size:12px;margin:0 15px;outline:none;padding:5px 8px;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:not(:focus){border-color:#d5d8dc}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:focus{border-color:#9da5ae}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-btn,.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn{font-size:11px;max-width:100px}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn{transition:all .3s}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn:hover{background-color:#dc2626;border-color:#dc2626;box-shadow:none;color:#fff}.elementor-metabox-content .row-font-label{align-items:center;display:flex;justify-content:space-between;margin:0;padding:0;text-transform:capitalize}.elementor-metabox-content .row-font-label li{box-sizing:border-box;flex-grow:1;margin:0;width:100%}.elementor-metabox-content .row-font-label li span.label{font-weight:500;padding-inline-end:10px}.elementor-metabox-content .row-font-label li.row-font-style,.elementor-metabox-content .row-font-label li.row-font-weight{max-width:180px}.elementor-metabox-content .row-font-label li.row-font-actions{max-width:200px;text-align:end}.elementor-metabox-content .repeater-content{margin:0}.elementor-metabox-content .repeater-content .repeater-content-top{align-items:center;display:flex;justify-content:space-between;line-height:28px;margin-block-end:20px}.elementor-metabox-content .repeater-content .repeater-content-top>div{box-sizing:border-box;flex-grow:1}.elementor-metabox-content .repeater-content .repeater-content-top p{display:inline-block;margin:0}.elementor-metabox-content .repeater-content .repeater-content-top p label{font-weight:500;padding-inline-end:10px}.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-select{max-width:180px}.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-toolbar{max-width:200px;text-align:end}.elementor-metabox-content .repeater-content .repeater-content-bottom{background-color:#f9fafa;margin:0 -20px;padding:20px 40px}.elementor-metabox-content input.button.add-repeater-row{margin-block-start:18px}.elementor-metabox-content .elementor-repeater-tool-btn{cursor:pointer;font-size:12px;padding:0 20px;transition:all .3s}.elementor-metabox-content .elementor-repeater-tool-btn i{padding-inline-end:5px}.elementor-metabox-content .elementor-repeater-tool-btn:hover{color:#3f444b}.elementor-metabox-content .elementor-repeater-tool-btn.remove-repeater-row:hover{color:#dc2626}.inline-preview,.row-font-preview,.widefat td.column-font_preview{font-size:30px;line-height:1.5;max-width:600px;overflow:hidden;text-overflow:ellipsis;text-transform:capitalize;white-space:nowrap}.post-type-elementor_icons .elementor-metabox-content .elementor-button:not([disabled]){margin-block-start:10px}.post-type-elementor_icons div#postbox-container-1{display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox{background-color:#fff;border:1px solid #f1f2f3;border-radius:1px;display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox .inside{margin-block:10px 20px}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-metabox-content{background-color:#fff}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox{padding-block:4px 10px;padding-inline:10px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox{padding:0}}.post-type-elementor_icons div#elementor-custom-icons-metabox h4{color:#1f2124;font-size:22px;font-weight:500;letter-spacing:.7px;line-height:28px;margin:0 0 4px}.post-type-elementor_icons div#elementor-custom-icons-metabox h5{color:#9da5ae;font-size:16px;font-weight:500;letter-spacing:.5px;line-height:21px;margin:0}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor--dropzone--upload__icon i{color:#0a875a;font-size:64px}.post-type-elementor_icons div#elementor-custom-icons-metabox .box__error,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__file,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__success,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__uploading{display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox .is-dragover{background-color:grey}.post-type-elementor_icons div#elementor-custom-icons-metabox .box__input{align-items:center;display:flex;flex-direction:column;padding:180px 0}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-field-dropzone{background-color:#fff;display:none;outline:2px dashed #d5d8dc;outline-offset:-3px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons{background-color:#f9fafa;border:1px solid #f1f2f3;border-radius:1px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content{background-color:#f9fafa}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content .elementor-custom-icons-metabox{padding-block:4px 0;padding-inline:10px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header{align-items:center;background-color:#fff;box-shadow:0 2px 6px 0 rgba(0,0,0,.06);color:#3f444b;display:flex;height:50px;justify-content:flex-start;padding:0 35px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header{padding:0 6px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div{padding-inline:10px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div{line-height:1}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div.remove{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div:nth-of-type(2){border:1px solid #9da5ae;border-block-end:0;border-block-start:0}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta{color:#1f2124;font-size:14px;line-height:1}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value{font-weight:700}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove{color:#1f2124;cursor:pointer;margin-inline-start:auto;opacity:.6;transition:all .3s}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove i{color:#3f444b}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove:hover{opacity:1}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-footer{border-block-start:1px solid #f1f2f3;color:#babfc5;font-family:Roboto,Arial,Helvetica,sans-serif;font-size:11px;font-weight:500;line-height:1;padding-block:10px;padding-inline-end:35px;text-align:end}.post-type-elementor_icons div#elementor-custom-icons-metabox ul{display:grid;grid-template-columns:repeat(auto-fill,minmax(105px,1fr));grid-gap:20px;max-height:575px;overflow-y:auto;padding-block:15px 0;padding-inline:35px}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li{background-color:#fff;border-radius:3px;box-shadow:0 1px 12px rgba(0,0,0,.05);height:0;overflow:hidden;padding-block-end:100%;position:relative}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon{align-items:center;display:flex;flex-direction:column;left:50%;padding:1px;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name{color:#babfc5;font-size:11px;max-width:100%;overflow:hidden;padding:18px 20px 0;text-overflow:ellipsis;white-space:nowrap}@media (max-width:479px){.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name{display:none}}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li i{font-size:32px}.post-type-elementor_icons #minor-publishing-actions,.post-type-elementor_icons #misc-publishing-actions,.post-type-elementor_icons #tagsdiv-elementor_icon_type{display:none}.column-icons_prefix{width:65%} \ No newline at end of file diff --git a/assets/css/app.css b/assets/css/app.css new file mode 100644 index 00000000..6a329aaa --- /dev/null +++ b/assets/css/app.css @@ -0,0 +1,363 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +:root { + --color-box-shadow-color: rgba(0, 0, 0, 0.05); +} + +.eps-theme-dark { + --color-box-shadow-color: rgba(0, 0, 0, 0.1); +} + +:root { + --eps-meta-icon-color: #818A96; +} + +.eps-theme-dark { + --eps-meta-icon-color: #BABFC5; +} + +.e-site-template__meta-data { + margin-inline-start: 0.625rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.6875rem; +} +.e-site-template__meta-data:last-of-type { + margin-inline-end: auto; +} +.e-site-template__meta-data:first-of-type { + margin-inline-start: 1rem; +} +.e-site-template__meta-data .eps-icon { + margin-inline-end: 0.3125rem; + color: var(--eps-meta-icon-color); + font-size: 0.8125rem; +} +.e-site-template__placeholder .eps-card__image { + filter: var(--placeholder-filter, none); +} +.e-site-template__overlay-preview { + padding-block-start: calc(var(--card-image-aspect-ratio, 95.6%) - 1.875rem); + position: relative; +} +.e-site-template__overlay-preview-button { + font-weight: bold; + display: flex; + flex-wrap: wrap; + height: 1.875rem; + width: 100%; + background-color: var(--card-background-color-hover); + justify-content: center; + align-items: center; + padding-block-start: 0.625rem; + line-height: 1.25rem; + --button-background-color: var(--card-headline-color); +} +.e-site-template__overlay-preview-button::before { + content: ""; + position: absolute; + display: block; + width: 100%; + top: 0; + left: 0; + padding-block-start: calc(var(--card-image-aspect-ratio, 95.6%) - 1.875rem); +} +.e-site-template__overlay-preview-button > :not(:first-child) { + margin-inline-start: 0.3125rem; +} +.e-site-template__edit-btn { + margin-inline-end: 1.25rem; +} +.e-site-template__edit-btn .eps-icon { + margin-inline-end: 0.3125rem; +} +.e-site-template__instances .eps-icon { + margin-inline-end: 0.3125rem; + color: var(--eps-meta-icon-color); + font-size: 0.8125rem; +} +.e-site-template__instances-list { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.e-site-template__edit-conditions { + margin-inline-start: 1rem; + text-decoration: underline; + font-style: italic; +} +.e-site-template--extended .eps-card__figure { + overflow: auto; +} +.e-site-template--extended .eps-card__headline { + flex-grow: 0; +} +.e-site-template--wide { + --card-image-aspect-ratio: 12.35%; +} + +.eps-add-new__overlay { + display: flex; + align-items: center; + justify-content: center; + opacity: 1; + --card-image-overlay-background-color: transparent; +} + +.e-site-editor__templates .page-header { + margin-block-end: 0.625rem; +} +.e-site-editor__templates .page-header > a { + align-self: baseline; +} +.e-site-editor__templates .eps-separator { + margin-block-end: 2.75rem; +} + +:root { + --e-site-editor-conditions-row-controls-background: #ffffff; + --e-site-editor-input-wrapper-border-color: #D5D8DC; + --e-site-editor-input-wrapper-select-color: #3f444b; + --e-site-editor-conditions-row-controls-border: 1px solid #D5D8DC; + --e-site-editor-add-button-background-color: #69727D; + --e-site-editor-add-button-color-hover-background-color: #515962; + --e-site-editor-input-wrapper-condition-include-background-color: + #69727D; + --e-site-editor-input-wrapper-condition-exclude-background-color: + #818A96; + --e-site-editor-input-select2-search-field-color: #515962 ; +} + +.eps-theme-dark { + --select2-selection-background-color: tints(600); + --e-site-editor-conditions-row-controls-background: #515962; + --e-site-editor-input-wrapper-border-color: #3f444b; + --e-site-editor-input-wrapper-select-color: #BABFC5; + --e-site-editor-conditions-row-controls-border: 1px solid #3f444b; + --e-site-editor-add-button-background-color: #69727D; + --e-site-editor-add-button-color-hover-background-color: #515962; + --e-site-editor-input-wrapper-condition-include-background-color: + #515962; + --e-site-editor-input-wrapper-condition-exclude-background-color: + #515962; + --e-site-editor-input-select2-search-field-color: #ffffff ; +} + +.e-site-editor-conditions__header { + text-align: center; +} +.e-site-editor-conditions__header-image { + display: block; + margin: 0 auto 2.75rem; + width: 4.375rem; +} +.e-site-editor-conditions__rows { + margin: 2.75rem auto; + max-width: 43.75rem; +} +.e-site-editor-conditions__row { + display: flex; + flex-grow: 1; + margin-block-start: 0.75rem; +} +.e-site-editor-conditions__remove-condition { + color: #818A96; + font-size: 1.125rem; + display: flex; + align-items: center; + justify-content: center; +} +.e-site-editor-conditions__row-controls { + overflow: hidden; + margin-inline-end: 0.625rem; + background-color: var(--e-site-editor-conditions-row-controls-background); + display: flex; + width: 100%; + border: var(--e-site-editor-conditions-row-controls-border); + border-radius: 0.1875rem; +} +.e-site-editor-conditions__row-controls--error { + border: 1px solid #DC2626; +} +.e-site-editor-conditions__conflict { + text-align: center; + margin-block-start: 0.3125rem; + color: #DC2626; +} +.e-site-editor-conditions__row-controls-inner { + width: 100%; + display: flex; +} +.e-site-editor-conditions__row-controls-inner div { + flex: 1; +} +.e-site-editor-conditions__add-button-container { + text-align: center; +} +.e-site-editor-conditions__add-button { + margin-block-start: 2.75rem; + background-color: var(--e-site-editor-add-button-background-color); + color: #ffffff; + text-transform: uppercase; +} +.e-site-editor-conditions__add-button:hover { + background-color: var(--e-site-editor-add-button-color-hover-background-color); + color: #ffffff; +} +.e-site-editor-conditions__footer { + display: flex; + justify-content: flex-end; + padding: 0.5rem; + margin-top: 1rem; +} +.e-site-editor-conditions__input-wrapper { + position: relative; + padding-inline-start: 1px solid; + border-color: var(--e-site-editor-input-wrapper-border-color); +} +.e-site-editor-conditions__input-wrapper:first-child { + border: none; +} +.e-site-editor-conditions__input-wrapper select { + -moz-appearance: none; + appearance: none; + -webkit-appearance: none; + font-size: 0.75rem; + height: 2.5rem; + border-width: 0; + padding: 0 0.625rem; + width: 100%; + position: relative; + color: var(--e-site-editor-input-wrapper-select-color); + outline: none; + background: transparent; +} +.e-site-editor-conditions__input-wrapper::after { + font-family: eicons; + content: "\e8ad"; + font-size: 0.75rem; + pointer-events: none; + position: absolute; + inset-block-start: 50%; + inset-inline-end: 0.625rem; + transform: translateY(-50%); +} +.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single { + border: none; + line-height: 2.5rem; +} +.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered { + line-height: 2.5rem; + font-size: 0.75rem; +} +.e-site-editor-conditions__input-wrapper .select2-selection { + outline: none; + background: transparent; + height: 2.5rem; +} +.e-site-editor-conditions__input-wrapper .select2-selection__arrow { + display: none; +} +.e-site-editor-conditions__input-wrapper--condition-type { + position: relative; +} +.e-site-editor-conditions__input-wrapper--condition-type::before { + font-family: eicons; + position: absolute; + transform: translateY(-50%); + inset-block-start: 50%; + inset-inline-start: 0.75rem; + font-size: 0.9375rem; + pointer-events: none; + z-index: 1000; +} +.e-site-editor-conditions__input-wrapper--condition-type select { + text-transform: uppercase; + padding-inline-start: 2.125rem; + width: 7.5rem; + font-size: 0.75rem; + border-inline-end: 1px solid; + border-color: var(--e-site-editor-input-wrapper-border-color); +} +.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=include]::before { + content: "\e8cc"; +} +.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=exclude]::before { + content: "\e8cd"; +} + +.select2-search__field { + background-color: transparent; + color: var(--e-site-editor-input-select2-search-field-color); +} + +.eps-back-button { + font-size: 14px; + margin-block-end: 1.5rem; +} +.eps-back-button .eps-icon { + scale: calc(1 * var(--direction-multiplier, 1)) 1; +} + +:root { + --indicator-bullet-border-color: #ffffff; +} + +.eps-theme-dark { + --indicator-bullet-border-color: #69727D; +} + +.eps-indicator-bullet { + display: block; + flex-shrink: 0; + width: 0.75rem; + height: 0.75rem; + box-shadow: 0 2px 3px 1px var(--color-box-shadow-color); + background-color: #9DA5AE; + border: 2px solid var(--indicator-bullet-border-color); + border-radius: 100%; + margin-inline-end: 0.625rem; +} +.eps-indicator-bullet--active { + background-color: #0A875A; +} + +.site-editor__preview-iframe { + height: 50vh; + position: relative; +} +.site-editor__preview-iframe__iframe { + top: 0; + left: 0; + position: absolute; + border: none; + transform-origin: 0 0; + height: 100%; +} +.site-editor__preview-iframe--header, .site-editor__preview-iframe--footer { + height: 15vh; +} + +.e-site-editor__content_container { + flex-direction: column; + min-height: 100%; + flex-wrap: nowrap; +} + +.e-site-editor__content_container_main { + flex: 1; + padding: 1.875rem; +} + +.e-site-editor__content_container_secondary { + margin: 0 auto; + align-items: center; + border-block-start: 1px solid var(--hr-color); + padding-block: 1rem; + padding-inline: 1.875rem; +} + +.eps-app__content:has(.e-site-editor__content_container_main) { + padding: 0; +} +/*# sourceMappingURL=app.css.map */ \ No newline at end of file diff --git a/assets/css/app.min.css b/assets/css/app.min.css new file mode 100644 index 00000000..61c3ac25 --- /dev/null +++ b/assets/css/app.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +:root{--color-box-shadow-color:rgba(0,0,0,.05)}.eps-theme-dark{--color-box-shadow-color:rgba(0,0,0,.1)}:root{--eps-meta-icon-color:#818a96}.eps-theme-dark{--eps-meta-icon-color:#babfc5}.e-site-template__meta-data{font-size:.6875rem;margin-inline-start:.625rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.e-site-template__meta-data:last-of-type{margin-inline-end:auto}.e-site-template__meta-data:first-of-type{margin-inline-start:1rem}.e-site-template__meta-data .eps-icon{color:var(--eps-meta-icon-color);font-size:.8125rem;margin-inline-end:.3125rem}.e-site-template__placeholder .eps-card__image{filter:var(--placeholder-filter,none)}.e-site-template__overlay-preview{padding-block-start:calc(var(--card-image-aspect-ratio, 95.6%) - 1.875rem);position:relative}.e-site-template__overlay-preview-button{align-items:center;background-color:var(--card-background-color-hover);display:flex;flex-wrap:wrap;font-weight:700;height:1.875rem;justify-content:center;line-height:1.25rem;padding-block-start:.625rem;width:100%;--button-background-color:var(--card-headline-color)}.e-site-template__overlay-preview-button:before{content:"";display:block;left:0;padding-block-start:calc(var(--card-image-aspect-ratio, 95.6%) - 1.875rem);position:absolute;top:0;width:100%}.e-site-template__overlay-preview-button>:not(:first-child){margin-inline-start:.3125rem}.e-site-template__edit-btn{margin-inline-end:1.25rem}.e-site-template__edit-btn .eps-icon{margin-inline-end:.3125rem}.e-site-template__instances .eps-icon{color:var(--eps-meta-icon-color);font-size:.8125rem;margin-inline-end:.3125rem}.e-site-template__instances-list{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.e-site-template__edit-conditions{font-style:italic;margin-inline-start:1rem;text-decoration:underline}.e-site-template--extended .eps-card__figure{overflow:auto}.e-site-template--extended .eps-card__headline{flex-grow:0}.e-site-template--wide{--card-image-aspect-ratio:12.35%}.eps-add-new__overlay{align-items:center;display:flex;justify-content:center;opacity:1;--card-image-overlay-background-color:transparent}.e-site-editor__templates .page-header{margin-block-end:.625rem}.e-site-editor__templates .page-header>a{align-self:baseline}.e-site-editor__templates .eps-separator{margin-block-end:2.75rem}:root{--e-site-editor-conditions-row-controls-background:#fff;--e-site-editor-input-wrapper-border-color:#d5d8dc;--e-site-editor-input-wrapper-select-color:#3f444b;--e-site-editor-conditions-row-controls-border:1px solid #d5d8dc;--e-site-editor-add-button-background-color:#69727d;--e-site-editor-add-button-color-hover-background-color:#515962;--e-site-editor-input-wrapper-condition-include-background-color:#69727d;--e-site-editor-input-wrapper-condition-exclude-background-color:#818a96;--e-site-editor-input-select2-search-field-color:#515962}.eps-theme-dark{--select2-selection-background-color:tints(600);--e-site-editor-conditions-row-controls-background:#515962;--e-site-editor-input-wrapper-border-color:#3f444b;--e-site-editor-input-wrapper-select-color:#babfc5;--e-site-editor-conditions-row-controls-border:1px solid #3f444b;--e-site-editor-add-button-background-color:#69727d;--e-site-editor-add-button-color-hover-background-color:#515962;--e-site-editor-input-wrapper-condition-include-background-color:#515962;--e-site-editor-input-wrapper-condition-exclude-background-color:#515962;--e-site-editor-input-select2-search-field-color:#fff}.e-site-editor-conditions__header{text-align:center}.e-site-editor-conditions__header-image{display:block;margin:0 auto 2.75rem;width:4.375rem}.e-site-editor-conditions__rows{margin:2.75rem auto;max-width:43.75rem}.e-site-editor-conditions__row{display:flex;flex-grow:1;margin-block-start:.75rem}.e-site-editor-conditions__remove-condition{align-items:center;color:#818a96;display:flex;font-size:1.125rem;justify-content:center}.e-site-editor-conditions__row-controls{background-color:var(--e-site-editor-conditions-row-controls-background);border:var(--e-site-editor-conditions-row-controls-border);border-radius:.1875rem;display:flex;margin-inline-end:.625rem;overflow:hidden;width:100%}.e-site-editor-conditions__row-controls--error{border:1px solid #dc2626}.e-site-editor-conditions__conflict{color:#dc2626;margin-block-start:.3125rem;text-align:center}.e-site-editor-conditions__row-controls-inner{display:flex;width:100%}.e-site-editor-conditions__row-controls-inner div{flex:1}.e-site-editor-conditions__add-button-container{text-align:center}.e-site-editor-conditions__add-button{background-color:var(--e-site-editor-add-button-background-color);color:#fff;margin-block-start:2.75rem;text-transform:uppercase}.e-site-editor-conditions__add-button:hover{background-color:var(--e-site-editor-add-button-color-hover-background-color);color:#fff}.e-site-editor-conditions__footer{display:flex;justify-content:flex-end;margin-top:1rem;padding:.5rem}.e-site-editor-conditions__input-wrapper{border-color:var(--e-site-editor-input-wrapper-border-color);padding-inline-start:1px solid;position:relative}.e-site-editor-conditions__input-wrapper:first-child{border:none}.e-site-editor-conditions__input-wrapper select{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:transparent;border-width:0;color:var(--e-site-editor-input-wrapper-select-color);font-size:.75rem;height:2.5rem;outline:none;padding:0 .625rem;position:relative;width:100%}.e-site-editor-conditions__input-wrapper:after{content:"\e8ad";font-family:eicons;font-size:.75rem;inset-block-start:50%;inset-inline-end:.625rem;pointer-events:none;position:absolute;transform:translateY(-50%)}.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single{border:none;line-height:2.5rem}.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered{font-size:.75rem;line-height:2.5rem}.e-site-editor-conditions__input-wrapper .select2-selection{background:transparent;height:2.5rem;outline:none}.e-site-editor-conditions__input-wrapper .select2-selection__arrow{display:none}.e-site-editor-conditions__input-wrapper--condition-type{position:relative}.e-site-editor-conditions__input-wrapper--condition-type:before{font-family:eicons;font-size:.9375rem;inset-block-start:50%;inset-inline-start:.75rem;pointer-events:none;position:absolute;transform:translateY(-50%);z-index:1000}.e-site-editor-conditions__input-wrapper--condition-type select{border-inline-end:1px solid;border-color:var(--e-site-editor-input-wrapper-border-color);font-size:.75rem;padding-inline-start:2.125rem;text-transform:uppercase;width:7.5rem}.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=include]:before{content:"\e8cc"}.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=exclude]:before{content:"\e8cd"}.select2-search__field{background-color:transparent;color:var(--e-site-editor-input-select2-search-field-color)}.eps-back-button{font-size:14px;margin-block-end:1.5rem}.eps-back-button .eps-icon{scale:calc(1 * var(--direction-multiplier, 1)) 1}:root{--indicator-bullet-border-color:#fff}.eps-theme-dark{--indicator-bullet-border-color:#69727d}.eps-indicator-bullet{background-color:#9da5ae;border:2px solid var(--indicator-bullet-border-color);border-radius:100%;box-shadow:0 2px 3px 1px var(--color-box-shadow-color);display:block;flex-shrink:0;height:.75rem;margin-inline-end:.625rem;width:.75rem}.eps-indicator-bullet--active{background-color:#0a875a}.site-editor__preview-iframe{height:50vh;position:relative}.site-editor__preview-iframe__iframe{border:none;height:100%;left:0;position:absolute;top:0;transform-origin:0 0}.site-editor__preview-iframe--footer,.site-editor__preview-iframe--header{height:15vh}.e-site-editor__content_container{flex-direction:column;flex-wrap:nowrap;min-height:100%}.e-site-editor__content_container_main{flex:1;padding:1.875rem}.e-site-editor__content_container_secondary{align-items:center;border-block-start:1px solid var(--hr-color);margin:0 auto;padding-block:1rem;padding-inline:1.875rem}.eps-app__content:has(.e-site-editor__content_container_main){padding:0} \ No newline at end of file diff --git a/assets/css/conditionals/popup.css b/assets/css/conditionals/popup.css new file mode 100644 index 00000000..4e429ce7 --- /dev/null +++ b/assets/css/conditionals/popup.css @@ -0,0 +1,53 @@ +[data-elementor-type=popup]:not(.elementor-edit-area) { + display: none; +} +[data-elementor-type=popup] .elementor-section-wrap:not(:empty) + #elementor-add-new-section { + display: none; +} + +.elementor-popup-modal.dialog-type-lightbox { + display: flex; + pointer-events: none; + background-color: transparent; + user-select: auto; +} +.elementor-popup-modal .dialog-header, .elementor-popup-modal .dialog-buttons-wrapper { + display: none; +} +.elementor-popup-modal .dialog-close-button { + display: none; + top: 20px; + margin-top: 0; + inset-inline-end: 20px; + opacity: 1; + z-index: 9999; + pointer-events: all; +} +.elementor-popup-modal .dialog-close-button svg { + fill: #1f2124; + height: 1em; + width: 1em; +} +.elementor-popup-modal .dialog-widget-content { + background-color: #fff; + width: initial; + overflow: visible; + max-width: 100%; + max-height: 100%; + border-radius: 0; + box-shadow: none; + pointer-events: all; +} +.elementor-popup-modal .dialog-message { + width: 640px; + max-width: 100vw; + max-height: 100vh; + padding: 0; + overflow: auto; + display: flex; +} +.elementor-popup-modal .elementor { + width: 100%; +} + +/*# sourceMappingURL=popup.css.map */ \ No newline at end of file diff --git a/assets/css/conditionals/popup.min.css b/assets/css/conditionals/popup.min.css new file mode 100644 index 00000000..34fbb4b5 --- /dev/null +++ b/assets/css/conditionals/popup.min.css @@ -0,0 +1 @@ +[data-elementor-type=popup] .elementor-section-wrap:not(:empty)+#elementor-add-new-section,[data-elementor-type=popup]:not(.elementor-edit-area){display:none}.elementor-popup-modal.dialog-type-lightbox{background-color:transparent;display:flex;pointer-events:none;-webkit-user-select:auto;-moz-user-select:auto;user-select:auto}.elementor-popup-modal .dialog-buttons-wrapper,.elementor-popup-modal .dialog-header{display:none}.elementor-popup-modal .dialog-close-button{display:none;inset-inline-end:20px;margin-top:0;opacity:1;pointer-events:all;top:20px;z-index:9999}.elementor-popup-modal .dialog-close-button svg{fill:#1f2124;height:1em;width:1em}.elementor-popup-modal .dialog-widget-content{background-color:#fff;border-radius:0;box-shadow:none;max-height:100%;max-width:100%;overflow:visible;pointer-events:all;width:auto}.elementor-popup-modal .dialog-message{display:flex;max-height:100vh;max-width:100vw;overflow:auto;padding:0;width:640px}.elementor-popup-modal .elementor{width:100%} \ No newline at end of file diff --git a/assets/css/conditionals/ribbon.css b/assets/css/conditionals/ribbon.css new file mode 100644 index 00000000..77faecc0 --- /dev/null +++ b/assets/css/conditionals/ribbon.css @@ -0,0 +1,40 @@ +.elementor-ribbon { + position: absolute; + inset-block-start: 0; + inset-inline: auto 0; + width: 150px; + height: 150px; + z-index: 1; + overflow: hidden; + transform: rotate(90deg); +} +[dir=rtl] .elementor-ribbon { + transform: rotate(0); +} +.elementor-ribbon-inner { + left: 0; + transform: translateY(-50%) translateX(-50%) translateX(35px) rotate(-45deg); + width: 200%; + margin-block-start: 35px; + font-size: 13px; + font-weight: 800; + line-height: 2; + text-align: center; + text-transform: uppercase; + background: #000; +} +[dir=rtl] .elementor-ribbon-inner { + transform: translateY(-50%) translateX(0) translateX(35px) rotate(-45deg); +} +.elementor-ribbon.elementor-ribbon-left { + transform: rotate(0); + left: 0; + right: auto; +} +.elementor-ribbon.elementor-ribbon-right { + transform: rotate(90deg); + left: auto; + right: 0; +} + +/*# sourceMappingURL=ribbon.css.map */ \ No newline at end of file diff --git a/assets/css/conditionals/ribbon.min.css b/assets/css/conditionals/ribbon.min.css new file mode 100644 index 00000000..2f64fa5c --- /dev/null +++ b/assets/css/conditionals/ribbon.min.css @@ -0,0 +1 @@ +.elementor-ribbon{height:150px;inset-block-start:0;inset-inline:auto 0;overflow:hidden;position:absolute;transform:rotate(90deg);width:150px;z-index:1}[dir=rtl] .elementor-ribbon{transform:rotate(0)}.elementor-ribbon-inner{background:#000;font-size:13px;font-weight:800;left:0;line-height:2;margin-block-start:35px;text-align:center;text-transform:uppercase;transform:translateY(-50%) translateX(-50%) translateX(35px) rotate(-45deg);width:200%}[dir=rtl] .elementor-ribbon-inner{transform:translateY(-50%) translateX(0) translateX(35px) rotate(-45deg)}.elementor-ribbon.elementor-ribbon-left{left:0;right:auto;transform:rotate(0)}.elementor-ribbon.elementor-ribbon-right{left:auto;right:0;transform:rotate(90deg)} \ No newline at end of file diff --git a/assets/css/conditionals/transitions.css b/assets/css/conditionals/transitions.css new file mode 100644 index 00000000..c210f45f --- /dev/null +++ b/assets/css/conditionals/transitions.css @@ -0,0 +1,111 @@ +.elementor-animated-content { + --translate: 0, 0; +} +.elementor-animated-content:hover .elementor-animated-item--grow, .elementor-animated-content:focus .elementor-animated-item--grow { + transform: scale(1.1); +} +.elementor-animated-content:hover .elementor-animated-item--shrink, .elementor-animated-content:focus .elementor-animated-item--shrink { + transform: scale(0.85); +} +.elementor-animated-content:hover .elementor-animated-item--shrink-contained, .elementor-animated-content:focus .elementor-animated-item--shrink-contained { + transform: scale(1); +} +.elementor-animated-content:hover .elementor-animated-item--enter-zoom-out, .elementor-animated-content:hover .elementor-animated-item--enter-zoom-in, .elementor-animated-content:hover .elementor-animated-item--fade-in, .elementor-animated-content:focus .elementor-animated-item--enter-zoom-out, .elementor-animated-content:focus .elementor-animated-item--enter-zoom-in, .elementor-animated-content:focus .elementor-animated-item--fade-in { + transform: scale(1); + opacity: 1; +} +.elementor-animated-content:hover .elementor-animated-item--exit-zoom-out, .elementor-animated-content:hover .elementor-animated-item--exit-zoom-in, .elementor-animated-content:hover .elementor-animated-item--fade-out, .elementor-animated-content:focus .elementor-animated-item--exit-zoom-out, .elementor-animated-content:focus .elementor-animated-item--exit-zoom-in, .elementor-animated-content:focus .elementor-animated-item--fade-out { + opacity: 0; +} +.elementor-animated-content:hover .elementor-animated-item--exit-zoom-out, .elementor-animated-content:focus .elementor-animated-item--exit-zoom-out { + transform: scale(0.2); +} +.elementor-animated-content:hover .elementor-animated-item--exit-zoom-in, .elementor-animated-content:focus .elementor-animated-item--exit-zoom-in { + transform: scale(2); +} +.elementor-animated-content:hover .elementor-animated-item--enter-from-right, .elementor-animated-content:hover .elementor-animated-item--enter-from-left, .elementor-animated-content:hover .elementor-animated-item--enter-from-top, .elementor-animated-content:hover .elementor-animated-item--enter-from-bottom, .elementor-animated-content:focus .elementor-animated-item--enter-from-right, .elementor-animated-content:focus .elementor-animated-item--enter-from-left, .elementor-animated-content:focus .elementor-animated-item--enter-from-top, .elementor-animated-content:focus .elementor-animated-item--enter-from-bottom { + opacity: 1; + transform: translateY(0) translateX(0); +} +.elementor-animated-content:hover .elementor-animated-item--exit-to-right, .elementor-animated-content:focus .elementor-animated-item--exit-to-right { + transform: translateX(1000px); +} +.elementor-animated-content:hover .elementor-animated-item--exit-to-left, .elementor-animated-content:focus .elementor-animated-item--exit-to-left { + transform: translateX(-1000px); +} +.elementor-animated-content:hover .elementor-animated-item--exit-to-top, .elementor-animated-content:focus .elementor-animated-item--exit-to-top { + transform: translateY(-600px); +} +.elementor-animated-content:hover .elementor-animated-item--exit-to-bottom, .elementor-animated-content:focus .elementor-animated-item--exit-to-bottom { + transform: translateY(600px); +} +.elementor-animated-content:hover .elementor-animated-item--exit-to-right, .elementor-animated-content:hover .elementor-animated-item--exit-to-left, .elementor-animated-content:hover .elementor-animated-item--exit-to-top, .elementor-animated-content:hover .elementor-animated-item--exit-to-bottom, .elementor-animated-content:focus .elementor-animated-item--exit-to-right, .elementor-animated-content:focus .elementor-animated-item--exit-to-left, .elementor-animated-content:focus .elementor-animated-item--exit-to-top, .elementor-animated-content:focus .elementor-animated-item--exit-to-bottom { + opacity: 0; +} +.elementor-animated-content:hover .elementor-animated-item--move-right, .elementor-animated-content:focus .elementor-animated-item--move-right { + transform: translateX(30px); +} +.elementor-animated-content:hover .elementor-animated-item--move-left, .elementor-animated-content:focus .elementor-animated-item--move-left { + transform: translateX(-30px); +} +.elementor-animated-content:hover .elementor-animated-item--move-up, .elementor-animated-content:focus .elementor-animated-item--move-up { + transform: translateY(-30px); +} +.elementor-animated-content:hover .elementor-animated-item--move-down, .elementor-animated-content:focus .elementor-animated-item--move-down { + transform: translateY(30px); +} +.elementor-animated-content:hover .elementor-animated-item--move-contained-right, .elementor-animated-content:focus .elementor-animated-item--move-contained-right { + --translate: 8%, 0; +} +.elementor-animated-content:hover .elementor-animated-item--move-contained-left, .elementor-animated-content:focus .elementor-animated-item--move-contained-left { + --translate: -8%, 0; +} +.elementor-animated-content:hover .elementor-animated-item--move-contained-top, .elementor-animated-content:focus .elementor-animated-item--move-contained-top { + --translate: 0, -8%; +} +.elementor-animated-content:hover .elementor-animated-item--move-contained-bottom, .elementor-animated-content:focus .elementor-animated-item--move-contained-bottom { + --translate: 0, 8%; +} +.elementor-animated-content *[class^=elementor-animated-item] { + will-change: transform, opacity; +} +.elementor-animated-content .elementor-animated-item--shrink-contained { + transform: scale(1.17); +} +.elementor-animated-content .elementor-animated-item--enter-zoom-in { + transform: scale(0.2); +} +.elementor-animated-content .elementor-animated-item--enter-zoom-out { + transform: scale(2); +} +.elementor-animated-content .elementor-animated-item--enter-zoom-out, .elementor-animated-content .elementor-animated-item--enter-zoom-in, .elementor-animated-content .elementor-animated-item--fade-in { + opacity: 0; +} +.elementor-animated-content .elementor-animated-item--exit-zoom-out, .elementor-animated-content .elementor-animated-item--exit-zoom-in, .elementor-animated-content .elementor-animated-item--fade-out { + opacity: 1; + transform: scale(1); +} +.elementor-animated-content .elementor-animated-item--enter-from-right { + transform: translateX(1000px); +} +.elementor-animated-content .elementor-animated-item--enter-from-left { + transform: translateX(-1000px); +} +.elementor-animated-content .elementor-animated-item--enter-from-top { + transform: translateY(-600px); +} +.elementor-animated-content .elementor-animated-item--enter-from-bottom { + transform: translateY(500px); +} +.elementor-animated-content .elementor-animated-item--enter-from-right, .elementor-animated-content .elementor-animated-item--enter-from-left, .elementor-animated-content .elementor-animated-item--enter-from-top, .elementor-animated-content .elementor-animated-item--enter-from-bottom { + opacity: 0; +} +.elementor-animated-content .elementor-animated-item--exit-to-right, .elementor-animated-content .elementor-animated-item--exit-to-left, .elementor-animated-content .elementor-animated-item--exit-to-top, .elementor-animated-content .elementor-animated-item--exit-to-bottom { + opacity: 1; + transform: translateY(0) translateX(0); +} +.elementor-animated-content .elementor-animated-item--move-contained-right, .elementor-animated-content .elementor-animated-item--move-contained-left, .elementor-animated-content .elementor-animated-item--move-contained-top, .elementor-animated-content .elementor-animated-item--move-contained-bottom { + transform: scale(1.2) translate(var(--translate)); +} + +/*# sourceMappingURL=transitions.css.map */ \ No newline at end of file diff --git a/assets/css/conditionals/transitions.min.css b/assets/css/conditionals/transitions.min.css new file mode 100644 index 00000000..74c0548a --- /dev/null +++ b/assets/css/conditionals/transitions.min.css @@ -0,0 +1 @@ +.elementor-animated-content{--translate:0,0}.elementor-animated-content:focus .elementor-animated-item--grow,.elementor-animated-content:hover .elementor-animated-item--grow{transform:scale(1.1)}.elementor-animated-content:focus .elementor-animated-item--shrink,.elementor-animated-content:hover .elementor-animated-item--shrink{transform:scale(.85)}.elementor-animated-content:focus .elementor-animated-item--shrink-contained,.elementor-animated-content:hover .elementor-animated-item--shrink-contained{transform:scale(1)}.elementor-animated-content:focus .elementor-animated-item--enter-zoom-in,.elementor-animated-content:focus .elementor-animated-item--enter-zoom-out,.elementor-animated-content:focus .elementor-animated-item--fade-in,.elementor-animated-content:hover .elementor-animated-item--enter-zoom-in,.elementor-animated-content:hover .elementor-animated-item--enter-zoom-out,.elementor-animated-content:hover .elementor-animated-item--fade-in{opacity:1;transform:scale(1)}.elementor-animated-content:focus .elementor-animated-item--exit-zoom-in,.elementor-animated-content:focus .elementor-animated-item--exit-zoom-out,.elementor-animated-content:focus .elementor-animated-item--fade-out,.elementor-animated-content:hover .elementor-animated-item--exit-zoom-in,.elementor-animated-content:hover .elementor-animated-item--exit-zoom-out,.elementor-animated-content:hover .elementor-animated-item--fade-out{opacity:0}.elementor-animated-content:focus .elementor-animated-item--exit-zoom-out,.elementor-animated-content:hover .elementor-animated-item--exit-zoom-out{transform:scale(.2)}.elementor-animated-content:focus .elementor-animated-item--exit-zoom-in,.elementor-animated-content:hover .elementor-animated-item--exit-zoom-in{transform:scale(2)}.elementor-animated-content:focus .elementor-animated-item--enter-from-bottom,.elementor-animated-content:focus .elementor-animated-item--enter-from-left,.elementor-animated-content:focus .elementor-animated-item--enter-from-right,.elementor-animated-content:focus .elementor-animated-item--enter-from-top,.elementor-animated-content:hover .elementor-animated-item--enter-from-bottom,.elementor-animated-content:hover .elementor-animated-item--enter-from-left,.elementor-animated-content:hover .elementor-animated-item--enter-from-right,.elementor-animated-content:hover .elementor-animated-item--enter-from-top{opacity:1;transform:translateY(0) translateX(0)}.elementor-animated-content:focus .elementor-animated-item--exit-to-right,.elementor-animated-content:hover .elementor-animated-item--exit-to-right{transform:translateX(1000px)}.elementor-animated-content:focus .elementor-animated-item--exit-to-left,.elementor-animated-content:hover .elementor-animated-item--exit-to-left{transform:translateX(-1000px)}.elementor-animated-content:focus .elementor-animated-item--exit-to-top,.elementor-animated-content:hover .elementor-animated-item--exit-to-top{transform:translateY(-600px)}.elementor-animated-content:focus .elementor-animated-item--exit-to-bottom,.elementor-animated-content:hover .elementor-animated-item--exit-to-bottom{transform:translateY(600px)}.elementor-animated-content:focus .elementor-animated-item--exit-to-bottom,.elementor-animated-content:focus .elementor-animated-item--exit-to-left,.elementor-animated-content:focus .elementor-animated-item--exit-to-right,.elementor-animated-content:focus .elementor-animated-item--exit-to-top,.elementor-animated-content:hover .elementor-animated-item--exit-to-bottom,.elementor-animated-content:hover .elementor-animated-item--exit-to-left,.elementor-animated-content:hover .elementor-animated-item--exit-to-right,.elementor-animated-content:hover .elementor-animated-item--exit-to-top{opacity:0}.elementor-animated-content:focus .elementor-animated-item--move-right,.elementor-animated-content:hover .elementor-animated-item--move-right{transform:translateX(30px)}.elementor-animated-content:focus .elementor-animated-item--move-left,.elementor-animated-content:hover .elementor-animated-item--move-left{transform:translateX(-30px)}.elementor-animated-content:focus .elementor-animated-item--move-up,.elementor-animated-content:hover .elementor-animated-item--move-up{transform:translateY(-30px)}.elementor-animated-content:focus .elementor-animated-item--move-down,.elementor-animated-content:hover .elementor-animated-item--move-down{transform:translateY(30px)}.elementor-animated-content:focus .elementor-animated-item--move-contained-right,.elementor-animated-content:hover .elementor-animated-item--move-contained-right{--translate:8%,0}.elementor-animated-content:focus .elementor-animated-item--move-contained-left,.elementor-animated-content:hover .elementor-animated-item--move-contained-left{--translate:-8%,0}.elementor-animated-content:focus .elementor-animated-item--move-contained-top,.elementor-animated-content:hover .elementor-animated-item--move-contained-top{--translate:0,-8%}.elementor-animated-content:focus .elementor-animated-item--move-contained-bottom,.elementor-animated-content:hover .elementor-animated-item--move-contained-bottom{--translate:0,8%}.elementor-animated-content [class^=elementor-animated-item]{will-change:transform,opacity}.elementor-animated-content .elementor-animated-item--shrink-contained{transform:scale(1.17)}.elementor-animated-content .elementor-animated-item--enter-zoom-in{transform:scale(.2)}.elementor-animated-content .elementor-animated-item--enter-zoom-out{transform:scale(2)}.elementor-animated-content .elementor-animated-item--enter-zoom-in,.elementor-animated-content .elementor-animated-item--enter-zoom-out,.elementor-animated-content .elementor-animated-item--fade-in{opacity:0}.elementor-animated-content .elementor-animated-item--exit-zoom-in,.elementor-animated-content .elementor-animated-item--exit-zoom-out,.elementor-animated-content .elementor-animated-item--fade-out{opacity:1;transform:scale(1)}.elementor-animated-content .elementor-animated-item--enter-from-right{transform:translateX(1000px)}.elementor-animated-content .elementor-animated-item--enter-from-left{transform:translateX(-1000px)}.elementor-animated-content .elementor-animated-item--enter-from-top{transform:translateY(-600px)}.elementor-animated-content .elementor-animated-item--enter-from-bottom{transform:translateY(500px)}.elementor-animated-content .elementor-animated-item--enter-from-bottom,.elementor-animated-content .elementor-animated-item--enter-from-left,.elementor-animated-content .elementor-animated-item--enter-from-right,.elementor-animated-content .elementor-animated-item--enter-from-top{opacity:0}.elementor-animated-content .elementor-animated-item--exit-to-bottom,.elementor-animated-content .elementor-animated-item--exit-to-left,.elementor-animated-content .elementor-animated-item--exit-to-right,.elementor-animated-content .elementor-animated-item--exit-to-top{opacity:1;transform:translateY(0) translateX(0)}.elementor-animated-content .elementor-animated-item--move-contained-bottom,.elementor-animated-content .elementor-animated-item--move-contained-left,.elementor-animated-content .elementor-animated-item--move-contained-right,.elementor-animated-content .elementor-animated-item--move-contained-top{transform:scale(1.2) translate(var(--translate))} \ No newline at end of file diff --git a/assets/css/editor.css b/assets/css/editor.css new file mode 100644 index 00000000..a9b15ab9 --- /dev/null +++ b/assets/css/editor.css @@ -0,0 +1,593 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-panel .elementor-control .e-control-error { + color: #F59E0B; +} +.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-content { + flex-flow: row; + align-items: center; +} +.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-title { + width: 45%; +} +.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-raw-html { + width: 55%; +} +.elementor-panel .elementor-control .elementor-button.elementor-button-default.elementor-button-center { + display: block; + margin: 0 auto; +} + +#elementor-element--promotion__dialog .dialog-header .eicon-pro-icon { + visibility: hidden; +} + +.elementor-context-menu-list__item { + position: relative; +} +.elementor-context-menu-list__item__shortcut .eicon-advanced { + font-size: 16px; + color: var(--e-a-color-txt-muted); +} +.elementor-context-menu-list__item__shortcut--link-fullwidth { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 2; + cursor: pointer; +} + +#elementor-widget-template-empty-templates { + margin-block-start: 15px; + text-align: center; +} + +.elementor-widget-template-empty-templates-title { + padding: 25px 0 30px; +} + +.elementor-widget-template-empty-templates-icon { + font-size: 96px; +} + +.elementor-widget-template-empty-templates-footer { + color: var(--e-a-color-txt-muted); + font-size: 13px; + font-style: italic; + margin-block-end: 15px; +} + +#elementor-panel-global-widget { + height: 100%; +} +#elementor-panel-global-widget > * { + background-color: var(--e-a-bg-default); +} + +#elementor-global-widget-locked-header { + border-block-end: var(--e-a-border); +} +#elementor-global-widget-locked-header.elementor-nerd-box { + padding: 40px 25px; +} +#elementor-global-widget-locked-header.elementor-nerd-box .elementor-nerd-box-icon { + margin-block-start: 20px; +} + +#elementor-global-widget-locked-tools { + margin-block-start: 15px; + padding: 0 20px; +} + +.elementor-global-widget-locked-tool { + display: flex; + padding: 20px 0; + align-items: center; +} +.elementor-global-widget-locked-tool .elementor-button { + min-width: 70px; +} + +.elementor-global-widget-locked-tool-description { + flex-grow: 1; +} + +#elementor-global-widget-locked-unlink { + border-block-start: var(--e-a-border); +} + +#elementor-global-templates .elementor-element { + position: relative; +} +#elementor-global-templates .elementor-element:before { + position: absolute; + font-family: eicons; + content: "\e91f"; + top: 5px; + left: 5px; + font-size: 10px; +} +#elementor-global-templates .elementor-element:hover:before { + color: var(--e-a-color-global); +} + +#elementor-global-widget-loading { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + align-items: center; + justify-content: center; +} +#elementor-global-widget-loading:not(.elementor-hidden) { + display: flex; +} +#elementor-global-widget-loading i { + font-size: 50px; +} + +.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields { + margin: 10px 0; +} +.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields .elementor-control { + padding: 0; +} +.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields:last-child { + margin-block-end: 0; +} + +.elementor-repeater-row--form-step .elementor-repeater-row-tools:hover { + background-color: #BABFC5; +} +.elementor-repeater-row--form-step .elementor-repeater-row-tools div:not(.elementor-repeater-row-handle-sortable) { + background-color: #F1F2F3; +} +.elementor-repeater-row--form-step .elementor-repeater-row-tools div:not(.elementor-repeater-row-handle-sortable):hover { + background-color: #ffffff; +} + +.elementor-facebook-widget.fb_iframe_widget { + width: 100% !important; +} +.elementor-facebook-widget.fb_iframe_widget span { + width: 100% !important; +} +.elementor-facebook-widget.fb_iframe_widget iframe { + position: relative; + width: 100% !important; +} +.elementor-facebook-widget.fb-like { + height: 1px; +} + +.elementor-widget-facebook-comments iframe { + width: 100% !important; +} + +#elementor-publish { + height: 100%; + display: flex; +} +#elementor-publish__modal .dialog-message { + padding: 0; +} +#elementor-publish__modal .dialog-buttons-wrapper { + display: flex; +} +#elementor-publish__tabs { + padding-block-start: 50px; +} +@media (max-width: 1439px) { + #elementor-publish__tabs { + width: 28%; + } +} +#elementor-publish__screen { + overflow: auto; + padding: 50px; +} + +.elementor-publish__tab { + display: flex; + align-items: center; + position: relative; + height: 110px; + padding: 20px 15px; + cursor: pointer; +} +.elementor-publish__tab:hover { + background-color: var(--e-a-bg-hover); +} +.elementor-publish__tab.elementor-active { + background-color: var(--e-a-bg-active); + color: var(--e-a-color-txt-accent); +} +.elementor-publish__tab.elementor-active::after { + content: ""; + position: absolute; + inset-block-start: 0; + inset-inline-start: 0; + height: 100%; + width: 3px; + background-color: var(--e-a-border-color-accent); +} +.elementor-publish__tab__image { + width: 50px; + flex-shrink: 0; +} +.elementor-publish__tab__image img { + width: 100%; +} +.elementor-publish__tab__content { + text-align: start; + padding-inline-start: 15px; +} +.elementor-publish__tab__title { + font-size: 18px; + font-weight: bold; +} + +#elementor-theme-builder-conditions { + margin: 40px 0 60px; +} +#elementor-theme-builder-conditions-view { + overflow: hidden; +} +#elementor-theme-builder-conditions .elementor-control { + background-color: transparent; + padding: 0; +} +#elementor-theme-builder-conditions .elementor-control::before { + content: none; +} +#elementor-theme-builder-conditions .elementor-control select { + border-width: 0; + height: 40px; + padding: 0 14px; +} +#elementor-theme-builder-conditions .elementor-control-type-query { + width: 100px; +} +#elementor-theme-builder-conditions .elementor-control-type-select .elementor-control-input-wrapper::after { + inset-inline-end: 10px; +} +#elementor-theme-builder-conditions .elementor-control-type { + width: 120px; +} +#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=include] .elementor-control-input-wrapper::before { + content: "\e8cc"; +} +#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=exclude] .elementor-control-input-wrapper::before { + content: "\e8cd"; +} +#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=exclude] select, #elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=include] select { + padding-inline-start: 33px; +} +#elementor-theme-builder-conditions .elementor-control-type .elementor-control-input-wrapper::before { + font-family: eicons; + position: absolute; + inset-block-start: 50%; + inset-inline-start: 13px; + transform: translateY(-50%); + font-size: 15px; +} +#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls { + display: flex; + flex-grow: 1; + margin-inline-end: 10px; + width: 70%; + border: var(--e-a-border-bold); + overflow: hidden; + border-radius: var(--e-a-border-radius); +} +#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls .elementor-control:not(:first-child) { + flex-grow: 1; + border-inline-start: var(--e-a-border-bold); + margin-inline-start: 1px; +} +#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls .elementor-control:not(:first-child) select { + border-radius: 0; +} +#elementor-theme-builder-conditions .elementor-repeater-fields-wrapper { + max-width: 700px; + width: 100%; + margin: auto; +} +#elementor-theme-builder-conditions .elementor-repeater-fields { + display: flex; + align-items: center; + justify-content: center; + margin-block-start: 10px; +} +#elementor-theme-builder-conditions .elementor-control-field { + display: block; +} +#elementor-theme-builder-conditions .elementor-control-title, +#elementor-theme-builder-conditions .elementor-control-spinner { + display: none; +} +#elementor-theme-builder-conditions .elementor-control-input-wrapper { + width: 100%; + max-width: initial; +} +#elementor-theme-builder-conditions .select2-selection { + height: 40px; + border: none; + border-radius: 0; +} +#elementor-theme-builder-conditions .select2-selection__rendered { + line-height: 40px; + padding-inline-start: 15px; + text-align: start; +} +#elementor-theme-builder-conditions .select2-selection__arrow { + height: 30px; +} +#elementor-theme-builder-conditions .select2-selection__arrow b { + border-width: 4px 4px 0; + margin-block-start: 2px; + margin-inline-start: -7px; +} +#elementor-theme-builder-conditions .elementor-repeater-tool-remove { + font-size: 18px; + cursor: pointer; + color: var(--e-a-color-txt); +} +#elementor-theme-builder-conditions .elementor-button-wrapper { + margin-block-start: 50px; +} +#elementor-theme-builder-conditions .elementor-repeater-add { + padding: 12px 26px; +} + +.elementor-error .elementor-theme-builder-conditions-repeater-row-controls { + border: 1px solid var(--e-a-color-warning); +} + +.elementor-conditions-conflict-message { + margin-block-start: 10px; + font-size: 14px; + font-weight: 400; + line-height: 1.4; + color: var(--e-a-color-danger); + text-align: center; +} +.elementor-conditions-conflict-message a, +.elementor-conditions-conflict-message a:hover { + color: var(--e-a-color-danger); +} + +.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu { + display: flex; +} +.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item { + width: 100%; +} +.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item i { + margin-inline-end: 5px; +} +.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item > * { + display: inline-block; + line-height: 40px; +} + +.elementor-conditions-select2-dropdown { + border: none; + border-radius: 0; +} +.elementor-conditions-select2-dropdown .select2-results__message { + display: none; +} +.elementor-conditions-select2-dropdown .select2-search--dropdown .select2-search__field { + border-width: 0 0 1px; + border-radius: 0; +} + +#elementor-toast.e-theme-builder-save-toaster .dialog-buttons-wrapper { + flex-direction: column; +} +#elementor-toast.e-theme-builder-save-toaster .dialog-buttons-message { + text-align: center; +} +#elementor-toast.e-theme-builder-save-toaster .dialog-open_site_editor { + margin-block-end: 10px; +} + +.elementor-control.elementor-control-sitemap_items.elementor-control-type-repeater .elementor-repeater-row-tools .elementor-repeater-row-item-title span { + text-transform: capitalize; +} + +.elementor-editor-popup .elementor-tab-control-settings a::before { + content: "\e922"; +} + +#elementor-publish .elementor-popup__display-settings .elementor-control-type-slider .elementor-control-input-wrapper { + width: 150px; +} +#elementor-publish .elementor-popup__display-settings .elementor-control-input-wrapper { + width: 80px; + max-width: 100%; +} +#elementor-publish .elementor-popup__display-settings .elementor-control-send_app_promo, #elementor-publish .elementor-popup__display-settings .elementor-control-type-raw_html { + padding: 0 0 10px; +} + +.elementor-popup__display-settings { + text-align: start; +} +.elementor-popup__display-settings_controls_group { + display: flex; + align-items: center; + height: 60px; + border: var(--e-a-border); + margin-block-end: 10px; + padding-inline-end: 20px; + border-radius: var(--e-a-border-radius); +} +.elementor-popup__display-settings_controls_group:hover { + background-color: var(--e-a-bg-hover); +} +.elementor-popup__display-settings_controls_group.elementor-active { + background-color: var(--e-a-bg-active); + color: var(--e-a-color-txt-accent); + border-color: var(--e-a-border-color-accent); +} +.elementor-popup__display-settings_controls_group:not(.elementor-active) .elementor-control:nth-child(2) h3 { + color: #9DA5AE; +} +.elementor-popup__display-settings_controls_group__icon { + width: 60px; + height: 60px; + border-inline-end: var(--e-a-border); + display: inline-flex; + align-items: center; + justify-content: center; +} +.elementor-popup__display-settings_controls_group__icon img { + width: 35px; +} +.elementor-popup__display-settings_controls_group .elementor-control { + padding: 0; + margin: 0; +} +.elementor-popup__display-settings_controls_group .elementor-control:nth-child(2) { + width: 230px; +} +.elementor-popup__display-settings_controls_group .elementor-control:nth-child(2) h3 { + font-size: 16px; + font-weight: 400; +} +.elementor-popup__display-settings_controls_group .elementor-control:not(:nth-child(2)) .elementor-control-title:not(:empty) { + width: 75px; +} +.elementor-popup__display-settings_controls_group .elementor-control:not(:last-child) { + margin-inline-start: 25px; +} +.elementor-popup__display-settings_controls_group .elementor-control-type-slider .elementor-control-input-wrapper { + display: flex; +} +.elementor-popup__display-settings_controls_group .elementor-control-type-slider .elementor-slider-input { + width: 45%; +} +.elementor-popup__display-settings_controls_group .elementor-control-type-switcher .elementor-control-field { + justify-content: flex-end; +} +.elementor-popup__display-settings .elementor-control-type-section { + display: none; +} +.elementor-popup__display-settings__group-toggle { + flex-grow: 1; +} + +#elementor-popup-timing__controls .select2-selection { + min-height: 27px; +} +#elementor-popup-timing__controls .select2-selection__rendered { + line-height: 1; +} +#elementor-popup-timing__controls .select2-selection__choice { + font-size: 10px; +} + +#elementor-popup__timing-controls-group--url .elementor-control-url_url .elementor-control-input-wrapper { + width: 200px; +} +#elementor-popup__timing-controls-group--sources .elementor-control-sources_sources .elementor-control-input-wrapper { + width: 300px; +} +#elementor-popup__timing-controls-group--devices .elementor-control-devices_devices .elementor-control-input-wrapper { + width: 330px; +} +#elementor-popup__timing-controls-group--logged_in .elementor-control-logged_in_roles .elementor-control-input-wrapper { + width: 195px; +} +#elementor-popup__timing-controls-group--browsers .elementor-control-browsers_browsers .elementor-control-input-wrapper { + width: 100px; +} +#elementor-popup__timing-controls-group--browsers .elementor-control-browsers_browsers_options .elementor-control-input-wrapper { + width: 200px; +} + +#elementor-popup__timing-controls-group--times .elementor-control-field { + display: unset; +} + +#elementor-popup__timing-controls-group--schedule .elementor-control-title { + width: unset; +} +#elementor-popup__timing-controls-group--schedule .elementor-control-input-wrapper { + margin-block-start: 5px; +} +#elementor-popup__timing-controls-group--schedule div[class*=elementor-control-schedule_] .elementor-control-content .elementor-control-field { + display: block; +} +#elementor-popup__timing-controls-group--schedule div[class*=elementor-control-schedule_] .elementor-control-content .elementor-control-input-wrapper { + width: 108px; +} +#elementor-popup__timing-controls-group--schedule .elementor-control-schedule_timezone { + margin-inline-start: -17px; +} + +.elementor-control-type-raw_html .elementor-descriptor-subtle a { + color: inherit; + border-block-end-color: inherit; + font-weight: 500; +} +.elementor-control-type-raw_html .elementor-descriptor-subtle a:hover { + color: #0C0D0E; +} + +.e-page-transition-preview::before { + content: ""; + height: 1em; + width: 0.8em; + margin-inline-end: 4px; + background-image: url("data:image/svg+xml,%3Csvg width='10' height='13' viewBox='0 0 10 13' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.40554 6.20969C8.6115 6.34841 8.6115 6.65153 8.40554 6.79026L1.19553 11.6467C0.963052 11.8033 0.65 11.6368 0.65 11.3565L0.650001 1.64349C0.650001 1.36319 0.963054 1.19661 1.19553 1.3532L8.40554 6.20969Z' stroke='white' stroke-width='1.3'/%3E%3C/svg%3E%0A"); + background-repeat: no-repeat; + background-size: contain; + display: inline-block; + vertical-align: top; + scale: calc(1 * var(--direction-multiplier, 1)) 1; +} + +.elementor-template-query-control-actions { + display: flex; + align-items: center; + justify-content: center; + margin-block-start: 15px; + gap: 15px; +} + +.e-control-display-conditions__wrapper, +.e-control-display-conditions-promo__wrapper { + display: flex; + justify-content: space-between; +} +.e-control-display-conditions__desc, +.e-control-display-conditions-promo__desc { + align-self: center; +} +.e-control-display-conditions__desc .eicon-lock, +.e-control-display-conditions-promo__desc .eicon-lock { + margin-inline-start: 15px; +} +.e-control-display-conditions__desc .eicon-lock:hover, +.e-control-display-conditions-promo__desc .eicon-lock:hover { + color: var(--e-a-color-accent); +} +.e-control-display-conditions.eicon-flow, +.e-control-display-conditions-promo.eicon-flow { + align-self: flex-end; + cursor: pointer; + border: var(--e-a-border-bold); + border-radius: var(--e-a-border-radius); + padding: 5px; +} +.e-control-display-conditions.eicon-flow.filled, +.e-control-display-conditions-promo.eicon-flow.filled { + background-color: var(--e-a-bg-active); + color: #E73CF6; +} +/*# sourceMappingURL=editor.css.map */ \ No newline at end of file diff --git a/assets/css/editor.min.css b/assets/css/editor.min.css new file mode 100644 index 00000000..82833258 --- /dev/null +++ b/assets/css/editor.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-panel .elementor-control .e-control-error{color:#f59e0b}.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-content{align-items:center;flex-flow:row}.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-title{width:45%}.elementor-panel .elementor-control.forms-field-shortcode .elementor-control-raw-html{width:55%}.elementor-panel .elementor-control .elementor-button.elementor-button-default.elementor-button-center{display:block;margin:0 auto}#elementor-element--promotion__dialog .dialog-header .eicon-pro-icon{visibility:hidden}.elementor-context-menu-list__item{position:relative}.elementor-context-menu-list__item__shortcut .eicon-advanced{color:var(--e-a-color-txt-muted);font-size:16px}.elementor-context-menu-list__item__shortcut--link-fullwidth{cursor:pointer;height:100%;left:0;position:absolute;top:0;width:100%;z-index:2}#elementor-widget-template-empty-templates{margin-block-start:15px;text-align:center}.elementor-widget-template-empty-templates-title{padding:25px 0 30px}.elementor-widget-template-empty-templates-icon{font-size:96px}.elementor-widget-template-empty-templates-footer{color:var(--e-a-color-txt-muted);font-size:13px;font-style:italic;margin-block-end:15px}#elementor-panel-global-widget{height:100%}#elementor-panel-global-widget>*{background-color:var(--e-a-bg-default)}#elementor-global-widget-locked-header{border-block-end:var(--e-a-border)}#elementor-global-widget-locked-header.elementor-nerd-box{padding:40px 25px}#elementor-global-widget-locked-header.elementor-nerd-box .elementor-nerd-box-icon{margin-block-start:20px}#elementor-global-widget-locked-tools{margin-block-start:15px;padding:0 20px}.elementor-global-widget-locked-tool{align-items:center;display:flex;padding:20px 0}.elementor-global-widget-locked-tool .elementor-button{min-width:70px}.elementor-global-widget-locked-tool-description{flex-grow:1}#elementor-global-widget-locked-unlink{border-block-start:var(--e-a-border)}#elementor-global-templates .elementor-element{position:relative}#elementor-global-templates .elementor-element:before{content:"\e91f";font-family:eicons;font-size:10px;left:5px;position:absolute;top:5px}#elementor-global-templates .elementor-element:hover:before{color:var(--e-a-color-global)}#elementor-global-widget-loading{align-items:center;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%}#elementor-global-widget-loading:not(.elementor-hidden){display:flex}#elementor-global-widget-loading i{font-size:50px}.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields{margin:10px 0}.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields .elementor-control{padding:0}.elementor-panel .elementor-control-type-fields_map .elementor-repeater-fields:last-child{margin-block-end:0}.elementor-repeater-row--form-step .elementor-repeater-row-tools:hover{background-color:#babfc5}.elementor-repeater-row--form-step .elementor-repeater-row-tools div:not(.elementor-repeater-row-handle-sortable){background-color:#f1f2f3}.elementor-repeater-row--form-step .elementor-repeater-row-tools div:not(.elementor-repeater-row-handle-sortable):hover{background-color:#fff}.elementor-facebook-widget.fb_iframe_widget,.elementor-facebook-widget.fb_iframe_widget span{width:100%!important}.elementor-facebook-widget.fb_iframe_widget iframe{position:relative;width:100%!important}.elementor-facebook-widget.fb-like{height:1px}.elementor-widget-facebook-comments iframe{width:100%!important}#elementor-publish{display:flex;height:100%}#elementor-publish__modal .dialog-message{padding:0}#elementor-publish__modal .dialog-buttons-wrapper{display:flex}#elementor-publish__tabs{padding-block-start:50px}@media (max-width:1439px){#elementor-publish__tabs{width:28%}}#elementor-publish__screen{overflow:auto;padding:50px}.elementor-publish__tab{align-items:center;cursor:pointer;display:flex;height:110px;padding:20px 15px;position:relative}.elementor-publish__tab:hover{background-color:var(--e-a-bg-hover)}.elementor-publish__tab.elementor-active{background-color:var(--e-a-bg-active);color:var(--e-a-color-txt-accent)}.elementor-publish__tab.elementor-active:after{background-color:var(--e-a-border-color-accent);content:"";height:100%;inset-block-start:0;inset-inline-start:0;position:absolute;width:3px}.elementor-publish__tab__image{flex-shrink:0;width:50px}.elementor-publish__tab__image img{width:100%}.elementor-publish__tab__content{padding-inline-start:15px;text-align:start}.elementor-publish__tab__title{font-size:18px;font-weight:700}#elementor-theme-builder-conditions{margin:40px 0 60px}#elementor-theme-builder-conditions-view{overflow:hidden}#elementor-theme-builder-conditions .elementor-control{background-color:transparent;padding:0}#elementor-theme-builder-conditions .elementor-control:before{content:none}#elementor-theme-builder-conditions .elementor-control select{border-width:0;height:40px;padding:0 14px}#elementor-theme-builder-conditions .elementor-control-type-query{width:100px}#elementor-theme-builder-conditions .elementor-control-type-select .elementor-control-input-wrapper:after{inset-inline-end:10px}#elementor-theme-builder-conditions .elementor-control-type{width:120px}#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=include] .elementor-control-input-wrapper:before{content:"\e8cc"}#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=exclude] .elementor-control-input-wrapper:before{content:"\e8cd"}#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=exclude] select,#elementor-theme-builder-conditions .elementor-control-type[data-elementor-condition-type=include] select{padding-inline-start:33px}#elementor-theme-builder-conditions .elementor-control-type .elementor-control-input-wrapper:before{font-family:eicons;font-size:15px;inset-block-start:50%;inset-inline-start:13px;position:absolute;transform:translateY(-50%)}#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls{border:var(--e-a-border-bold);border-radius:var(--e-a-border-radius);display:flex;flex-grow:1;margin-inline-end:10px;overflow:hidden;width:70%}#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls .elementor-control:not(:first-child){border-inline-start:var(--e-a-border-bold);flex-grow:1;margin-inline-start:1px}#elementor-theme-builder-conditions .elementor-theme-builder-conditions-repeater-row-controls .elementor-control:not(:first-child) select{border-radius:0}#elementor-theme-builder-conditions .elementor-repeater-fields-wrapper{margin:auto;max-width:700px;width:100%}#elementor-theme-builder-conditions .elementor-repeater-fields{align-items:center;display:flex;justify-content:center;margin-block-start:10px}#elementor-theme-builder-conditions .elementor-control-field{display:block}#elementor-theme-builder-conditions .elementor-control-spinner,#elementor-theme-builder-conditions .elementor-control-title{display:none}#elementor-theme-builder-conditions .elementor-control-input-wrapper{max-width:none;width:100%}#elementor-theme-builder-conditions .select2-selection{border:none;border-radius:0;height:40px}#elementor-theme-builder-conditions .select2-selection__rendered{line-height:40px;padding-inline-start:15px;text-align:start}#elementor-theme-builder-conditions .select2-selection__arrow{height:30px}#elementor-theme-builder-conditions .select2-selection__arrow b{border-width:4px 4px 0;margin-block-start:2px;margin-inline-start:-7px}#elementor-theme-builder-conditions .elementor-repeater-tool-remove{color:var(--e-a-color-txt);cursor:pointer;font-size:18px}#elementor-theme-builder-conditions .elementor-button-wrapper{margin-block-start:50px}#elementor-theme-builder-conditions .elementor-repeater-add{padding:12px 26px}.elementor-error .elementor-theme-builder-conditions-repeater-row-controls{border:1px solid var(--e-a-color-warning)}.elementor-conditions-conflict-message{color:var(--e-a-color-danger);font-size:14px;font-weight:400;line-height:1.4;margin-block-start:10px;text-align:center}.elementor-conditions-conflict-message a,.elementor-conditions-conflict-message a:hover{color:var(--e-a-color-danger)}.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu{display:flex}.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item{width:100%}.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item i{margin-inline-end:5px}.elementor-panel-footer-theme-builder-buttons-wrapper .elementor-panel-footer-sub-menu-item>*{display:inline-block;line-height:40px}.elementor-conditions-select2-dropdown{border:none;border-radius:0}.elementor-conditions-select2-dropdown .select2-results__message{display:none}.elementor-conditions-select2-dropdown .select2-search--dropdown .select2-search__field{border-radius:0;border-width:0 0 1px}#elementor-toast.e-theme-builder-save-toaster .dialog-buttons-wrapper{flex-direction:column}#elementor-toast.e-theme-builder-save-toaster .dialog-buttons-message{text-align:center}#elementor-toast.e-theme-builder-save-toaster .dialog-open_site_editor{margin-block-end:10px}.elementor-control.elementor-control-sitemap_items.elementor-control-type-repeater .elementor-repeater-row-tools .elementor-repeater-row-item-title span{text-transform:capitalize}.elementor-editor-popup .elementor-tab-control-settings a:before{content:"\e922"}#elementor-publish .elementor-popup__display-settings .elementor-control-type-slider .elementor-control-input-wrapper{width:150px}#elementor-publish .elementor-popup__display-settings .elementor-control-input-wrapper{max-width:100%;width:80px}#elementor-publish .elementor-popup__display-settings .elementor-control-send_app_promo,#elementor-publish .elementor-popup__display-settings .elementor-control-type-raw_html{padding:0 0 10px}.elementor-popup__display-settings{text-align:start}.elementor-popup__display-settings_controls_group{align-items:center;border:var(--e-a-border);border-radius:var(--e-a-border-radius);display:flex;height:60px;margin-block-end:10px;padding-inline-end:20px}.elementor-popup__display-settings_controls_group:hover{background-color:var(--e-a-bg-hover)}.elementor-popup__display-settings_controls_group.elementor-active{background-color:var(--e-a-bg-active);border-color:var(--e-a-border-color-accent);color:var(--e-a-color-txt-accent)}.elementor-popup__display-settings_controls_group:not(.elementor-active) .elementor-control:nth-child(2) h3{color:#9da5ae}.elementor-popup__display-settings_controls_group__icon{align-items:center;border-inline-end:var(--e-a-border);display:inline-flex;height:60px;justify-content:center;width:60px}.elementor-popup__display-settings_controls_group__icon img{width:35px}.elementor-popup__display-settings_controls_group .elementor-control{margin:0;padding:0}.elementor-popup__display-settings_controls_group .elementor-control:nth-child(2){width:230px}.elementor-popup__display-settings_controls_group .elementor-control:nth-child(2) h3{font-size:16px;font-weight:400}.elementor-popup__display-settings_controls_group .elementor-control:not(:nth-child(2)) .elementor-control-title:not(:empty){width:75px}.elementor-popup__display-settings_controls_group .elementor-control:not(:last-child){margin-inline-start:25px}.elementor-popup__display-settings_controls_group .elementor-control-type-slider .elementor-control-input-wrapper{display:flex}.elementor-popup__display-settings_controls_group .elementor-control-type-slider .elementor-slider-input{width:45%}.elementor-popup__display-settings_controls_group .elementor-control-type-switcher .elementor-control-field{justify-content:flex-end}.elementor-popup__display-settings .elementor-control-type-section{display:none}.elementor-popup__display-settings__group-toggle{flex-grow:1}#elementor-popup-timing__controls .select2-selection{min-height:27px}#elementor-popup-timing__controls .select2-selection__rendered{line-height:1}#elementor-popup-timing__controls .select2-selection__choice{font-size:10px}#elementor-popup__timing-controls-group--url .elementor-control-url_url .elementor-control-input-wrapper{width:200px}#elementor-popup__timing-controls-group--sources .elementor-control-sources_sources .elementor-control-input-wrapper{width:300px}#elementor-popup__timing-controls-group--devices .elementor-control-devices_devices .elementor-control-input-wrapper{width:330px}#elementor-popup__timing-controls-group--logged_in .elementor-control-logged_in_roles .elementor-control-input-wrapper{width:195px}#elementor-popup__timing-controls-group--browsers .elementor-control-browsers_browsers .elementor-control-input-wrapper{width:100px}#elementor-popup__timing-controls-group--browsers .elementor-control-browsers_browsers_options .elementor-control-input-wrapper{width:200px}#elementor-popup__timing-controls-group--times .elementor-control-field{display:unset}#elementor-popup__timing-controls-group--schedule .elementor-control-title{width:unset}#elementor-popup__timing-controls-group--schedule .elementor-control-input-wrapper{margin-block-start:5px}#elementor-popup__timing-controls-group--schedule div[class*=elementor-control-schedule_] .elementor-control-content .elementor-control-field{display:block}#elementor-popup__timing-controls-group--schedule div[class*=elementor-control-schedule_] .elementor-control-content .elementor-control-input-wrapper{width:108px}#elementor-popup__timing-controls-group--schedule .elementor-control-schedule_timezone{margin-inline-start:-17px}.elementor-control-type-raw_html .elementor-descriptor-subtle a{border-block-end-color:inherit;color:inherit;font-weight:500}.elementor-control-type-raw_html .elementor-descriptor-subtle a:hover{color:#0c0d0e}.e-page-transition-preview:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='13' fill='none' viewBox='0 0 10 13'%3E%3Cpath stroke='%23fff' stroke-width='1.3' d='M8.406 6.21a.35.35 0 0 1 0 .58l-7.21 4.857a.35.35 0 0 1-.546-.29V1.643a.35.35 0 0 1 .546-.29z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:inline-block;height:1em;margin-inline-end:4px;scale:calc(1 * var(--direction-multiplier, 1)) 1;vertical-align:top;width:.8em}.elementor-template-query-control-actions{align-items:center;display:flex;gap:15px;justify-content:center;margin-block-start:15px}.e-control-display-conditions-promo__wrapper,.e-control-display-conditions__wrapper{display:flex;justify-content:space-between}.e-control-display-conditions-promo__desc,.e-control-display-conditions__desc{align-self:center}.e-control-display-conditions-promo__desc .eicon-lock,.e-control-display-conditions__desc .eicon-lock{margin-inline-start:15px}.e-control-display-conditions-promo__desc .eicon-lock:hover,.e-control-display-conditions__desc .eicon-lock:hover{color:var(--e-a-color-accent)}.e-control-display-conditions-promo.eicon-flow,.e-control-display-conditions.eicon-flow{align-self:flex-end;border:var(--e-a-border-bold);border-radius:var(--e-a-border-radius);cursor:pointer;padding:5px}.e-control-display-conditions-promo.eicon-flow.filled,.e-control-display-conditions.eicon-flow.filled{background-color:var(--e-a-bg-active);color:#e73cf6} \ No newline at end of file diff --git a/assets/css/modules/custom-code.css b/assets/css/modules/custom-code.css new file mode 100644 index 00000000..5b35d761 --- /dev/null +++ b/assets/css/modules/custom-code.css @@ -0,0 +1,1961 @@ +@keyframes fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +.wrap.elementor-admin-page-license .elementor-license-box { + max-width: 600px; + background: white; + margin: 20px 0; + padding: 20px; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0; + padding: 0; + padding-block-end: 20px; + border-block-end: 1px solid #eee; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 span { + flex-grow: 1; + padding-inline-start: 5px; +} +.wrap.elementor-admin-page-license .elementor-license-box h3 small { + font-size: 13px; + font-weight: normal; +} +.wrap.elementor-admin-page-license .elementor-license-box label { + display: block; + font-size: 1.3em; + font-weight: 600; + margin: 1em 0; +} +.wrap.elementor-admin-page-license .elementor-license-box .button { + height: 30px; + margin-inline-start: 15px; + margin-block-end: 0; +} +.wrap.elementor-admin-page-license .elementor-license-box p.description { + margin: 10px 0; +} +.wrap.elementor-admin-page-license .elementor-license-box .e-row-stretch, .wrap.elementor-admin-page-license .elementor-license-box.e-row-stretch { + display: flex; + align-items: center; + justify-content: space-between; +} +.wrap.elementor-admin-page-license .elementor-license-box .e-row-divider-bottom { + padding-block-end: 15px; + border-block-end: 1px solid #eee; +} +.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link { + color: #93003f; + border-color: #93003f; +} +.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link:hover { + color: #fff; + background-color: #93003f; +} +.wrap.elementor-admin-page-license .elementor-box-action { + display: flex; + justify-content: flex-end; + align-items: flex-end; + margin-block-start: 30px; +} +.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link { + color: #72777c; + margin-inline-end: 15px; +} +.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link:hover { + color: inherit; +} + +#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link] { + font-weight: 600; + font-size: 12px; + line-height: 1.5; + background-color: #93003f; + color: #ffffff; + margin: 3px 10px 0; + padding: 5px 0; + display: block; + text-align: center; + border-radius: 3px; + transition: all 0.3s; +} +#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:hover, #adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:focus { + background-color: rgb(198, 0, 84.8571428571); + box-shadow: none; +} + +.fixed .column-elementor_library_type, +.fixed .column-instances { + width: 10%; +} +.fixed .elementor-shortcode-input { + min-width: 235px; +} +@media (min-width: 768px) and (max-width: 1440px) { + .fixed .column-shortcode { + width: 25%; + } + .fixed .elementor-shortcode-input { + min-width: 100%; + } +} + +#available-widgets [class*=elementor-template] .widget-title:before { + content: "\e801"; + font-family: eicon; + font-size: 17px; +} + +#elementor-widget-template-empty-templates { + margin-block-start: 15px; + text-align: center; +} + +.elementor-widget-template-empty-templates-title { + padding: 25px 0 30px; +} + +.elementor-widget-template-empty-templates-icon { + font-size: 96px; +} + +.elementor-widget-template-empty-templates-footer { + color: var(--e-a-color-txt-muted); + font-size: 13px; + font-style: italic; + margin-block-end: 15px; +} + +.elementor-button-spinner.error:before { + content: "\f335"; + color: #ff0000; +} + +@media screen and (max-width: 782px) { + .e-form-submissions-list-table { + /* Don't judge me... (need to override WordPress style). */ + } + .e-form-submissions-list-table.wp-list-table tr:not(.inline-edit-row):not(.no-items) > td.bulk-checkbox-column:not(.check-column) { + width: 2.2em !important; + } +} +.e-form-submissions-list-table .bulk-checkbox-column { + padding: 9px 0 0 3px; + width: 2.2em; +} +.e-form-submissions-list-table .column-actions { + width: 11%; +} +.e-form-submissions-list-table .column-actions i { + font-size: 15px; +} +.e-form-submissions-list-table .column-id { + width: 7%; +} +.e-form-submissions-list-table .column-page { + width: 17%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} +.e-form-submissions-list-table .column-date { + width: 17%; +} +.e-form-submissions-list-table .column-form { + width: 20%; +} + +.e-form-submissions-referer-icon { + font-size: 18px; +} + +.e-form-submissions-main .postbox { + border: none; +} +.e-form-submissions-main .postbox-header { + border: 1px solid #D5D8DC; + border-block-end: none; + padding: 8px; +} +.e-form-submissions-main__header { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +#e-form-submissions .eicon-success { + color: #5cb85c; +} +#e-form-submissions .eicon-error { + color: #d9534f; +} +#e-form-submissions .misc-pub-section { + line-height: 1.3rem; +} + +#e-form-submissions .e-form-submissions-item-table { + border: none; + border-collapse: collapse; +} +#e-form-submissions .e-form-submissions-item-table td:first-child { + width: 150px; + background: #F9FAFA; + font-weight: 700; +} +@media screen and (max-width: 782px) { + #e-form-submissions .e-form-submissions-item-table td:first-child { + /* Must set !important because wordpress set also !important. */ + width: 90px !important; + } +} +#e-form-submissions .e-form-submissions-item-table td { + border: 1px solid #D5D8DC; + padding: 15px; +} +#e-form-submissions .e-form-submissions-item-table input:not([type=checkbox]):not([type=radio]), #e-form-submissions .e-form-submissions-item-table textarea, #e-form-submissions .e-form-submissions-item-table select { + width: 100%; + max-width: 400px; +} + +#e-form-submissions .e-export-button { + margin-inline-start: 15px; +} +@media screen and (max-width: 782px) { + #e-form-submissions .e-export-button { + display: none; + } +} +#e-form-submissions .tablenav .actions select { + width: 10rem; +} +#e-form-submissions .tablenav .actions .select2-container { + float: left; + margin-right: 6px; +} +#e-form-submissions .tablenav .actions .select2-container .select2-selection__arrow { + height: 30px; +} +#e-form-submissions .tablenav .actions .select2-container .select2-selection--single { + height: 30px; + border: 1px solid #7e8993; +} + +input[type=search].select2-search__field { + line-height: 1; +} + +.e-form-submissions-search { + position: relative; +} +.e-form-submissions-search__spinner { + position: absolute; + inset-inline-end: 12px; + font-size: 11px; + height: 100%; + display: flex; + align-items: center; + color: var(--wp-admin-theme-color-darker-20, #005a87); +} +.e-form-submissions-search:focus-within .e-form-submissions-search__spinner, .e-form-submissions-search:hover .e-form-submissions-search__spinner { + inset-inline-end: 30px; +} + +.e-form-submissions-action-log--success .e-form-submissions-action-log__message { + background: #dff0d8; + border-color: #5cb85c; +} +.e-form-submissions-action-log--error .e-form-submissions-action-log__message { + background: #f2dede; + border-color: #d9534f; +} +.e-form-submissions-action-log:not(:last-child) { + border-block-end: 1px solid #D5D8DC; +} +.e-form-submissions-action-log__label { + display: inline-block; + padding-inline-end: 15px; +} +.e-form-submissions-action-log__icon { + display: inline-block; + padding-inline-end: 3px; +} +.e-form-submissions-action-log__date { + font-size: 12px; + color: #69727D; +} +.e-form-submissions-action-log__message { + padding: 10px; + font-size: 12px; + color: #1f2124; + background: #F1F2F3; + border-inline-start: 4px solid #69727D; +} + +.e-form-submissions-value-label:not(:last-child) { + display: block; + margin-block-end: 10px; +} + +span.font-variations-count { + display: inline-block; + vertical-align: top; + margin: 1px 0 0 5px; + padding: 0 5px; + min-width: 7px; + height: 17px; + border-radius: 11px; + background-color: #d4dffb; + color: #4278b2; + font-size: 9px; + line-height: 17px; + text-align: center; + z-index: 26; +} + +.post-type-elementor_font #elementor-font-custommetabox { + background: none; + border: 0; +} +.post-type-elementor_font #elementor-font-custommetabox button.handlediv { + display: none; +} +.post-type-elementor_font #elementor-font-custommetabox .inside { + margin-block-start: 15px; +} +.post-type-elementor_font #elementor-font-custommetabox h2.hndle { + padding-inline: 0; + font-size: 16px; +} +.post-type-elementor_font #elementor-font-custommetabox .handle-actions { + display: none; +} +.post-type-elementor_font #elementor-font-custommetabox .elementor-metabox-content:not(.has-font-variable):not(.has-font-static) { + display: flex; +} +.post-type-elementor_font #tagsdiv-elementor_font_type, +.post-type-elementor_font #minor-publishing-actions, +.post-type-elementor_font #misc-publishing-actions { + display: none; +} + +.elementor-metabox-content #add-variable-font { + margin-block-start: 18px; + margin-inline-start: 18px; +} +.elementor-metabox-content.has-font-variable .repeater-content-bottom { + display: flex; + flex-direction: column; +} +.elementor-metabox-content.has-font-variable .variable-width-wrap, +.elementor-metabox-content.has-font-variable .variable-weight-wrap { + display: flex; + gap: 20px; + margin-block: 10px; + min-height: 30px; + order: 1; +} +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_min, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_max, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_min, +.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_max, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_min, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_max, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_min, +.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_max { + display: none; +} +.elementor-metabox-content.has-font-variable #add-variable-font, +.elementor-metabox-content.has-font-variable .add-repeater-row, +.elementor-metabox-content.has-font-variable .font_weight, +.elementor-metabox-content.has-font-variable .font_style, +.elementor-metabox-content.has-font-variable .row-font-weight, +.elementor-metabox-content.has-font-variable .row-font-style, +.elementor-metabox-content.has-font-variable .repeater-block .elementor-field-file:not(.ttf) { + display: none; +} +.elementor-metabox-content.has-font-variable .elementor-field-input { + display: flex; + align-items: center; + min-width: 80px; +} +.elementor-metabox-content.has-font-variable .variable-description { + order: 1; + margin-block: 20px 10px; +} +.elementor-metabox-content.has-font-variable .variable_width .elementor-field-label, +.elementor-metabox-content.has-font-variable .variable_weight .elementor-field-label { + order: 1; +} +.elementor-metabox-content.has-font-variable .variable_width_min label, +.elementor-metabox-content.has-font-variable .variable_width_max label, +.elementor-metabox-content.has-font-variable .variable_weight_min label, +.elementor-metabox-content.has-font-variable .variable_weight_max label { + min-width: 80px; +} +.elementor-metabox-content.has-font-variable .variable_width_min input, +.elementor-metabox-content.has-font-variable .variable_width_max input, +.elementor-metabox-content.has-font-variable .variable_weight_min input, +.elementor-metabox-content.has-font-variable .variable_weight_max input { + max-width: 80px; +} +.elementor-metabox-content.has-font-static .variable-width-wrap, +.elementor-metabox-content.has-font-static .variable-weight-wrap, +.elementor-metabox-content.has-font-static .variable-description, +.elementor-metabox-content.has-font-static #add-variable-font { + display: none; +} +.elementor-metabox-content .repeater-block { + background: #fff; + color: #3f444b; + padding: 20px; + margin-block-end: 2px; +} +.elementor-metabox-content .repeater-block span.elementor-repeater-tool-btn.close-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block.block-visible { + padding-block-end: 0; + margin-block-end: 0; +} +.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.toggle-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.close-repeater-row { + display: inline-block; +} +.elementor-metabox-content .repeater-block:not(.block-visible) .close-repeater-row { + display: none; +} +.elementor-metabox-content .repeater-block .repeater-title { + cursor: pointer; +} +.elementor-metabox-content .repeater-block .elementor-field-file { + display: flex; + align-items: center; + background-color: #fff; + padding: 10px 20px; + margin-block-end: 10px; + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.05); +} +.elementor-metabox-content .repeater-block .elementor-field-file:last-child { + margin-block-end: 0; +} +.elementor-metabox-content .repeater-block .elementor-field-file p, +.elementor-metabox-content .repeater-block .elementor-field-file input { + box-sizing: border-box; + flex-grow: 1; + width: 100%; + margin: 0; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-label { + font-weight: 500; + max-width: 120px; + width: 100%; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input { + padding: 5px 8px; + margin: 0 15px; + border-radius: 3px; + font-size: 12px; + width: 100%; + background: none; + box-shadow: none; + color: #0C0D0E; + border: 1px solid; + outline: none; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:not(:focus) { + border-color: #D5D8DC; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:focus { + border-color: #9DA5AE; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-btn, +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn { + max-width: 100px; + font-size: 11px; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn { + transition: all 0.3s; +} +.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn:hover { + background-color: #DC2626; + border-color: #DC2626; + box-shadow: none; + color: white; +} +.elementor-metabox-content .row-font-label { + padding: 0; + margin: 0; + display: flex; + text-transform: capitalize; + justify-content: space-between; + align-items: center; +} +.elementor-metabox-content .row-font-label li { + box-sizing: border-box; + flex-grow: 1; + width: 100%; + margin: 0; +} +.elementor-metabox-content .row-font-label li span.label { + font-weight: 500; + padding-inline-end: 10px; +} +.elementor-metabox-content .row-font-label li.row-font-weight, .elementor-metabox-content .row-font-label li.row-font-style { + max-width: 180px; +} +.elementor-metabox-content .row-font-label li.row-font-actions { + max-width: 200px; + text-align: end; +} +.elementor-metabox-content .repeater-content { + margin: 0; +} +.elementor-metabox-content .repeater-content .repeater-content-top { + display: flex; + justify-content: space-between; + align-items: center; + margin-block-end: 20px; + line-height: 28px; +} +.elementor-metabox-content .repeater-content .repeater-content-top > div { + box-sizing: border-box; + flex-grow: 1; +} +.elementor-metabox-content .repeater-content .repeater-content-top p { + margin: 0; + display: inline-block; +} +.elementor-metabox-content .repeater-content .repeater-content-top p label { + font-weight: 500; + padding-inline-end: 10px; +} +.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-select { + max-width: 180px; +} +.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-toolbar { + max-width: 200px; + text-align: end; +} +.elementor-metabox-content .repeater-content .repeater-content-bottom { + background-color: #F9FAFA; + padding: 20px 40px; + margin: 0 -20px; +} +.elementor-metabox-content input.button.add-repeater-row { + margin-block-start: 18px; +} +.elementor-metabox-content .elementor-repeater-tool-btn { + cursor: pointer; + padding: 0 20px; + font-size: 12px; + transition: all 0.3s; +} +.elementor-metabox-content .elementor-repeater-tool-btn i { + padding-inline-end: 5px; +} +.elementor-metabox-content .elementor-repeater-tool-btn:hover { + color: #3f444b; +} +.elementor-metabox-content .elementor-repeater-tool-btn.remove-repeater-row:hover { + color: #DC2626; +} + +.row-font-preview, +.inline-preview, +.widefat td.column-font_preview { + font-size: 30px; + text-transform: capitalize; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 600px; + line-height: 1.5; +} + +.post-type-elementor_icons .elementor-metabox-content .elementor-button:not([disabled]) { + margin-block-start: 10px; +} +.post-type-elementor_icons div#postbox-container-1 { + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox { + display: none; + border: 1px solid #F1F2F3; + border-radius: 1px; + background-color: #fff; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .inside { + margin-block: 10px 20px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-metabox-content { + background-color: #fff; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox { + padding-block: 4px 10px; + padding-inline: 10px; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox { + padding: 0; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox h4 { + color: #1f2124; + font-size: 22px; + font-weight: 500; + letter-spacing: 0.7px; + line-height: 28px; + margin: 0 0 4px 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox h5 { + color: #9DA5AE; + font-size: 16px; + font-weight: 500; + letter-spacing: 0.5px; + line-height: 21px; + margin: 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor--dropzone--upload__icon i { + font-size: 64px; + color: #0A875A; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__uploading, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__success, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__error, +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__file { + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .is-dragover { + background-color: grey; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .box__input { + padding: 180px 0; + display: flex; + flex-direction: column; + align-items: center; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-field-dropzone { + outline: 2px dashed #D5D8DC; + outline-offset: -3px; + background-color: #fff; + display: none; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons { + background-color: #F9FAFA; + border: 1px solid #F1F2F3; + border-radius: 1px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content { + background-color: #F9FAFA; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content .elementor-custom-icons-metabox { + padding-block: 4px 0; + padding-inline: 10px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header { + height: 50px; + color: #3f444b; + background-color: #fff; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.06); + padding: 0 35px; + display: flex; + align-items: center; + justify-content: flex-start; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header { + padding: 0 6px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div { + padding-inline: 10px; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div { + line-height: 1; + } + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div.remove { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div:nth-of-type(2) { + border: 1px solid #9DA5AE; + border-block-start: 0; + border-block-end: 0; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta { + color: #1f2124; + font-size: 14px; + line-height: 1; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value { + font-weight: bold; +} +@media (max-width: 1025px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value { + font-size: 10px; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove { + margin-inline-start: auto; + color: #1f2124; + opacity: 0.6; + cursor: pointer; + transition: all 0.3s; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove i { + color: #3f444b; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove:hover { + opacity: 1; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-footer { + color: #BABFC5; + font-family: Roboto, Arial, Helvetica, sans-serif; + border-block-start: 1px solid #F1F2F3; + font-size: 11px; + font-weight: 500; + line-height: 1; + text-align: end; + padding-block: 10px; + padding-inline-end: 35px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(105px, 1fr)); + grid-gap: 20px; + padding-block: 15px 0; + padding-inline: 35px; + overflow-y: auto; + max-height: 575px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li { + position: relative; + height: 0; + padding-block-end: 100%; + background-color: #fff; + box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05); + border-radius: 3px; + overflow: hidden; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 1px; +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name { + color: #BABFC5; + font-size: 11px; + padding: 18px 20px 0; + white-space: nowrap; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; +} +@media (max-width: 479px) { + .post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name { + display: none; + } +} +.post-type-elementor_icons div#elementor-custom-icons-metabox ul li i { + font-size: 32px; +} +.post-type-elementor_icons #tagsdiv-elementor_icon_type, +.post-type-elementor_icons #minor-publishing-actions, +.post-type-elementor_icons #misc-publishing-actions { + display: none; +} + +.column-icons_prefix { + width: 65%; +} + +:root { + --color-box-shadow-color: rgba(0, 0, 0, 0.05); +} + +.eps-theme-dark { + --color-box-shadow-color: rgba(0, 0, 0, 0.1); +} + +.eps-grid-container { + display: flex; + flex-wrap: wrap; + width: 100%; +} +.eps-grid-container--no-wrap { + flex-wrap: nowrap; +} +.eps-grid-container--wrap-reverse { + flex-wrap: wrap-reverse; +} +.eps-grid-container--spacing { + --grid-row-gutter: calc(-1 * calc(var(--grid-spacing-gutter) * 0.625rem / 10)); + width: var(--grid-spacing-width); + margin: var(--grid-row-gutter); +} +.eps-grid-container--spacing > .eps-grid-item { + padding: var(--grid-spacing-gutter); +} +.eps-grid--direction-row { + flex-direction: row; +} +.eps-grid--direction-row-reverse { + flex-direction: row-reverse; +} +.eps-grid--direction-column { + flex-direction: column; +} +.eps-grid--direction-column-reverse { + flex-direction: column-reverse; +} +.eps-grid--justify-stretch { + justify-content: stretch; +} +.eps-grid--justify-start { + justify-content: flex-start; +} +.eps-grid--justify-center { + justify-content: center; +} +.eps-grid--justify-end { + justify-content: flex-end; +} +.eps-grid--justify-space-between { + justify-content: space-between; +} +.eps-grid--justify-space-around { + justify-content: space-around; +} +.eps-grid--justify-space-evenly { + justify-content: space-evenly; +} +.eps-grid--align-content-stretch { + align-content: stretch; +} +.eps-grid--align-content-start { + align-content: flex-start; +} +.eps-grid--align-content-center { + align-content: center; +} +.eps-grid--align-content-end { + align-content: flex-end; +} +.eps-grid--align-content-space-between { + align-content: space-between; +} +.eps-grid--align-items-start { + align-items: flex-start; +} +.eps-grid--align-items-center { + align-items: center; +} +.eps-grid--align-items-end { + align-items: flex-end; +} +.eps-grid--align-items-baseline { + align-items: baseline; +} +.eps-grid--align-items-stretch { + align-items: stretch; +} + +.eps-grid-item--zero-min-width { + min-width: 0; +} + +@media screen and (min-width: 480px) { + .eps-grid-item-sm { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } +} +@media screen and (min-width: 768px) { + .eps-grid-item-md { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } +} +@media screen and (min-width: 1025px) { + .eps-grid-item-lg { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } +} +@media screen and (min-width: 1440px) { + .eps-grid-item-xl { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } +} +@media screen and (min-width: 1600px) { + .eps-grid-item-xxl { + flex-grow: 1; + max-width: 100%; + flex-basis: 0; + } +} +.eps-grid-item-xs-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); +} + +.eps-grid-item-xs-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); +} + +.eps-grid-item-xs-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); +} + +.eps-grid-item-xs-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); +} + +.eps-grid-item-xs-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); +} + +.eps-grid-item-xs-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); +} + +.eps-grid-item-xs-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); +} + +.eps-grid-item-xs-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); +} + +.eps-grid-item-xs-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); +} + +.eps-grid-item-xs-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); +} + +.eps-grid-item-xs-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); +} + +.eps-grid-item-xs-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); +} + +@media screen and (min-width: 480px) { + .eps-grid-item-sm-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); + } + .eps-grid-item-sm-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); + } + .eps-grid-item-sm-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); + } + .eps-grid-item-sm-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); + } + .eps-grid-item-sm-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); + } + .eps-grid-item-sm-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); + } + .eps-grid-item-sm-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); + } + .eps-grid-item-sm-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); + } + .eps-grid-item-sm-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); + } + .eps-grid-item-sm-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); + } + .eps-grid-item-sm-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); + } + .eps-grid-item-sm-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); + } +} +@media screen and (min-width: 768px) { + .eps-grid-item-md-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); + } + .eps-grid-item-md-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); + } + .eps-grid-item-md-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); + } + .eps-grid-item-md-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); + } + .eps-grid-item-md-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); + } + .eps-grid-item-md-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); + } + .eps-grid-item-md-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); + } + .eps-grid-item-md-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); + } + .eps-grid-item-md-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); + } + .eps-grid-item-md-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); + } + .eps-grid-item-md-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); + } + .eps-grid-item-md-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); + } +} +@media screen and (min-width: 1025px) { + .eps-grid-item-lg-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); + } + .eps-grid-item-lg-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); + } + .eps-grid-item-lg-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); + } + .eps-grid-item-lg-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); + } + .eps-grid-item-lg-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); + } + .eps-grid-item-lg-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); + } + .eps-grid-item-lg-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); + } + .eps-grid-item-lg-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); + } + .eps-grid-item-lg-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); + } + .eps-grid-item-lg-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); + } + .eps-grid-item-lg-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); + } + .eps-grid-item-lg-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); + } +} +@media screen and (min-width: 1440px) { + .eps-grid-item-xl-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); + } + .eps-grid-item-xl-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); + } + .eps-grid-item-xl-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); + } + .eps-grid-item-xl-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); + } + .eps-grid-item-xl-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); + } + .eps-grid-item-xl-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); + } + .eps-grid-item-xl-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); + } + .eps-grid-item-xl-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); + } + .eps-grid-item-xl-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); + } + .eps-grid-item-xl-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); + } + .eps-grid-item-xl-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); + } + .eps-grid-item-xl-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); + } +} +@media screen and (min-width: 1600px) { + .eps-grid-item-xxl-1 { + flex-grow: 0; + max-width: calc(1 / 12 * 100%); + flex-basis: calc(1 / 12 * 100%); + } + .eps-grid-item-xxl-2 { + flex-grow: 0; + max-width: calc(2 / 12 * 100%); + flex-basis: calc(2 / 12 * 100%); + } + .eps-grid-item-xxl-3 { + flex-grow: 0; + max-width: calc(3 / 12 * 100%); + flex-basis: calc(3 / 12 * 100%); + } + .eps-grid-item-xxl-4 { + flex-grow: 0; + max-width: calc(4 / 12 * 100%); + flex-basis: calc(4 / 12 * 100%); + } + .eps-grid-item-xxl-5 { + flex-grow: 0; + max-width: calc(5 / 12 * 100%); + flex-basis: calc(5 / 12 * 100%); + } + .eps-grid-item-xxl-6 { + flex-grow: 0; + max-width: calc(6 / 12 * 100%); + flex-basis: calc(6 / 12 * 100%); + } + .eps-grid-item-xxl-7 { + flex-grow: 0; + max-width: calc(7 / 12 * 100%); + flex-basis: calc(7 / 12 * 100%); + } + .eps-grid-item-xxl-8 { + flex-grow: 0; + max-width: calc(8 / 12 * 100%); + flex-basis: calc(8 / 12 * 100%); + } + .eps-grid-item-xxl-9 { + flex-grow: 0; + max-width: calc(9 / 12 * 100%); + flex-basis: calc(9 / 12 * 100%); + } + .eps-grid-item-xxl-10 { + flex-grow: 0; + max-width: calc(10 / 12 * 100%); + flex-basis: calc(10 / 12 * 100%); + } + .eps-grid-item-xxl-11 { + flex-grow: 0; + max-width: calc(11 / 12 * 100%); + flex-basis: calc(11 / 12 * 100%); + } + .eps-grid-item-xxl-12 { + flex-grow: 0; + max-width: calc(12 / 12 * 100%); + flex-basis: calc(12 / 12 * 100%); + } +} +:root { + --eps-modal-background-color: #ffffff; + --eps-modal-header-background-color: #2563EB; + --eps-tip-background-color: #F0F7FF; +} + +.eps-theme-dark { + --eps-modal-background-color: #0C0D0E; + --eps-modal-header-background-color: #0077CC; + --eps-tip-background-color: #0A1A3D; +} + +/** ---------------------------------------------------------------- + EPS Modal +---------------------------------------------------------------- */ +.eps-modal { + max-width: 43.75rem; + background: var(--eps-modal-background-color); + border-radius: 0.1875rem; + animation: fade-in 0.4s ease-in both; +} +.eps-modal__overlay { + background: rgba(0, 0, 0, 0.5); + position: fixed; + display: flex; + inset: 0; + align-items: center; + justify-content: center; + z-index: 1030; +} +.eps-modal__header { + font-size: 0.875rem; + background: var(--eps-modal-header-background-color); + height: 2.75rem; + padding: 0.625rem 1rem; + border-radius: 0.1875rem; +} +.eps-modal__header, .eps-modal__header .title { + color: #ffffff; +} +.eps-modal__icon { + margin-inline-end: 0.625rem; +} +.eps-modal__body { + padding: 1.875rem; +} +.eps-modal__tip, .eps-modal .eps-tip { + padding: 0.5rem; + padding-inline-start: 0.75rem; + border-inline-start: 3px solid #2563EB; + background-color: var(--eps-tip-background-color); +} +.eps-modal__tip:not(:last-child), .eps-modal .eps-tip:not(:last-child) { + margin-block-end: 1.875rem; +} +.eps-modal__tip:not(:first-child), .eps-modal .eps-tip:not(:first-child) { + margin-block-start: 1.875rem; +} +.eps-modal__section:not(:first-child) { + margin-block-start: 1.875rem; +} +.eps-modal__close-wrapper { + padding-inline-start: 1rem; + border-inline-start: solid 1px #ffffff; +} + +.eps-button { + display: inline-flex; + --button-line-height: 16px; + --button-padding-y: 0.5em; + --button-padding-x: 1.5em; + --button-primary-background-color: #F3BAFD; + --button-primary-hover-background-color: #F5D0FE; + --button-primary-active-background-color: #F3BAFD; + --button-primary-color: #0C0D0E; + --button-secondary-background-color: #69727D; + --button-secondary-hover-background-color: rgb(81.7173913043, 88.7217391304, 97.2826086957); + --button-secondary-active-background-color: rgb(58.4347826087, 63.4434782609, 69.5652173913); + --button-secondary-color: #ffffff; + --button-danger-background-color: #DC2626; + --button-danger-hover-background-color: rgb(178.25, 28.75, 28.75); + --button-danger-active-background-color: rgb(134.3333333333, 21.6666666667, 21.6666666667); + --button-danger-color: #ffffff; + --button-cta-background-color: #93003f; + --button-cta-hover-background-color: rgb(96, 0, 41.1428571429); + --button-cta-active-background-color: rgb(45, 0, 19.2857142857); + --button-cta-color: #ffffff; + --button-brand-background-color: #93003f; + --button-brand-hover-background-color: rgb(96, 0, 41.1428571429); + --button-brand-active-background-color: rgb(45, 0, 19.2857142857); + --button-brand-color: #ffffff; + --button-link-background-color: #515962; + --button-link-hover-background-color: rgb(57.9217877095, 63.6424581006, 70.0782122905); + --button-link-active-background-color: rgb(34.843575419, 38.2849162011, 42.156424581); + --button-link-color: #ffffff; + --button-disabled-background-color: #D5D8DC; + --button-disabled-hover-background-color: rgb(185.1818181818, 190.1688311688, 196.8181818182); + --button-disabled-active-background-color: rgb(157.3636363636, 164.3376623377, 173.6363636364); + --button-disabled-color: #ffffff; + color: var(--button-background-color, currentColor); + font-size: var(--button-font-size, inherit); + font-weight: 500; + line-height: var(--button-line-height); + transition: var(--e-a-transition-hover); + cursor: pointer; +} +.eps-button:active { + --button-background-color: var(--button-active-background-color, transparent); +} +.eps-button:hover { + --button-background-color: var(--button-hover-background-color); +} +.eps-theme-dark .eps-button { + --button-primary-background-color: #F3BAFD; + --button-primary-color: #0C0D0E; + --button-primary-hover-background-color: #EB8EFB; + --button-primary-active-background-color: #F3BAFD; + --button-secondary-background-color: #BABFC5; + --button-secondary-color: #fff; + --button-secondary-hover-background-color: rgb(158.2913385827, 165.2992125984, 173.7086614173); + --button-secondary-active-background-color: rgb(130.5826771654, 139.5984251969, 150.4173228346); + --button-cta-background-color: #93003f; + --button-cta-hover-background-color: rgb(96, 0, 41.1428571429); + --button-cta-active-background-color: rgb(45, 0, 19.2857142857); + --button-cta-color: #fff; + --button-brand-hover-background-color: rgb(96, 0, 41.1428571429); + --button-brand-active-background-color: rgb(45, 0, 19.2857142857); + --button-brand-color: #fff; + --button-brand-background-color: #93003f; + --button-link-background-color: #515962; + --button-link-hover-background-color: rgb(57.9217877095, 63.6424581006, 70.0782122905); + --button-link-active-background-color: rgb(34.843575419, 38.2849162011, 42.156424581); + --button-link-color: #ffffff; + --button-disabled-background-color: #69727D; + --button-disabled-hover-background-color: rgb(81.7173913043, 88.7217391304, 97.2826086957); + --button-disabled-active-background-color: rgb(58.4347826087, 63.4434782609, 69.5652173913); + --button-disabled-color: #fff; +} +.eps-button--contained { + color: var(--button-color); + padding: var(--button-padding-y) var(--button-padding-x); + background-color: var(--button-background-color, transparent); + border: 1px solid var(--button-background-color); +} +.eps-button--contained:hover { + color: var(--button-color); +} +.eps-button--outlined { + display: block; + padding: var(--button-padding-y) var(--button-padding-x); + border: 1px solid var(--button-background-color); +} +.eps-button--contained, .eps-button--outlined { + border-radius: 0.1875rem; +} +.eps-button--underlined { + text-decoration: underline; +} +.eps-button--sm { + --button-font-size: 0.75rem; + --button-line-height: 14px; +} +.eps-button--lg { + --button-font-size: 0.9375rem; + --button-line-height: 18px; +} +.eps-button--primary { + --button-color: var(--button-primary-color); + --button-background-color: var(--button-primary-background-color); + --button-hover-background-color: var(--button-primary-hover-background-color); + --button-active-background-color: var(--button-primary-active-background-color); +} +.eps-button--secondary { + --button-color: var(--button-secondary-color); + --button-background-color: var(--button-secondary-background-color); + --button-hover-background-color: var(--button-secondary-hover-background-color); + --button-active-background-color: var(--button-secondary-active-background-color); +} +.eps-button--danger { + --button-color: var(--button-danger-color); + --button-background-color: var(--button-danger-background-color); + --button-hover-background-color: var(--button-danger-hover-background-color); + --button-active-background-color: var(--button-danger-active-background-color); +} +.eps-button--cta { + --button-color: var(--button-brand-color); + --button-background-color: var(--button-cta-background-color); + --button-hover-background-color: var(--button-cta-hover-background-color); + --button-active-background-color: var(--button-cta-active-background-color); +} +.eps-button--brand { + --button-color: var(--button-cta-color); + --button-background-color: var(--button-cta-background-color); + --button-hover-background-color: var(--button-cta-hover-background-color); + --button-active-background-color: var(--button-cta-active-background-color); +} +.eps-button--link { + --button-color: var(--button-link-color); + --button-background-color: var(--button-link-background-color); + --button-hover-background-color: var(--button-link-hover-background-color); + --button-active-background-color: var(--button-link-active-background-color); +} +.eps-button--disabled, .eps-button[disabled] { + --button-color: var(--button-disabled-color); + --button-background-color: var(--button-disabled-background-color); + --button-hover-background-color: var(--button-disabled-hover-background-color); + --button-active-background-color: var(--button-disabled-active-background-color); + cursor: default; +} + +:root { + --e-site-editor-conditions-row-controls-background: #ffffff; + --e-site-editor-input-wrapper-border-color: #D5D8DC; + --e-site-editor-input-wrapper-select-color: #3f444b; + --e-site-editor-conditions-row-controls-border: 1px solid #D5D8DC; + --e-site-editor-add-button-background-color: #69727D; + --e-site-editor-add-button-color-hover-background-color: #515962; + --e-site-editor-input-wrapper-condition-include-background-color: + #69727D; + --e-site-editor-input-wrapper-condition-exclude-background-color: + #818A96; + --e-site-editor-input-select2-search-field-color: #515962 ; +} + +.eps-theme-dark { + --select2-selection-background-color: tints(600); + --e-site-editor-conditions-row-controls-background: #515962; + --e-site-editor-input-wrapper-border-color: #3f444b; + --e-site-editor-input-wrapper-select-color: #BABFC5; + --e-site-editor-conditions-row-controls-border: 1px solid #3f444b; + --e-site-editor-add-button-background-color: #69727D; + --e-site-editor-add-button-color-hover-background-color: #515962; + --e-site-editor-input-wrapper-condition-include-background-color: + #515962; + --e-site-editor-input-wrapper-condition-exclude-background-color: + #515962; + --e-site-editor-input-select2-search-field-color: #ffffff ; +} + +.e-site-editor-conditions__header { + text-align: center; +} +.e-site-editor-conditions__header-image { + display: block; + margin: 0 auto 2.75rem; + width: 4.375rem; +} +.e-site-editor-conditions__rows { + margin: 2.75rem auto; + max-width: 43.75rem; +} +.e-site-editor-conditions__row { + display: flex; + flex-grow: 1; + margin-block-start: 0.75rem; +} +.e-site-editor-conditions__remove-condition { + color: #818A96; + font-size: 1.125rem; + display: flex; + align-items: center; + justify-content: center; +} +.e-site-editor-conditions__row-controls { + overflow: hidden; + margin-inline-end: 0.625rem; + background-color: var(--e-site-editor-conditions-row-controls-background); + display: flex; + width: 100%; + border: var(--e-site-editor-conditions-row-controls-border); + border-radius: 0.1875rem; +} +.e-site-editor-conditions__row-controls--error { + border: 1px solid #DC2626; +} +.e-site-editor-conditions__conflict { + text-align: center; + margin-block-start: 0.3125rem; + color: #DC2626; +} +.e-site-editor-conditions__row-controls-inner { + width: 100%; + display: flex; +} +.e-site-editor-conditions__row-controls-inner div { + flex: 1; +} +.e-site-editor-conditions__add-button-container { + text-align: center; +} +.e-site-editor-conditions__add-button { + margin-block-start: 2.75rem; + background-color: var(--e-site-editor-add-button-background-color); + color: #ffffff; + text-transform: uppercase; +} +.e-site-editor-conditions__add-button:hover { + background-color: var(--e-site-editor-add-button-color-hover-background-color); + color: #ffffff; +} +.e-site-editor-conditions__footer { + display: flex; + justify-content: flex-end; + padding: 0.5rem; + margin-top: 1rem; +} +.e-site-editor-conditions__input-wrapper { + position: relative; + padding-inline-start: 1px solid; + border-color: var(--e-site-editor-input-wrapper-border-color); +} +.e-site-editor-conditions__input-wrapper:first-child { + border: none; +} +.e-site-editor-conditions__input-wrapper select { + appearance: none; + -webkit-appearance: none; + font-size: 0.75rem; + height: 2.5rem; + border-width: 0; + padding: 0 0.625rem; + width: 100%; + position: relative; + color: var(--e-site-editor-input-wrapper-select-color); + outline: none; + background: transparent; +} +.e-site-editor-conditions__input-wrapper::after { + font-family: eicons; + content: "\e8ad"; + font-size: 0.75rem; + pointer-events: none; + position: absolute; + inset-block-start: 50%; + inset-inline-end: 0.625rem; + transform: translateY(-50%); +} +.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single { + border: none; + line-height: 2.5rem; +} +.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered { + line-height: 2.5rem; + font-size: 0.75rem; +} +.e-site-editor-conditions__input-wrapper .select2-selection { + outline: none; + background: transparent; + height: 2.5rem; +} +.e-site-editor-conditions__input-wrapper .select2-selection__arrow { + display: none; +} +.e-site-editor-conditions__input-wrapper--condition-type { + position: relative; +} +.e-site-editor-conditions__input-wrapper--condition-type::before { + font-family: eicons; + position: absolute; + transform: translateY(-50%); + inset-block-start: 50%; + inset-inline-start: 0.75rem; + font-size: 0.9375rem; + pointer-events: none; + z-index: 1000; +} +.e-site-editor-conditions__input-wrapper--condition-type select { + text-transform: uppercase; + padding-inline-start: 2.125rem; + width: 7.5rem; + font-size: 0.75rem; + border-inline-end: 1px solid; + border-color: var(--e-site-editor-input-wrapper-border-color); +} +.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=include]::before { + content: "\e8cc"; +} +.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=exclude]::before { + content: "\e8cd"; +} + +.select2-search__field { + background-color: transparent; + color: var(--e-site-editor-input-select2-search-field-color); +} + +.misc-pub-visibility { + display: none; +} + +.eps-modal__overlay { + background: rgba(0, 0, 0, 0.8); + z-index: 9999; /* After '#adminmenuwrap' */ +} + +.select2-container { + z-index: 9999; /* After 'eps-modal__overlay'. */ +} + +.post-conditions .spinner { + margin: 0 10px; + float: none; + visibility: visible; +} +.post-conditions .eps-button--underlined { + /* No variable was used since this color comes from wordpress */ + color: #0073aa; +} +.post-conditions .eps-modal { + position: relative; + background: #f1f3f5; + max-width: 1200px; + max-height: 800px; + width: 90vw; + height: 90vh; + margin: auto; +} +.post-conditions .eps-modal .eps-modal__body { + display: flex; + flex-direction: column; + flex-grow: 1; +} +.post-conditions .eps-modal .eps-h1 { + font-size: 30px; + font-weight: 300; +} +.post-conditions .eps-modal .eps-text { + font-size: 18px; + line-height: 150%; + margin: 1em 0; + color: #9DA5AE; +} +.post-conditions .eps-modal .eps-grid-container { + width: auto; +} +.post-conditions .eps-modal__header { + background: #ffffff; + color: #1f2124; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); + padding: 2px 15px; +} +.post-conditions .eps-modal__header .eps-app__logo { + width: 1.75rem; + height: 1.75rem; + line-height: 1.75rem; + text-align: center; + font-size: 0.7rem; + border-radius: 50%; + color: #ffffff; + background-color: #93003F; +} +.post-conditions .eps-modal__header .eps-text { + /* Didn't find better solution */ + position: relative; + top: 2px; + font-size: 0.9375rem; + font-weight: 700; + text-transform: uppercase; + color: #6d7882; +} +.post-conditions .eps-modal__header .eps-button { + font-size: 18px; +} +.post-conditions .eps-modal .e-site-editor-conditions__header { + padding-block-start: 5vh; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows { + overflow-y: auto; + max-height: 30vh; + margin: 0 auto; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows:empty { + margin-block-end: 30px; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows:not(:empty) { + margin-block-end: 20px; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row { + margin-block-start: 15px; + padding: 0 14px; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls { + border-radius: 0; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select { + text-transform: none; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select:focus { + box-shadow: none; + border: none; + color: inherit; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select:hover { + color: inherit; +} +.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls .e-site-editor-conditions__input-wrapper--condition-type select:hover, .post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls .e-site-editor-conditions__input-wrapper--condition-type select:focus { + color: #ffffff; +} +.post-conditions .eps-modal .e-site-editor-conditions__add-button { + margin-block-start: 0; +} +.post-conditions .eps-modal .e-site-editor-conditions__footer { + display: flex; + justify-content: flex-end; + position: absolute; + bottom: 0; + right: 0; + left: 0; + z-index: 1000; + border-block-start: 1px solid #d5dadf; +} + +#elementor-custom-code.postbox { + border: 0; +} +#elementor-custom-code .postbox-header { + display: none; +} +#elementor-custom-code .inside { + padding: 0; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box { + margin: 0; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel { + border: 1px solid #F1F2F3; + border-block-end: 1px solid #ccd0d4; + background: #ffffff; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-panel-placement { + padding: 5px 40px; + margin: 10px 0; + flex-wrap: wrap; + gap: 10px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-options-placement { + display: none; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-options-placement.show { + display: flex; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel div { + display: flex; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field i { + color: #BABFC5; + font-size: 15px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field select { + height: 20px; + margin-block-start: 7px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field select#location { + direction: ltr; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field.priority { + margin-inline-start: auto; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field.location { + margin-inline-end: 10px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label { + font-weight: 500; + font-size: 14px; + line-height: 16px; + color: #3f444b; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label:nth-child(even) { + margin-inline-end: 20px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label:nth-child(odd) { + margin-inline-end: 5px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-checkboxes { + padding-block-start: 18px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-checkboxes .label { + position: relative; + top: -5px; +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .e-ai-button { + all: unset; + color: #D004D4; + cursor: pointer; + transition: var(--e-a-transition-hover); +} +#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .e-ai-button:hover { + color: #E73CF6; +} +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder { + border: 1px solid #F1F2F3; + background: #F9FAFA; + padding: 40px; +} +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-field-label { + margin: 0; +} +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror { + border: 1px solid #ccd0d4; + resize: vertical; + overflow: auto; + max-width: 100%; +} +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .elementor-field-textarea, +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror.CodeMirror-wrap, +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror-scroll { + height: 100%; +} +#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror-sizer { + min-height: 300px !important; + border-right: 0; +} + +.post-type-elementor_snippet #minor-publishing-actions, +.post-type-elementor_snippet #save-action { + display: none; +} + +.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror { + background-color: var(--e-a-bg-default); + display: flex; +} +.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror .elementor-field-textarea { + width: calc(100% - 8px); +} +.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror .CodeMirror-sizer { + box-sizing: border-box; +} + +@media (max-width: 850px), (max-height: 825px) { + .post-conditions .eps-modal { + width: 100vw; + height: 90vh; + } + .post-conditions .eps-modal .e-site-editor-conditions__header { + padding-block-start: 0; + } + .post-conditions .eps-modal .e-site-editor-conditions__rows { + max-height: 30vh; + } + .post-conditions .eps-modal .e-site-editor-conditions__header-image { + margin: 0 auto; + } +} +@media (max-width: 590px), (max-height: 666px) { + .post-conditions .eps-modal .eps-modal__body { + overflow: auto; + height: calc(100vh - 200px); + } + .post-conditions .eps-modal .eps-modal__body .e-site-editor-conditions__footer { + background: #f1f3f5; + } +} + +/*# sourceMappingURL=custom-code.css.map */ \ No newline at end of file diff --git a/assets/css/modules/custom-code.min.css b/assets/css/modules/custom-code.min.css new file mode 100644 index 00000000..6eeba4d5 --- /dev/null +++ b/assets/css/modules/custom-code.min.css @@ -0,0 +1 @@ +@keyframes fade-in{0%{opacity:0}to{opacity:1}}.wrap.elementor-admin-page-license .elementor-license-box{background:#fff;margin:20px 0;max-width:600px;padding:20px}.wrap.elementor-admin-page-license .elementor-license-box h3{align-items:center;border-block-end:1px solid #eee;display:flex;justify-content:space-between;margin:0;padding:0;padding-block-end:20px}.wrap.elementor-admin-page-license .elementor-license-box h3 span{flex-grow:1;padding-inline-start:5px}.wrap.elementor-admin-page-license .elementor-license-box h3 small{font-size:13px;font-weight:400}.wrap.elementor-admin-page-license .elementor-license-box label{display:block;font-size:1.3em;font-weight:600;margin:1em 0}.wrap.elementor-admin-page-license .elementor-license-box .button{height:30px;margin-block-end:0;margin-inline-start:15px}.wrap.elementor-admin-page-license .elementor-license-box p.description{margin:10px 0}.wrap.elementor-admin-page-license .elementor-license-box .e-row-stretch,.wrap.elementor-admin-page-license .elementor-license-box.e-row-stretch{align-items:center;display:flex;justify-content:space-between}.wrap.elementor-admin-page-license .elementor-license-box .e-row-divider-bottom{border-block-end:1px solid #eee;padding-block-end:15px}.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link{border-color:#93003f;color:#93003f}.wrap.elementor-admin-page-license .elementor-license-box .elementor-upgrade-link:hover{background-color:#93003f;color:#fff}.wrap.elementor-admin-page-license .elementor-box-action{align-items:flex-end;display:flex;justify-content:flex-end;margin-block-start:30px}.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link{color:#72777c;margin-inline-end:15px}.wrap.elementor-admin-page-license .elementor-box-action .elementor-manually-link:hover{color:inherit}#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]{background-color:#93003f;border-radius:3px;color:#fff;display:block;font-size:12px;font-weight:600;line-height:1.5;margin:3px 10px 0;padding:5px 0;text-align:center;transition:all .3s}#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:focus,#adminmenu #toplevel_page_elementor a[href*=elementor_pro_upgrade_license_menu_link]:hover{background-color:#c60055;box-shadow:none}.fixed .column-elementor_library_type,.fixed .column-instances{width:10%}.fixed .elementor-shortcode-input{min-width:235px}@media (min-width:768px) and (max-width:1440px){.fixed .column-shortcode{width:25%}.fixed .elementor-shortcode-input{min-width:100%}}#available-widgets [class*=elementor-template] .widget-title:before{content:"\e801";font-family:eicon;font-size:17px}#elementor-widget-template-empty-templates{margin-block-start:15px;text-align:center}.elementor-widget-template-empty-templates-title{padding:25px 0 30px}.elementor-widget-template-empty-templates-icon{font-size:96px}.elementor-widget-template-empty-templates-footer{color:var(--e-a-color-txt-muted);font-size:13px;font-style:italic;margin-block-end:15px}.elementor-button-spinner.error:before{color:red;content:"\f335"}@media screen and (max-width:782px){.e-form-submissions-list-table.wp-list-table tr:not(.inline-edit-row):not(.no-items)>td.bulk-checkbox-column:not(.check-column){width:2.2em!important}}.e-form-submissions-list-table .bulk-checkbox-column{padding:9px 0 0 3px;width:2.2em}.e-form-submissions-list-table .column-actions{width:11%}.e-form-submissions-list-table .column-actions i{font-size:15px}.e-form-submissions-list-table .column-id{width:7%}.e-form-submissions-list-table .column-page{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:17%}.e-form-submissions-list-table .column-date{width:17%}.e-form-submissions-list-table .column-form{width:20%}.e-form-submissions-referer-icon{font-size:18px}.e-form-submissions-main .postbox{border:none}.e-form-submissions-main .postbox-header{border:1px solid #d5d8dc;border-block-end:none;padding:8px}.e-form-submissions-main__header{align-items:center;display:flex;justify-content:space-between;width:100%}#e-form-submissions .eicon-success{color:#5cb85c}#e-form-submissions .eicon-error{color:#d9534f}#e-form-submissions .misc-pub-section{line-height:1.3rem}#e-form-submissions .e-form-submissions-item-table{border:none;border-collapse:collapse}#e-form-submissions .e-form-submissions-item-table td:first-child{background:#f9fafa;font-weight:700;width:150px}@media screen and (max-width:782px){#e-form-submissions .e-form-submissions-item-table td:first-child{width:90px!important}}#e-form-submissions .e-form-submissions-item-table td{border:1px solid #d5d8dc;padding:15px}#e-form-submissions .e-form-submissions-item-table input:not([type=checkbox]):not([type=radio]),#e-form-submissions .e-form-submissions-item-table select,#e-form-submissions .e-form-submissions-item-table textarea{max-width:400px;width:100%}#e-form-submissions .e-export-button{margin-inline-start:15px}@media screen and (max-width:782px){#e-form-submissions .e-export-button{display:none}}#e-form-submissions .tablenav .actions select{width:10rem}#e-form-submissions .tablenav .actions .select2-container{float:left;margin-right:6px}#e-form-submissions .tablenav .actions .select2-container .select2-selection__arrow{height:30px}#e-form-submissions .tablenav .actions .select2-container .select2-selection--single{border:1px solid #7e8993;height:30px}input[type=search].select2-search__field{line-height:1}.e-form-submissions-search{position:relative}.e-form-submissions-search__spinner{align-items:center;color:var(--wp-admin-theme-color-darker-20,#005a87);display:flex;font-size:11px;height:100%;inset-inline-end:12px;position:absolute}.e-form-submissions-search:focus-within .e-form-submissions-search__spinner,.e-form-submissions-search:hover .e-form-submissions-search__spinner{inset-inline-end:30px}.e-form-submissions-action-log--success .e-form-submissions-action-log__message{background:#dff0d8;border-color:#5cb85c}.e-form-submissions-action-log--error .e-form-submissions-action-log__message{background:#f2dede;border-color:#d9534f}.e-form-submissions-action-log:not(:last-child){border-block-end:1px solid #d5d8dc}.e-form-submissions-action-log__label{display:inline-block;padding-inline-end:15px}.e-form-submissions-action-log__icon{display:inline-block;padding-inline-end:3px}.e-form-submissions-action-log__date{color:#69727d;font-size:12px}.e-form-submissions-action-log__message{background:#f1f2f3;border-inline-start:4px solid #69727d;color:#1f2124;font-size:12px;padding:10px}.e-form-submissions-value-label:not(:last-child){display:block;margin-block-end:10px}span.font-variations-count{background-color:#d4dffb;border-radius:11px;color:#4278b2;display:inline-block;font-size:9px;height:17px;line-height:17px;margin:1px 0 0 5px;min-width:7px;padding:0 5px;text-align:center;vertical-align:top;z-index:26}.post-type-elementor_font #elementor-font-custommetabox{background:none;border:0}.post-type-elementor_font #elementor-font-custommetabox button.handlediv{display:none}.post-type-elementor_font #elementor-font-custommetabox .inside{margin-block-start:15px}.post-type-elementor_font #elementor-font-custommetabox h2.hndle{font-size:16px;padding-inline:0}.post-type-elementor_font #elementor-font-custommetabox .handle-actions{display:none}.post-type-elementor_font #elementor-font-custommetabox .elementor-metabox-content:not(.has-font-variable):not(.has-font-static){display:flex}.post-type-elementor_font #minor-publishing-actions,.post-type-elementor_font #misc-publishing-actions,.post-type-elementor_font #tagsdiv-elementor_font_type{display:none}.elementor-metabox-content #add-variable-font{margin-block-start:18px;margin-inline-start:18px}.elementor-metabox-content.has-font-variable .repeater-content-bottom{display:flex;flex-direction:column}.elementor-metabox-content.has-font-variable .variable-weight-wrap,.elementor-metabox-content.has-font-variable .variable-width-wrap{display:flex;gap:20px;margin-block:10px;min-height:30px;order:1}.elementor-metabox-content.has-font-variable #add-variable-font,.elementor-metabox-content.has-font-variable .add-repeater-row,.elementor-metabox-content.has-font-variable .font_style,.elementor-metabox-content.has-font-variable .font_weight,.elementor-metabox-content.has-font-variable .repeater-block .elementor-field-file:not(.ttf),.elementor-metabox-content.has-font-variable .row-font-style,.elementor-metabox-content.has-font-variable .row-font-weight,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_max,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_weight_min,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_max,.elementor-metabox-content.has-font-variable .variable-weight-wrap.e-font-variable-hidden .variable_width_min,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_max,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_weight_min,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_max,.elementor-metabox-content.has-font-variable .variable-width-wrap.e-font-variable-hidden .variable_width_min{display:none}.elementor-metabox-content.has-font-variable .elementor-field-input{align-items:center;display:flex;min-width:80px}.elementor-metabox-content.has-font-variable .variable-description{margin-block:20px 10px;order:1}.elementor-metabox-content.has-font-variable .variable_weight .elementor-field-label,.elementor-metabox-content.has-font-variable .variable_width .elementor-field-label{order:1}.elementor-metabox-content.has-font-variable .variable_weight_max label,.elementor-metabox-content.has-font-variable .variable_weight_min label,.elementor-metabox-content.has-font-variable .variable_width_max label,.elementor-metabox-content.has-font-variable .variable_width_min label{min-width:80px}.elementor-metabox-content.has-font-variable .variable_weight_max input,.elementor-metabox-content.has-font-variable .variable_weight_min input,.elementor-metabox-content.has-font-variable .variable_width_max input,.elementor-metabox-content.has-font-variable .variable_width_min input{max-width:80px}.elementor-metabox-content.has-font-static #add-variable-font,.elementor-metabox-content.has-font-static .variable-description,.elementor-metabox-content.has-font-static .variable-weight-wrap,.elementor-metabox-content.has-font-static .variable-width-wrap{display:none}.elementor-metabox-content .repeater-block{background:#fff;color:#3f444b;margin-block-end:2px;padding:20px}.elementor-metabox-content .repeater-block span.elementor-repeater-tool-btn.close-repeater-row{display:none}.elementor-metabox-content .repeater-block.block-visible{margin-block-end:0;padding-block-end:0}.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.toggle-repeater-row{display:none}.elementor-metabox-content .repeater-block.block-visible span.elementor-repeater-tool-btn.close-repeater-row{display:inline-block}.elementor-metabox-content .repeater-block:not(.block-visible) .close-repeater-row{display:none}.elementor-metabox-content .repeater-block .repeater-title{cursor:pointer}.elementor-metabox-content .repeater-block .elementor-field-file{align-items:center;background-color:#fff;box-shadow:0 3px 5px rgba(0,0,0,.05);display:flex;margin-block-end:10px;padding:10px 20px}.elementor-metabox-content .repeater-block .elementor-field-file:last-child{margin-block-end:0}.elementor-metabox-content .repeater-block .elementor-field-file input,.elementor-metabox-content .repeater-block .elementor-field-file p{box-sizing:border-box;flex-grow:1;margin:0;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-label{font-weight:500;max-width:120px;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input{background:none;border:1px solid;border-radius:3px;box-shadow:none;color:#0c0d0e;font-size:12px;margin:0 15px;outline:none;padding:5px 8px;width:100%}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:not(:focus){border-color:#d5d8dc}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-field-input:focus{border-color:#9da5ae}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-btn,.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn{font-size:11px;max-width:100px}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn{transition:all .3s}.elementor-metabox-content .repeater-block .elementor-field-file .elementor-upload-clear-btn:hover{background-color:#dc2626;border-color:#dc2626;box-shadow:none;color:#fff}.elementor-metabox-content .row-font-label{align-items:center;display:flex;justify-content:space-between;margin:0;padding:0;text-transform:capitalize}.elementor-metabox-content .row-font-label li{box-sizing:border-box;flex-grow:1;margin:0;width:100%}.elementor-metabox-content .row-font-label li span.label{font-weight:500;padding-inline-end:10px}.elementor-metabox-content .row-font-label li.row-font-style,.elementor-metabox-content .row-font-label li.row-font-weight{max-width:180px}.elementor-metabox-content .row-font-label li.row-font-actions{max-width:200px;text-align:end}.elementor-metabox-content .repeater-content{margin:0}.elementor-metabox-content .repeater-content .repeater-content-top{align-items:center;display:flex;justify-content:space-between;line-height:28px;margin-block-end:20px}.elementor-metabox-content .repeater-content .repeater-content-top>div{box-sizing:border-box;flex-grow:1}.elementor-metabox-content .repeater-content .repeater-content-top p{display:inline-block;margin:0}.elementor-metabox-content .repeater-content .repeater-content-top p label{font-weight:500;padding-inline-end:10px}.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-select{max-width:180px}.elementor-metabox-content .repeater-content .repeater-content-top .elementor-field-toolbar{max-width:200px;text-align:end}.elementor-metabox-content .repeater-content .repeater-content-bottom{background-color:#f9fafa;margin:0 -20px;padding:20px 40px}.elementor-metabox-content input.button.add-repeater-row{margin-block-start:18px}.elementor-metabox-content .elementor-repeater-tool-btn{cursor:pointer;font-size:12px;padding:0 20px;transition:all .3s}.elementor-metabox-content .elementor-repeater-tool-btn i{padding-inline-end:5px}.elementor-metabox-content .elementor-repeater-tool-btn:hover{color:#3f444b}.elementor-metabox-content .elementor-repeater-tool-btn.remove-repeater-row:hover{color:#dc2626}.inline-preview,.row-font-preview,.widefat td.column-font_preview{font-size:30px;line-height:1.5;max-width:600px;overflow:hidden;text-overflow:ellipsis;text-transform:capitalize;white-space:nowrap}.post-type-elementor_icons .elementor-metabox-content .elementor-button:not([disabled]){margin-block-start:10px}.post-type-elementor_icons div#postbox-container-1{display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox{background-color:#fff;border:1px solid #f1f2f3;border-radius:1px;display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox .inside{margin-block:10px 20px}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-metabox-content{background-color:#fff}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox{padding-block:4px 10px;padding-inline:10px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-custom-icons-metabox{padding:0}}.post-type-elementor_icons div#elementor-custom-icons-metabox h4{color:#1f2124;font-size:22px;font-weight:500;letter-spacing:.7px;line-height:28px;margin:0 0 4px}.post-type-elementor_icons div#elementor-custom-icons-metabox h5{color:#9da5ae;font-size:16px;font-weight:500;letter-spacing:.5px;line-height:21px;margin:0}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor--dropzone--upload__icon i{color:#0a875a;font-size:64px}.post-type-elementor_icons div#elementor-custom-icons-metabox .box__error,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__file,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__success,.post-type-elementor_icons div#elementor-custom-icons-metabox .box__uploading{display:none}.post-type-elementor_icons div#elementor-custom-icons-metabox .is-dragover{background-color:grey}.post-type-elementor_icons div#elementor-custom-icons-metabox .box__input{align-items:center;display:flex;flex-direction:column;padding:180px 0}.post-type-elementor_icons div#elementor-custom-icons-metabox .elementor-field-dropzone{background-color:#fff;display:none;outline:2px dashed #d5d8dc;outline-offset:-3px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons{background-color:#f9fafa;border:1px solid #f1f2f3;border-radius:1px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content{background-color:#f9fafa}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-metabox-content .elementor-custom-icons-metabox{padding-block:4px 0;padding-inline:10px}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header{align-items:center;background-color:#fff;box-shadow:0 2px 6px 0 rgba(0,0,0,.06);color:#3f444b;display:flex;height:50px;justify-content:flex-start;padding:0 35px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header{padding:0 6px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div{padding-inline:10px}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div{line-height:1}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div.remove{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header div:nth-of-type(2){border:1px solid #9da5ae;border-block-end:0;border-block-start:0}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta{color:#1f2124;font-size:14px;line-height:1}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value{font-weight:700}@media (max-width:1025px){.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-value{font-size:10px}}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove{color:#1f2124;cursor:pointer;margin-inline-start:auto;opacity:.6;transition:all .3s}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove i{color:#3f444b}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-header-meta-remove:hover{opacity:1}.post-type-elementor_icons div#elementor-custom-icons-metabox.elementor--has-icons .elementor-icon-set-footer{border-block-start:1px solid #f1f2f3;color:#babfc5;font-family:Roboto,Arial,Helvetica,sans-serif;font-size:11px;font-weight:500;line-height:1;padding-block:10px;padding-inline-end:35px;text-align:end}.post-type-elementor_icons div#elementor-custom-icons-metabox ul{display:grid;grid-template-columns:repeat(auto-fill,minmax(105px,1fr));grid-gap:20px;max-height:575px;overflow-y:auto;padding-block:15px 0;padding-inline:35px}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li{background-color:#fff;border-radius:3px;box-shadow:0 1px 12px rgba(0,0,0,.05);height:0;overflow:hidden;padding-block-end:100%;position:relative}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon{align-items:center;display:flex;flex-direction:column;left:50%;padding:1px;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name{color:#babfc5;font-size:11px;max-width:100%;overflow:hidden;padding:18px 20px 0;text-overflow:ellipsis;white-space:nowrap}@media (max-width:479px){.post-type-elementor_icons div#elementor-custom-icons-metabox ul li div.icon-name{display:none}}.post-type-elementor_icons div#elementor-custom-icons-metabox ul li i{font-size:32px}.post-type-elementor_icons #minor-publishing-actions,.post-type-elementor_icons #misc-publishing-actions,.post-type-elementor_icons #tagsdiv-elementor_icon_type{display:none}.column-icons_prefix{width:65%}:root{--color-box-shadow-color:rgba(0,0,0,.05)}.eps-theme-dark{--color-box-shadow-color:rgba(0,0,0,.1)}.eps-grid-container{display:flex;flex-wrap:wrap;width:100%}.eps-grid-container--no-wrap{flex-wrap:nowrap}.eps-grid-container--wrap-reverse{flex-wrap:wrap-reverse}.eps-grid-container--spacing{--grid-row-gutter:calc(-1 * calc(var(--grid-spacing-gutter) * 0.625rem / 10));margin:var(--grid-row-gutter);width:var(--grid-spacing-width)}.eps-grid-container--spacing>.eps-grid-item{padding:var(--grid-spacing-gutter)}.eps-grid--direction-row{flex-direction:row}.eps-grid--direction-row-reverse{flex-direction:row-reverse}.eps-grid--direction-column{flex-direction:column}.eps-grid--direction-column-reverse{flex-direction:column-reverse}.eps-grid--justify-stretch{justify-content:stretch}.eps-grid--justify-start{justify-content:flex-start}.eps-grid--justify-center{justify-content:center}.eps-grid--justify-end{justify-content:flex-end}.eps-grid--justify-space-between{justify-content:space-between}.eps-grid--justify-space-around{justify-content:space-around}.eps-grid--justify-space-evenly{justify-content:space-evenly}.eps-grid--align-content-stretch{align-content:stretch}.eps-grid--align-content-start{align-content:flex-start}.eps-grid--align-content-center{align-content:center}.eps-grid--align-content-end{align-content:flex-end}.eps-grid--align-content-space-between{align-content:space-between}.eps-grid--align-items-start{align-items:flex-start}.eps-grid--align-items-center{align-items:center}.eps-grid--align-items-end{align-items:flex-end}.eps-grid--align-items-baseline{align-items:baseline}.eps-grid--align-items-stretch{align-items:stretch}.eps-grid-item--zero-min-width{min-width:0}@media screen and (min-width:480px){.eps-grid-item-sm{flex-basis:0;flex-grow:1;max-width:100%}}@media screen and (min-width:768px){.eps-grid-item-md{flex-basis:0;flex-grow:1;max-width:100%}}@media screen and (min-width:1025px){.eps-grid-item-lg{flex-basis:0;flex-grow:1;max-width:100%}}@media screen and (min-width:1440px){.eps-grid-item-xl{flex-basis:0;flex-grow:1;max-width:100%}}@media screen and (min-width:1600px){.eps-grid-item-xxl{flex-basis:0;flex-grow:1;max-width:100%}}.eps-grid-item-xs-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-xs-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-xs-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-xs-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-xs-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-xs-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-xs-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-xs-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-xs-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-xs-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-xs-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-xs-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}@media screen and (min-width:480px){.eps-grid-item-sm-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-sm-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-sm-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-sm-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-sm-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-sm-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-sm-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-sm-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-sm-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-sm-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-sm-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-sm-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}}@media screen and (min-width:768px){.eps-grid-item-md-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-md-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-md-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-md-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-md-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-md-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-md-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-md-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-md-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-md-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-md-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-md-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}}@media screen and (min-width:1025px){.eps-grid-item-lg-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-lg-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-lg-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-lg-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-lg-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-lg-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-lg-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-lg-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-lg-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-lg-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-lg-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-lg-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}}@media screen and (min-width:1440px){.eps-grid-item-xl-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-xl-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-xl-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-xl-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-xl-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-xl-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-xl-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-xl-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-xl-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-xl-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-xl-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-xl-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}}@media screen and (min-width:1600px){.eps-grid-item-xxl-1{flex-basis:calc(1 / 12 * 100%);flex-grow:0;max-width:calc(1 / 12 * 100%)}.eps-grid-item-xxl-2{flex-basis:calc(2 / 12 * 100%);flex-grow:0;max-width:calc(2 / 12 * 100%)}.eps-grid-item-xxl-3{flex-basis:calc(3 / 12 * 100%);flex-grow:0;max-width:calc(3 / 12 * 100%)}.eps-grid-item-xxl-4{flex-basis:calc(4 / 12 * 100%);flex-grow:0;max-width:calc(4 / 12 * 100%)}.eps-grid-item-xxl-5{flex-basis:calc(5 / 12 * 100%);flex-grow:0;max-width:calc(5 / 12 * 100%)}.eps-grid-item-xxl-6{flex-basis:calc(6 / 12 * 100%);flex-grow:0;max-width:calc(6 / 12 * 100%)}.eps-grid-item-xxl-7{flex-basis:calc(7 / 12 * 100%);flex-grow:0;max-width:calc(7 / 12 * 100%)}.eps-grid-item-xxl-8{flex-basis:calc(8 / 12 * 100%);flex-grow:0;max-width:calc(8 / 12 * 100%)}.eps-grid-item-xxl-9{flex-basis:calc(9 / 12 * 100%);flex-grow:0;max-width:calc(9 / 12 * 100%)}.eps-grid-item-xxl-10{flex-basis:calc(10 / 12 * 100%);flex-grow:0;max-width:calc(10 / 12 * 100%)}.eps-grid-item-xxl-11{flex-basis:calc(11 / 12 * 100%);flex-grow:0;max-width:calc(11 / 12 * 100%)}.eps-grid-item-xxl-12{flex-basis:calc(12 / 12 * 100%);flex-grow:0;max-width:calc(12 / 12 * 100%)}}:root{--eps-modal-background-color:#fff;--eps-modal-header-background-color:#2563eb;--eps-tip-background-color:#f0f7ff}.eps-theme-dark{--eps-modal-background-color:#0c0d0e;--eps-modal-header-background-color:#07c;--eps-tip-background-color:#0a1a3d}.eps-modal{animation:fade-in .4s ease-in both;background:var(--eps-modal-background-color);border-radius:.1875rem;max-width:43.75rem}.eps-modal__overlay{align-items:center;background:rgba(0,0,0,.5);display:flex;inset:0;justify-content:center;position:fixed;z-index:1030}.eps-modal__header{background:var(--eps-modal-header-background-color);border-radius:.1875rem;font-size:.875rem;height:2.75rem;padding:.625rem 1rem}.eps-modal__header,.eps-modal__header .title{color:#fff}.eps-modal__icon{margin-inline-end:.625rem}.eps-modal__body{padding:1.875rem}.eps-modal .eps-tip,.eps-modal__tip{background-color:var(--eps-tip-background-color);border-inline-start:3px solid #2563eb;padding:.5rem;padding-inline-start:.75rem}.eps-modal .eps-tip:not(:last-child),.eps-modal__tip:not(:last-child){margin-block-end:1.875rem}.eps-modal .eps-tip:not(:first-child),.eps-modal__section:not(:first-child),.eps-modal__tip:not(:first-child){margin-block-start:1.875rem}.eps-modal__close-wrapper{border-inline-start:1px solid #fff;padding-inline-start:1rem}.eps-button{display:inline-flex;--button-line-height:16px;--button-padding-y:0.5em;--button-padding-x:1.5em;--button-primary-background-color:#f3bafd;--button-primary-hover-background-color:#f5d0fe;--button-primary-active-background-color:#f3bafd;--button-primary-color:#0c0d0e;--button-secondary-background-color:#69727d;--button-secondary-hover-background-color:#525961;--button-secondary-active-background-color:#3a3f46;--button-secondary-color:#fff;--button-danger-background-color:#dc2626;--button-danger-hover-background-color:#b21d1d;--button-danger-active-background-color:#861616;--button-danger-color:#fff;--button-cta-background-color:#93003f;--button-cta-hover-background-color:#600029;--button-cta-active-background-color:#2d0013;--button-cta-color:#fff;--button-brand-background-color:#93003f;--button-brand-hover-background-color:#600029;--button-brand-active-background-color:#2d0013;--button-brand-color:#fff;--button-link-background-color:#515962;--button-link-hover-background-color:#3a4046;--button-link-active-background-color:#23262a;--button-link-color:#fff;--button-disabled-background-color:#d5d8dc;--button-disabled-hover-background-color:#b9bec5;--button-disabled-active-background-color:#9da4ae;--button-disabled-color:#fff;color:var(--button-background-color,currentColor);cursor:pointer;font-size:var(--button-font-size,inherit);font-weight:500;line-height:var(--button-line-height);transition:var(--e-a-transition-hover)}.eps-button:active{--button-background-color:var(--button-active-background-color,transparent)}.eps-button:hover{--button-background-color:var(--button-hover-background-color)}.eps-theme-dark .eps-button{--button-primary-background-color:#f3bafd;--button-primary-color:#0c0d0e;--button-primary-hover-background-color:#eb8efb;--button-primary-active-background-color:#f3bafd;--button-secondary-background-color:#babfc5;--button-secondary-color:#fff;--button-secondary-hover-background-color:#9ea5ae;--button-secondary-active-background-color:#838c96;--button-cta-background-color:#93003f;--button-cta-hover-background-color:#600029;--button-cta-active-background-color:#2d0013;--button-cta-color:#fff;--button-brand-hover-background-color:#600029;--button-brand-active-background-color:#2d0013;--button-brand-color:#fff;--button-brand-background-color:#93003f;--button-link-background-color:#515962;--button-link-hover-background-color:#3a4046;--button-link-active-background-color:#23262a;--button-link-color:#fff;--button-disabled-background-color:#69727d;--button-disabled-hover-background-color:#525961;--button-disabled-active-background-color:#3a3f46;--button-disabled-color:#fff}.eps-button--contained{background-color:var(--button-background-color,transparent);border:1px solid var(--button-background-color);padding:var(--button-padding-y) var(--button-padding-x)}.eps-button--contained,.eps-button--contained:hover{color:var(--button-color)}.eps-button--outlined{border:1px solid var(--button-background-color);display:block;padding:var(--button-padding-y) var(--button-padding-x)}.eps-button--contained,.eps-button--outlined{border-radius:.1875rem}.eps-button--underlined{text-decoration:underline}.eps-button--sm{--button-font-size:0.75rem;--button-line-height:14px}.eps-button--lg{--button-font-size:0.9375rem;--button-line-height:18px}.eps-button--primary{--button-color:var(--button-primary-color);--button-background-color:var(--button-primary-background-color);--button-hover-background-color:var(--button-primary-hover-background-color);--button-active-background-color:var(--button-primary-active-background-color)}.eps-button--secondary{--button-color:var(--button-secondary-color);--button-background-color:var(--button-secondary-background-color);--button-hover-background-color:var(--button-secondary-hover-background-color);--button-active-background-color:var(--button-secondary-active-background-color)}.eps-button--danger{--button-color:var(--button-danger-color);--button-background-color:var(--button-danger-background-color);--button-hover-background-color:var(--button-danger-hover-background-color);--button-active-background-color:var(--button-danger-active-background-color)}.eps-button--cta{--button-color:var(--button-brand-color);--button-background-color:var(--button-cta-background-color);--button-hover-background-color:var(--button-cta-hover-background-color);--button-active-background-color:var(--button-cta-active-background-color)}.eps-button--brand{--button-color:var(--button-cta-color);--button-background-color:var(--button-cta-background-color);--button-hover-background-color:var(--button-cta-hover-background-color);--button-active-background-color:var(--button-cta-active-background-color)}.eps-button--link{--button-color:var(--button-link-color);--button-background-color:var(--button-link-background-color);--button-hover-background-color:var(--button-link-hover-background-color);--button-active-background-color:var(--button-link-active-background-color)}.eps-button--disabled,.eps-button[disabled]{--button-color:var(--button-disabled-color);--button-background-color:var(--button-disabled-background-color);--button-hover-background-color:var(--button-disabled-hover-background-color);--button-active-background-color:var(--button-disabled-active-background-color);cursor:default}:root{--e-site-editor-conditions-row-controls-background:#fff;--e-site-editor-input-wrapper-border-color:#d5d8dc;--e-site-editor-input-wrapper-select-color:#3f444b;--e-site-editor-conditions-row-controls-border:1px solid #d5d8dc;--e-site-editor-add-button-background-color:#69727d;--e-site-editor-add-button-color-hover-background-color:#515962;--e-site-editor-input-wrapper-condition-include-background-color:#69727d;--e-site-editor-input-wrapper-condition-exclude-background-color:#818a96;--e-site-editor-input-select2-search-field-color:#515962}.eps-theme-dark{--select2-selection-background-color:tints(600);--e-site-editor-conditions-row-controls-background:#515962;--e-site-editor-input-wrapper-border-color:#3f444b;--e-site-editor-input-wrapper-select-color:#babfc5;--e-site-editor-conditions-row-controls-border:1px solid #3f444b;--e-site-editor-add-button-background-color:#69727d;--e-site-editor-add-button-color-hover-background-color:#515962;--e-site-editor-input-wrapper-condition-include-background-color:#515962;--e-site-editor-input-wrapper-condition-exclude-background-color:#515962;--e-site-editor-input-select2-search-field-color:#fff}.e-site-editor-conditions__header{text-align:center}.e-site-editor-conditions__header-image{display:block;margin:0 auto 2.75rem;width:4.375rem}.e-site-editor-conditions__rows{margin:2.75rem auto;max-width:43.75rem}.e-site-editor-conditions__row{display:flex;flex-grow:1;margin-block-start:.75rem}.e-site-editor-conditions__remove-condition{align-items:center;color:#818a96;display:flex;font-size:1.125rem;justify-content:center}.e-site-editor-conditions__row-controls{background-color:var(--e-site-editor-conditions-row-controls-background);border:var(--e-site-editor-conditions-row-controls-border);border-radius:.1875rem;display:flex;margin-inline-end:.625rem;overflow:hidden;width:100%}.e-site-editor-conditions__row-controls--error{border:1px solid #dc2626}.e-site-editor-conditions__conflict{color:#dc2626;margin-block-start:.3125rem;text-align:center}.e-site-editor-conditions__row-controls-inner{display:flex;width:100%}.e-site-editor-conditions__row-controls-inner div{flex:1}.e-site-editor-conditions__add-button-container{text-align:center}.e-site-editor-conditions__add-button{background-color:var(--e-site-editor-add-button-background-color);color:#fff;margin-block-start:2.75rem;text-transform:uppercase}.e-site-editor-conditions__add-button:hover{background-color:var(--e-site-editor-add-button-color-hover-background-color);color:#fff}.e-site-editor-conditions__footer{display:flex;justify-content:flex-end;margin-top:1rem;padding:.5rem}.e-site-editor-conditions__input-wrapper{border-color:var(--e-site-editor-input-wrapper-border-color);padding-inline-start:1px solid;position:relative}.e-site-editor-conditions__input-wrapper:first-child{border:none}.e-site-editor-conditions__input-wrapper select{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:transparent;border-width:0;color:var(--e-site-editor-input-wrapper-select-color);font-size:.75rem;height:2.5rem;outline:none;padding:0 .625rem;position:relative;width:100%}.e-site-editor-conditions__input-wrapper:after{content:"\e8ad";font-family:eicons;font-size:.75rem;inset-block-start:50%;inset-inline-end:.625rem;pointer-events:none;position:absolute;transform:translateY(-50%)}.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single{border:none;line-height:2.5rem}.e-site-editor-conditions__input-wrapper .select2-container--default .select2-selection--single .select2-selection__rendered{font-size:.75rem;line-height:2.5rem}.e-site-editor-conditions__input-wrapper .select2-selection{background:transparent;height:2.5rem;outline:none}.e-site-editor-conditions__input-wrapper .select2-selection__arrow{display:none}.e-site-editor-conditions__input-wrapper--condition-type{position:relative}.e-site-editor-conditions__input-wrapper--condition-type:before{font-family:eicons;font-size:.9375rem;inset-block-start:50%;inset-inline-start:.75rem;pointer-events:none;position:absolute;transform:translateY(-50%);z-index:1000}.e-site-editor-conditions__input-wrapper--condition-type select{border-inline-end:1px solid;border-color:var(--e-site-editor-input-wrapper-border-color);font-size:.75rem;padding-inline-start:2.125rem;text-transform:uppercase;width:7.5rem}.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=include]:before{content:"\e8cc"}.e-site-editor-conditions__input-wrapper--condition-type[data-elementor-condition-type=exclude]:before{content:"\e8cd"}.select2-search__field{background-color:transparent;color:var(--e-site-editor-input-select2-search-field-color)}.misc-pub-visibility{display:none}.eps-modal__overlay{background:rgba(0,0,0,.8);z-index:9999}.select2-container{z-index:9999}.post-conditions .spinner{float:none;margin:0 10px;visibility:visible}.post-conditions .eps-button--underlined{color:#0073aa}.post-conditions .eps-modal{background:#f1f3f5;height:90vh;margin:auto;max-height:800px;max-width:1200px;position:relative;width:90vw}.post-conditions .eps-modal .eps-modal__body{display:flex;flex-direction:column;flex-grow:1}.post-conditions .eps-modal .eps-h1{font-size:30px;font-weight:300}.post-conditions .eps-modal .eps-text{color:#9da5ae;font-size:18px;line-height:150%;margin:1em 0}.post-conditions .eps-modal .eps-grid-container{width:auto}.post-conditions .eps-modal__header{background:#fff;box-shadow:0 0 8px rgba(0,0,0,.1);color:#1f2124;padding:2px 15px}.post-conditions .eps-modal__header .eps-app__logo{background-color:#93003f;border-radius:50%;color:#fff;font-size:.7rem;height:1.75rem;line-height:1.75rem;text-align:center;width:1.75rem}.post-conditions .eps-modal__header .eps-text{color:#6d7882;font-size:.9375rem;font-weight:700;position:relative;text-transform:uppercase;top:2px}.post-conditions .eps-modal__header .eps-button{font-size:18px}.post-conditions .eps-modal .e-site-editor-conditions__header{padding-block-start:5vh}.post-conditions .eps-modal .e-site-editor-conditions__rows{margin:0 auto;max-height:30vh;overflow-y:auto}.post-conditions .eps-modal .e-site-editor-conditions__rows:empty{margin-block-end:30px}.post-conditions .eps-modal .e-site-editor-conditions__rows:not(:empty){margin-block-end:20px}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row{margin-block-start:15px;padding:0 14px}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls{border-radius:0}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select{text-transform:none}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select:focus{border:none;box-shadow:none;color:inherit}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls select:hover{color:inherit}.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls .e-site-editor-conditions__input-wrapper--condition-type select:focus,.post-conditions .eps-modal .e-site-editor-conditions__rows .e-site-editor-conditions__row-controls .e-site-editor-conditions__input-wrapper--condition-type select:hover{color:#fff}.post-conditions .eps-modal .e-site-editor-conditions__add-button{margin-block-start:0}.post-conditions .eps-modal .e-site-editor-conditions__footer{border-block-start:1px solid #d5dadf;bottom:0;display:flex;justify-content:flex-end;left:0;position:absolute;right:0;z-index:1000}#elementor-custom-code.postbox{border:0}#elementor-custom-code .postbox-header{display:none}#elementor-custom-code .inside{padding:0}#elementor-custom-code .inside .elementor-custom-code-meta-box{margin:0}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel{background:#fff;border:1px solid #f1f2f3;border-block-end:1px solid #ccd0d4}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-panel-placement{flex-wrap:wrap;gap:10px;margin:10px 0;padding:5px 40px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-options-placement{display:none}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-custom-code-options-placement.show,#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel div{display:flex}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field i{color:#babfc5;font-size:15px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field select{height:20px;margin-block-start:7px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field select#location{direction:ltr}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field.priority{margin-inline-start:auto}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field.location{margin-inline-end:10px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label{color:#3f444b;font-size:14px;font-weight:500;line-height:16px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label:nth-child(2n){margin-inline-end:20px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-label:nth-child(odd){margin-inline-end:5px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-checkboxes{padding-block-start:18px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .elementor-field-checkboxes .label{position:relative;top:-5px}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .e-ai-button{all:unset;color:#d004d4;cursor:pointer;transition:var(--e-a-transition-hover)}#elementor-custom-code .inside .elementor-custom-code-meta-box .elementor-custom-code-panel .e-ai-button:hover{color:#e73cf6}#elementor-custom-code .inside .elementor-custom-code-codemirror-holder{background:#f9fafa;border:1px solid #f1f2f3;padding:40px}#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-field-label{margin:0}#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror{border:1px solid #ccd0d4;max-width:100%;overflow:auto;resize:vertical}#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror-scroll,#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror.CodeMirror-wrap,#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .elementor-field-textarea{height:100%}#elementor-custom-code .inside .elementor-custom-code-codemirror-holder .elementor-custom-code-codemirror .CodeMirror-sizer{border-right:0;min-height:300px!important}.post-type-elementor_snippet #minor-publishing-actions,.post-type-elementor_snippet #save-action{display:none}.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror{background-color:var(--e-a-bg-default);display:flex}.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror .elementor-field-textarea{width:calc(100% - 8px)}.e--ua-safari #elementor-custom-code .elementor-custom-code-codemirror .CodeMirror-sizer{box-sizing:border-box}@media (max-height:825px),(max-width:850px){.post-conditions .eps-modal{height:90vh;width:100vw}.post-conditions .eps-modal .e-site-editor-conditions__header{padding-block-start:0}.post-conditions .eps-modal .e-site-editor-conditions__rows{max-height:30vh}.post-conditions .eps-modal .e-site-editor-conditions__header-image{margin:0 auto}}@media (max-height:666px),(max-width:590px){.post-conditions .eps-modal .eps-modal__body{height:calc(100vh - 200px);overflow:auto}.post-conditions .eps-modal .eps-modal__body .e-site-editor-conditions__footer{background:#f1f3f5}} \ No newline at end of file diff --git a/assets/css/modules/loop-grid-cta.css b/assets/css/modules/loop-grid-cta.css new file mode 100644 index 00000000..216d3bca --- /dev/null +++ b/assets/css/modules/loop-grid-cta.css @@ -0,0 +1,164 @@ +.e-loop-empty-view__container { + display: flex; + flex-direction: row; + justify-content: space-between; + width: 100%; +} +.e-loop-empty-view__box { + min-height: 413px; + width: 100%; + display: flex; +} +.e-loop-empty-view__box-inner { + border: 1px dashed #D5D8DC; + margin: 10px; + width: 100%; + padding: 10px; + font-size: 12px; + color: #9DA5AE; + display: flex; + flex-direction: column; + text-align: center; + align-items: center; + justify-content: center; + font-family: Roboto, sans-serif; +} +.e-loop-empty-view__box-inner img { + max-height: 99px; + margin-bottom: 28px; +} +.e-loop-empty-view__box-title { + font-size: 20px; + font-weight: 700; + margin-bottom: 12px; +} +.e-loop-empty-view__box-description { + margin-bottom: 12px; +} +.e-loop-empty-view__box-cta { + color: #ffffff; + background-color: #9DA5AE; + padding: 6px 8px; + border-radius: 3px; + text-decoration: none; + transition-property: background, color, box-shadow, opacity; + transition-duration: 0.3s; +} +.e-loop-empty-view__box-cta:hover { + background-color: #3f444b; + color: #ffffff; +} +.e-loop-empty-view__box--active { + border: 2px solid #5EEAD4; +} + +.elementor-widget-loop-grid .elementor-grid.e-loop-empty-view__container { + grid-column-gap: calc(var(--grid-column-gap) - 20px); +} + +.e-loop-empty-view__container.loop-carousel { + width: 95%; + margin: 0 auto; + padding: 30px 0; +} +.e-loop-empty-view__container .e-loop-empty-view__box, +.e-loop-empty-view__container .elementor-swiper-button, +.e-loop-empty-view__container .swiper-pagination { + opacity: 1; +} + +.elementor-swiper-button { + position: absolute; + display: inline-flex; + z-index: 1; + cursor: default; + font-size: 25px; + color: rgba(224, 219, 219, 0.9); + top: 50%; + transform: translateY(-50%); +} +.elementor-swiper-button-prev { + left: 0; +} +.elementor-swiper-button-next { + right: 0; +} +.elementor-swiper-button svg { + fill: rgba(224, 219, 219, 0.9); + height: 1em; + width: 1em; +} + +.elementor-pagination-position-outside .elementor-swiper-button { + top: calc(50% - 15px); +} + +.screen-reader-text, .screen-reader-text span, .ui-helper-hidden-accessible, .elementor-screen-only { + position: absolute; + top: -10000em; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} + +.swiper-container-horizontal > .swiper-pagination-bullets, +.swiper-horizontal > .swiper-pagination-bullets { + bottom: 5px; + left: 0; + width: 100%; +} +.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet, +.swiper-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 0 6px; +} + +.swiper-container-horizontal > .swiper-pagination-bullets { + bottom: 5px; + left: 0; + width: 100%; +} +.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 0 6px; +} +.swiper-pagination { + position: absolute; + text-align: center; + transition: 300ms; + transform: translate3d(0, 0, 0); + z-index: 10; +} +.swiper-pagination-bullet { + width: 6px; + height: 6px; + display: inline-block; + border-radius: 50%; + background: #000; + opacity: 0.2; + pointer-events: none; +} +.swiper-pagination-fraction { + bottom: 5px; + left: 0; + width: 100%; +} +.swiper-pagination-custom { + bottom: 5px; + left: 0; + width: 100%; +} +.swiper-pagination-bullets { + color: #fff; + cursor: default; + bottom: 0; + left: 0; + width: 100%; +} +.swiper-pagination-bullet-active { + opacity: 0.8; +} + +/*# sourceMappingURL=loop-grid-cta.css.map */ \ No newline at end of file diff --git a/assets/css/modules/loop-grid-cta.min.css b/assets/css/modules/loop-grid-cta.min.css new file mode 100644 index 00000000..74572ecc --- /dev/null +++ b/assets/css/modules/loop-grid-cta.min.css @@ -0,0 +1 @@ +.e-loop-empty-view__container{display:flex;flex-direction:row;justify-content:space-between;width:100%}.e-loop-empty-view__box{display:flex;min-height:413px;width:100%}.e-loop-empty-view__box-inner{align-items:center;border:1px dashed #d5d8dc;color:#9da5ae;display:flex;flex-direction:column;font-family:Roboto,sans-serif;font-size:12px;justify-content:center;margin:10px;padding:10px;text-align:center;width:100%}.e-loop-empty-view__box-inner img{margin-bottom:28px;max-height:99px}.e-loop-empty-view__box-title{font-size:20px;font-weight:700;margin-bottom:12px}.e-loop-empty-view__box-description{margin-bottom:12px}.e-loop-empty-view__box-cta{background-color:#9da5ae;border-radius:3px;color:#fff;padding:6px 8px;text-decoration:none;transition-duration:.3s;transition-property:background,color,box-shadow,opacity}.e-loop-empty-view__box-cta:hover{background-color:#3f444b;color:#fff}.e-loop-empty-view__box--active{border:2px solid #5eead4}.elementor-widget-loop-grid .elementor-grid.e-loop-empty-view__container{grid-column-gap:calc(var(--grid-column-gap) - 20px)}.e-loop-empty-view__container.loop-carousel{margin:0 auto;padding:30px 0;width:95%}.e-loop-empty-view__container .e-loop-empty-view__box,.e-loop-empty-view__container .elementor-swiper-button,.e-loop-empty-view__container .swiper-pagination{opacity:1}.elementor-swiper-button{color:hsla(0,7%,87%,.9);cursor:default;display:inline-flex;font-size:25px;position:absolute;top:50%;transform:translateY(-50%);z-index:1}.elementor-swiper-button-prev{left:0}.elementor-swiper-button-next{right:0}.elementor-swiper-button svg{fill:hsla(0,7%,87%,.9);height:1em;width:1em}.elementor-pagination-position-outside .elementor-swiper-button{top:calc(50% - 15px)}.elementor-screen-only,.screen-reader-text,.screen-reader-text span,.ui-helper-hidden-accessible{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;top:-10000em;width:1px;clip:rect(0,0,0,0);border:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-horizontal>.swiper-pagination-bullets{bottom:5px;left:0;width:100%}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 6px}.swiper-container-horizontal>.swiper-pagination-bullets{bottom:5px;left:0;width:100%}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 6px}.swiper-pagination{position:absolute;text-align:center;transform:translateZ(0);transition:.3s;z-index:10}.swiper-pagination-bullet{background:#000;border-radius:50%;display:inline-block;height:6px;opacity:.2;pointer-events:none;width:6px}.swiper-pagination-custom,.swiper-pagination-fraction{bottom:5px;left:0;width:100%}.swiper-pagination-bullets{bottom:0;color:#fff;cursor:default;left:0;width:100%}.swiper-pagination-bullet-active{opacity:.8} \ No newline at end of file diff --git a/assets/css/modules/motion-fx.css b/assets/css/modules/motion-fx.css new file mode 100644 index 00000000..e21f268f --- /dev/null +++ b/assets/css/modules/motion-fx.css @@ -0,0 +1,37 @@ +.elementor-motion-effects-element, +.elementor-motion-effects-layer { + transition-property: transform, opacity; + transition-timing-function: cubic-bezier(0, 0.33, 0.07, 1.03); + transition-duration: 1s; +} + +@media (prefers-reduced-motion: reduce) { + .elementor-motion-effects-element, + .elementor-motion-effects-layer { + transition-duration: 0s !important; + } +} +.elementor-motion-effects-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + transform-origin: var(--e-transform-origin-y) var(--e-transform-origin-x); +} +.elementor-motion-effects-layer { + position: absolute; + top: 0; + left: 0; + background-repeat: no-repeat; + background-size: cover; +} +.elementor-motion-effects-perspective { + perspective: 1200px; +} +.elementor-motion-effects-element { + transform-origin: var(--e-transform-origin-y) var(--e-transform-origin-x); +} + +/*# sourceMappingURL=motion-fx.css.map */ \ No newline at end of file diff --git a/assets/css/modules/motion-fx.min.css b/assets/css/modules/motion-fx.min.css new file mode 100644 index 00000000..35913fe2 --- /dev/null +++ b/assets/css/modules/motion-fx.min.css @@ -0,0 +1 @@ +.elementor-motion-effects-element,.elementor-motion-effects-layer{transition-duration:1s;transition-property:transform,opacity;transition-timing-function:cubic-bezier(0,.33,.07,1.03)}@media (prefers-reduced-motion:reduce){.elementor-motion-effects-element,.elementor-motion-effects-layer{transition-duration:0s!important}}.elementor-motion-effects-container{height:100%;left:0;overflow:hidden;position:absolute;top:0;transform-origin:var(--e-transform-origin-y) var(--e-transform-origin-x);width:100%}.elementor-motion-effects-layer{background-repeat:no-repeat;background-size:cover;left:0;position:absolute;top:0}.elementor-motion-effects-perspective{perspective:1200px}.elementor-motion-effects-element{transform-origin:var(--e-transform-origin-y) var(--e-transform-origin-x)} \ No newline at end of file diff --git a/assets/css/modules/notes.css b/assets/css/modules/notes.css new file mode 100644 index 00000000..fd51c938 --- /dev/null +++ b/assets/css/modules/notes.css @@ -0,0 +1,24 @@ +#wpadminbar #wp-admin-bar-elementor_notes > .ab-item::before { + content: "\e918"; + font-family: eicons; + top: 3px; + font-size: 18px; +} + +.e-route-notes { + --color-editor-info: #58d0f5; +} +.e-route-notes [data-radix-portal] *:focus { + outline: none; +} +.e-route-notes.e-route-notes--notable .elementor-element, .e-route-notes.e-route-notes--notable .elementor-element * { + cursor: url("data:image/svg+xml,%3Csvg width='22' height='25' viewBox='0 0 34 40' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20.0048 38.7339L29.0211 29.5523C31.3985 27.1312 33.0175 24.0466 33.6734 20.6885C34.3293 17.3304 33.9926 13.8497 32.7059 10.6865C31.4192 7.52328 29.2402 4.81963 26.4446 2.91746C23.649 1.01528 20.3622 0 17 0C13.6378 0 10.351 1.01528 7.5554 2.91746C4.75979 4.81963 2.58085 7.52328 1.29414 10.6865C0.00742391 13.8497 -0.329284 17.3304 0.326594 20.6885C0.982471 24.0466 2.60148 27.1312 4.97888 29.5523L13.9974 38.7339C14.7943 39.5446 15.8746 40 17.0011 40C18.1275 40 19.2078 39.5446 20.0048 38.7339ZM17 25.9668C21.6944 25.9668 25.5 22.0915 25.5 17.311C25.5 12.5306 21.6944 8.65524 17 8.65524C12.3056 8.65524 8.5 12.5306 8.5 17.311C8.5 22.0915 12.3056 25.9668 17 25.9668Z' fill='%23A4AFB6'/%3E%3C/svg%3E%0A") 0 25, pointer; +} +.e-route-notes.e-route-notes--notable .elementor-element:hover { + outline: 1px solid var(--color-editor-info); +} +.e-route-notes.e-route-notes--notable .elementor-element iframe { + pointer-events: none; +} + +/*# sourceMappingURL=notes.css.map */ \ No newline at end of file diff --git a/assets/css/modules/notes.min.css b/assets/css/modules/notes.min.css new file mode 100644 index 00000000..031b14d5 --- /dev/null +++ b/assets/css/modules/notes.min.css @@ -0,0 +1 @@ +#wpadminbar #wp-admin-bar-elementor_notes>.ab-item:before{content:"\e918";font-family:eicons;font-size:18px;top:3px}.e-route-notes{--color-editor-info:#58d0f5}.e-route-notes [data-radix-portal] :focus{outline:none}.e-route-notes.e-route-notes--notable .elementor-element,.e-route-notes.e-route-notes--notable .elementor-element *{cursor:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='25' fill='none' viewBox='0 0 34 40'%3E%3Cpath fill='%23A4AFB6' fill-rule='evenodd' d='m20.005 38.734 9.016-9.182a17.4 17.4 0 0 0 4.652-8.863c.656-3.359.32-6.84-.967-10.002a17.25 17.25 0 0 0-6.261-7.77A16.8 16.8 0 0 0 17 0a16.8 16.8 0 0 0-9.445 2.917 17.25 17.25 0 0 0-6.26 7.77 17.6 17.6 0 0 0-.968 10.002 17.4 17.4 0 0 0 4.652 8.863l9.018 9.182A4.2 4.2 0 0 0 17.001 40a4.21 4.21 0 0 0 3.004-1.266M17 25.967c4.694 0 8.5-3.875 8.5-8.656 0-4.78-3.806-8.656-8.5-8.656s-8.5 3.876-8.5 8.656 3.806 8.656 8.5 8.656' clip-rule='evenodd'/%3E%3C/svg%3E") 0 25,pointer}.e-route-notes.e-route-notes--notable .elementor-element:hover{outline:1px solid var(--color-editor-info)}.e-route-notes.e-route-notes--notable .elementor-element iframe{pointer-events:none} \ No newline at end of file diff --git a/assets/css/modules/sticky.css b/assets/css/modules/sticky.css new file mode 100644 index 00000000..481225f7 --- /dev/null +++ b/assets/css/modules/sticky.css @@ -0,0 +1,12 @@ +.elementor-sticky--active { + z-index: 99; +} +.elementor-sticky__spacer .e-n-menu .e-n-menu-content { + display: none; +} + +.e-con.elementor-sticky--active { + z-index: var(--z-index, 99); +} + +/*# sourceMappingURL=sticky.css.map */ \ No newline at end of file diff --git a/assets/css/modules/sticky.min.css b/assets/css/modules/sticky.min.css new file mode 100644 index 00000000..f52adf80 --- /dev/null +++ b/assets/css/modules/sticky.min.css @@ -0,0 +1 @@ +.elementor-sticky--active{z-index:99}.elementor-sticky__spacer .e-n-menu .e-n-menu-content{display:none}.e-con.elementor-sticky--active{z-index:var(--z-index,99)} \ No newline at end of file diff --git a/assets/css/preview.css b/assets/css/preview.css new file mode 100644 index 00000000..3cdd930b --- /dev/null +++ b/assets/css/preview.css @@ -0,0 +1,228 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +*[data-editable-elementor-document] { + position: relative; +} +*[data-editable-elementor-document]::before, *[data-editable-elementor-document]::after { + content: ""; + display: table; +} +*[data-editable-elementor-document] .elementor-document-handle { + position: absolute; + z-index: 2147483620; + cursor: pointer; + inset: 0; + display: none; + border: 2px solid var(--e-a-color-primary, #F3BAFD); +} +*[data-editable-elementor-document] .elementor-document-handle::before { + content: ""; + position: absolute; + background: var(--e-a-color-primary, #F3BAFD); + opacity: 0.3; + inset: 0; +} +*[data-editable-elementor-document] .elementor-document-handle__inner { + display: none; + align-items: center; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + background: var(--e-a-color-primary, #F3BAFD); + padding: 8px 16px; + font-family: Roboto, Arial, Helvetica, sans-serif; + font-size: 12px; + line-height: 14px; + color: var(--e-p-border-global-invert, #0C0D0E); + gap: 8px; + border-radius: 0 0 3px 3px; +} +*[data-editable-elementor-document] .elementor-document-handle__inner::before, *[data-editable-elementor-document] .elementor-document-handle__inner::after { + content: ""; + position: absolute; + border: solid transparent; +} +*[data-editable-elementor-document] .elementor-document-handle__inner::before { + right: calc(100% - 1px); + border-inline-end-color: var(--e-a-color-primary, #F3BAFD); + border-width: 0 14px 30px 0; +} +*[data-editable-elementor-document] .elementor-document-handle__inner::after { + left: calc(100% - 1px); + border-inline-start-color: var(--e-a-color-primary, #F3BAFD); + border-width: 0 0 30px 14px; +} +*[data-editable-elementor-document].e-embedded-document-active .elementor-document-handle:not(.elementor-document-save-back-handle), *[data-editable-elementor-document].elementor-widget-container .elementor-document-handle:not(.elementor-document-save-back-handle) { + bottom: unset; + border-block-end: unset; +} +*[data-editable-elementor-document].e-embedded-document-active .elementor-document-handle:not(.elementor-document-save-back-handle)::before, *[data-editable-elementor-document].elementor-widget-container .elementor-document-handle:not(.elementor-document-save-back-handle)::before { + display: none; + bottom: unset; +} + +.elementor-editor-active *[data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle) { + display: block; +} +.elementor-editor-active *[data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle)::before { + display: block; +} +.elementor-editor-active *[data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle) .elementor-document-handle__inner { + display: flex; +} +.elementor-editor-active *[data-editable-elementor-document].loading { + opacity: 0.5; +} +.elementor-editor-active *[data-editable-elementor-document][data-elementor-type=single] > .elementor-document-handle { + transform: translateX(-50%) translateY(-100%); + border-radius: 3px 3px 0 0; +} +.elementor-editor-active *[data-editable-elementor-document][data-elementor-type=single] > .elementor-document-handle::before { + border-width: 30px 14px 0 0; +} +.elementor-editor-active *[data-editable-elementor-document][data-elementor-type=single] > .elementor-document-handle::after { + border-width: 30px 0 0 14px; +} + +[data-elementor-post-type=elementor_library] > .elementor-document-handle { + border: 2px solid var(--e-p-border-global, #5EEAD4); +} +[data-elementor-post-type=elementor_library] > .elementor-document-handle::before { + background-color: var(--e-p-border-global, #5EEAD4); +} +[data-elementor-post-type=elementor_library] > .elementor-document-handle .elementor-document-handle__inner { + background-color: var(--e-p-border-global, #5EEAD4); +} +[data-elementor-post-type=elementor_library] > .elementor-document-handle .elementor-document-handle__inner::before { + border-inline-end-color: var(--e-p-border-global, #5EEAD4); +} +[data-elementor-post-type=elementor_library] > .elementor-document-handle .elementor-document-handle__inner::after { + border-inline-start-color: var(--e-p-border-global, #5EEAD4); +} + +.elementor-widget.elementor-sticky--effects .elementor-editor-widget-settings { + right: -14px; +} + +.elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget:hover { + outline: 1px solid var(--e-p-border-global); +} +.elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget.elementor-element-editable, .elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget.elementor-element-editable:hover { + box-shadow: 0 0 0 2px var(--e-p-border-global); +} +.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings { + background-color: var(--e-p-border-global); +} +.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting { + background-color: var(--e-p-border-global); + color: var(--e-p-border-global-invert); +} +.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting:hover { + background-color: var(--e-p-border-global-hover); +} +.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting.elementor-editor-element-save { + display: none; +} + +.elementor-embedded-editor.elementor-location-header .elementor-section-wrap:not(:empty) + #elementor-add-new-section { + display: none; +} + +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-element-overlay, +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-empty, +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-add-section, +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-add-section-inline, +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-empty-view, +.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-widget-empty { + display: initial; +} +.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle { + display: block; + bottom: unset; + border: unset; +} +.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle:before { + display: none; +} +.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle > .elementor-document-handle__inner { + display: flex; + opacity: 1; +} +.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner { + transform: translateX(-50%) translateY(-100%); + border-radius: 3px 3px 0 0; +} +.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner:before { + border-width: 30px 14px 0 0; +} +.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner:after { + border-width: 30px 0 0 14px; +} +.elementor-document-handle.elementor-document-save-back-handle .eicon-arrow-left, +.elementor-document-handle.elementor-document-save-back-handle .eicon-arrow-right { + margin-inline-end: 5px; +} +.elementor-loop-container > div.elementor-edit-area-active:first-of-type { + border: 2px solid #5EEAD4; +} + +div[class*=elementor-widget-loop] .elementor-edit-area-active[data-editable-elementor-document], div[class*=elementor-widget-loop] .elementor-edit-area-active.swiper-slide-active, div[class*=elementor-widget-loop] .elementor-edit-area-active.e-loop-first-edit:first-of-type { + border: 2px solid #5EEAD4; +} +div[class*=elementor-widget-loop] .elementor-edit-area-active .elementor-document-save-back-handle { + display: flex; + line-height: initial; + white-space: nowrap; +} +div[class*=elementor-widget-loop] #elementor-add-new-section { + margin: 30px auto; +} +div[class*=elementor-widget-loop] .elementor-add-section-inner { + padding: 15px 0; +} + +.elementor-edit-area-active[data-elementor-type=loop-item] .elementor-section-wrap { + /* Overwrite the 25px min-height from the default .elementor-section-wrap:empty, as this causes unnecessary + white space between the "Drag widget here" box and the document handles for in-place editing, making + it look like this area is not vertically aligned on a new empty state. */ +} +.elementor-edit-area-active[data-elementor-type=loop-item] .elementor-section-wrap:not(:empty) + #elementor-add-new-section { + display: none; +} +.elementor-edit-area-active[data-elementor-type=loop-item] .elementor-section-wrap:empty { + min-height: 0; +} + +.elementor-editor-active [class*=elementor-widget-loop] .elementor:not([data-editable-elementor-document]):not(.e-loop-alternate-template):hover { + box-shadow: initial; +} + +.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle) { + display: flex; + line-height: initial; + white-space: nowrap; +} +.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle)::before { + display: block; +} +.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle) .elementor-document-handle__inner { + display: flex; +} +.elementor-editor-active [class*=elementor-widget-loop]:hover .e-loop-alternate-template { + box-shadow: 0 0 0 1px #9DA5AE; +} + +.e-loop-template-canvas { + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} +.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item { + max-width: var(--preview-width, 410px); + width: var(--preview-width, 410px); +} +.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item #elementor-add-new-section { + width: var(--preview-width, 410px); +} +/*# sourceMappingURL=preview.css.map */ \ No newline at end of file diff --git a/assets/css/preview.min.css b/assets/css/preview.min.css new file mode 100644 index 00000000..852c713d --- /dev/null +++ b/assets/css/preview.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +[data-editable-elementor-document]{position:relative}[data-editable-elementor-document]:after,[data-editable-elementor-document]:before{content:"";display:table}[data-editable-elementor-document] .elementor-document-handle{border:2px solid var(--e-a-color-primary,#f3bafd);cursor:pointer;display:none;inset:0;position:absolute;z-index:2147483620}[data-editable-elementor-document] .elementor-document-handle:before{background:var(--e-a-color-primary,#f3bafd);content:"";inset:0;opacity:.3;position:absolute}[data-editable-elementor-document] .elementor-document-handle__inner{align-items:center;background:var(--e-a-color-primary,#f3bafd);border-radius:0 0 3px 3px;color:var(--e-p-border-global-invert,#0c0d0e);display:none;font-family:Roboto,Arial,Helvetica,sans-serif;font-size:12px;gap:8px;left:50%;line-height:14px;padding:8px 16px;position:absolute;top:0;transform:translateX(-50%)}[data-editable-elementor-document] .elementor-document-handle__inner:after,[data-editable-elementor-document] .elementor-document-handle__inner:before{border:solid transparent;content:"";position:absolute}[data-editable-elementor-document] .elementor-document-handle__inner:before{border-inline-end-color:var(--e-a-color-primary,#f3bafd);border-width:0 14px 30px 0;right:calc(100% - 1px)}[data-editable-elementor-document] .elementor-document-handle__inner:after{border-inline-start-color:var(--e-a-color-primary,#f3bafd);border-width:0 0 30px 14px;left:calc(100% - 1px)}[data-editable-elementor-document].e-embedded-document-active .elementor-document-handle:not(.elementor-document-save-back-handle),[data-editable-elementor-document].elementor-widget-container .elementor-document-handle:not(.elementor-document-save-back-handle){border-block-end:unset;bottom:unset}[data-editable-elementor-document].e-embedded-document-active .elementor-document-handle:not(.elementor-document-save-back-handle):before,[data-editable-elementor-document].elementor-widget-container .elementor-document-handle:not(.elementor-document-save-back-handle):before{bottom:unset;display:none}.elementor-editor-active [data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle),.elementor-editor-active [data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle):before{display:block}.elementor-editor-active [data-editable-elementor-document]:not(.elementor-edit-mode):hover .elementor-document-handle:not(.elementor-document-save-back-handle) .elementor-document-handle__inner{display:flex}.elementor-editor-active [data-editable-elementor-document].loading{opacity:.5}.elementor-editor-active [data-editable-elementor-document][data-elementor-type=single]>.elementor-document-handle{border-radius:3px 3px 0 0;transform:translateX(-50%) translateY(-100%)}.elementor-editor-active [data-editable-elementor-document][data-elementor-type=single]>.elementor-document-handle:before{border-width:30px 14px 0 0}.elementor-editor-active [data-editable-elementor-document][data-elementor-type=single]>.elementor-document-handle:after{border-width:30px 0 0 14px}[data-elementor-post-type=elementor_library]>.elementor-document-handle{border:2px solid var(--e-p-border-global,#5eead4)}[data-elementor-post-type=elementor_library]>.elementor-document-handle .elementor-document-handle__inner,[data-elementor-post-type=elementor_library]>.elementor-document-handle:before{background-color:var(--e-p-border-global,#5eead4)}[data-elementor-post-type=elementor_library]>.elementor-document-handle .elementor-document-handle__inner:before{border-inline-end-color:var(--e-p-border-global,#5eead4)}[data-elementor-post-type=elementor_library]>.elementor-document-handle .elementor-document-handle__inner:after{border-inline-start-color:var(--e-p-border-global,#5eead4)}.elementor-widget.elementor-sticky--effects .elementor-editor-widget-settings{right:-14px}.elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget:hover{outline:1px solid var(--e-p-border-global)}.elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget.elementor-element-editable,.elementor-editor-active .elementor.elementor-edit-mode .elementor-widget.elementor-global-widget.elementor-element-editable:hover{box-shadow:0 0 0 2px var(--e-p-border-global)}.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings{background-color:var(--e-p-border-global)}.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting{background-color:var(--e-p-border-global);color:var(--e-p-border-global-invert)}.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting:hover{background-color:var(--e-p-border-global-hover)}.elementor-editor-active .elementor.elementor-edit-mode .elementor-global-widget .elementor-editor-widget-settings .elementor-editor-element-setting.elementor-editor-element-save,.elementor-embedded-editor.elementor-location-header .elementor-section-wrap:not(:empty)+#elementor-add-new-section{display:none}.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-add-section,.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-add-section-inline,.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-element-overlay,.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-empty,.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-empty-view,.elementor-editor-preview .elementor-edit-area-active[data-elementor-type=loop-item] .elementor-widget-empty{display:initial}.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle{border:unset;bottom:unset;display:block}.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle:before{display:none}.elementor.elementor-edit-area-active .elementor-document-handle.elementor-document-save-back-handle>.elementor-document-handle__inner{display:flex;opacity:1}.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner{border-radius:3px 3px 0 0;transform:translateX(-50%) translateY(-100%)}.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner:before{border-width:30px 14px 0 0}.elementor-document-handle.elementor-document-save-back-handle .elementor-document-handle__inner:after{border-width:30px 0 0 14px}.elementor-document-handle.elementor-document-save-back-handle .eicon-arrow-left,.elementor-document-handle.elementor-document-save-back-handle .eicon-arrow-right{margin-inline-end:5px}.elementor-loop-container>div.elementor-edit-area-active:first-of-type,div[class*=elementor-widget-loop] .elementor-edit-area-active.e-loop-first-edit:first-of-type,div[class*=elementor-widget-loop] .elementor-edit-area-active.swiper-slide-active,div[class*=elementor-widget-loop] .elementor-edit-area-active[data-editable-elementor-document]{border:2px solid #5eead4}div[class*=elementor-widget-loop] .elementor-edit-area-active .elementor-document-save-back-handle{display:flex;line-height:normal;white-space:nowrap}div[class*=elementor-widget-loop] #elementor-add-new-section{margin:30px auto}div[class*=elementor-widget-loop] .elementor-add-section-inner{padding:15px 0}.elementor-edit-area-active[data-elementor-type=loop-item] .elementor-section-wrap:not(:empty)+#elementor-add-new-section{display:none}.elementor-edit-area-active[data-elementor-type=loop-item] .elementor-section-wrap:empty{min-height:0}.elementor-editor-active [class*=elementor-widget-loop] .elementor:not([data-editable-elementor-document]):not(.e-loop-alternate-template):hover{box-shadow:none}.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle){display:flex;line-height:normal;white-space:nowrap}.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle):before{display:block}.elementor-editor-active [class*=elementor-widget-loop]:hover .elementor-document-handle:not(.elementor-document-save-back-handle) .elementor-document-handle__inner{display:flex}.elementor-editor-active [class*=elementor-widget-loop]:hover .e-loop-alternate-template{box-shadow:0 0 0 1px #9da5ae}.e-loop-template-canvas{align-items:center;display:flex;justify-content:center;min-height:100vh}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item{max-width:var(--preview-width,410px);width:var(--preview-width,410px)}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item #elementor-add-new-section{width:var(--preview-width,410px)} \ No newline at end of file diff --git a/assets/css/templates/widget-animated-headline-rtl.min.css b/assets/css/templates/widget-animated-headline-rtl.min.css new file mode 100644 index 00000000..edaa7b2c --- /dev/null +++ b/assets/css/templates/widget-animated-headline-rtl.min.css @@ -0,0 +1 @@ +.elementor-headline{display:block;font-size:43px;line-height:1.2}.elementor-headline-dynamic-text{color:var(--dynamic-text-color,#aebcb9)}.elementor-headline--style-rotate .elementor-headline-dynamic-wrapper{text-align:start}.elementor-headline--style-highlight .elementor-headline-dynamic-wrapper{overflow:visible;text-align:inherit}.elementor-headline--style-highlight .elementor-headline-dynamic-text{z-index:1}.elementor-headline--style-highlight .elementor-headline-plain-text{position:relative;z-index:1}.elementor-headline--style-highlight svg{height:calc(100% + 20px);left:50%;overflow:visible;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% + 20px)}.elementor-headline--style-highlight svg path{stroke:red;stroke-width:9;fill:none;opacity:0;stroke-dasharray:0 1500;transition:.3s}.elementor-headline.e-animated svg path{animation:elementor-headline-dash forwards;animation-duration:var(--animation-duration,1.2s);animation-iteration-count:1}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path{animation-duration:0s}}.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:calc(var(--animation-duration, 1.2s) / 2)}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:0s}}.elementor-headline.e-hide-highlight svg path{opacity:1;stroke-dasharray:1500 1500;animation:hide-highlight .4s forwards;animation-iteration-count:1}@keyframes elementor-headline-dash{0%{stroke-dasharray:0 1500;opacity:1}to{stroke-dasharray:1500 1500;opacity:1}}@keyframes hide-highlight{0%{opacity:1;stroke-dasharray:1500 1500}to{filter:blur(10px);opacity:0}}.elementor-headline-text-wrapper{vertical-align:bottom}.elementor-headline-dynamic-wrapper{display:inline-block;position:relative}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text{display:inline-block;inset-block-start:0;inset-inline-start:0;position:absolute}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text.elementor-headline-text-active{position:relative}.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text{opacity:0;transform:rotateX(180deg);transform-origin:50% 100%}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-flip-in 1.2s;opacity:1;transform:rotateX(0deg)}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-flip-out 1.2s;transform:rotateX(180deg)}@keyframes elementor-headline-flip-in{0%{opacity:0;transform:rotateX(180deg)}35%{opacity:0;transform:rotateX(120deg)}65%{opacity:0}to{opacity:1;transform:rotateX(1turn)}}@keyframes elementor-headline-flip-out{0%{opacity:1;transform:rotateX(0deg)}35%{opacity:1;transform:rotateX(-40deg)}65%{opacity:0}to{opacity:0;transform:rotateX(180deg)}}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:90%;inset-block-start:50%;inset-inline:auto 0;position:absolute;transform:translateY(-50%);width:1px}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:not(.elementor-headline-typing-selected):after{animation:elementor-headline-pulse 1s infinite}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected{background-color:var(--typing-selected-bg-color,#0d0d0d)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected:after{visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected .elementor-headline-dynamic-text{color:var(--typing-selected-color,var(--dynamic-text-color),#aebcb9)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-text:not(.elementor-headline-text-active){visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){position:absolute;visibility:hidden}@keyframes elementor-headline-pulse{0%{opacity:1;transform:translateY(-50%) scale(1)}40%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:0;transform:translateY(-50%) scale(0)}}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text{opacity:0;transform:scaleX(1.0005)}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:0;transform:translateZ(-20px) rotateX(90deg);transform-style:preserve-3d}.elementor-headline-text-active .elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-swirl-in .4s forwards}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-swirl-out .4s forwards}@keyframes elementor-headline-swirl-in{0%{opacity:0;transform:translateZ(-20px) rotateX(90deg)}60%{opacity:1;transform:translateZ(-20px) rotateX(-10deg)}to{opacity:1;transform:translateZ(-20px) rotateX(0deg)}}@keyframes elementor-headline-swirl-out{0%{opacity:1;transform:translateZ(-20px) rotateX(0)}60%{opacity:0;transform:translateZ(-20px) rotateX(-100deg)}to{opacity:0;transform:translateZ(-20px) rotateX(-90deg)}}.elementor-headline-animation-type-slide-down .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text{opacity:0;top:.2em}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-down-in .6s;opacity:1;top:0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-down-out .6s}@keyframes elementor-headline-slide-down-in{0%{opacity:0;transform:translateY(-100%)}60%{opacity:1;transform:translateY(20%)}to{opacity:1;transform:translateY(0)}}@keyframes elementor-headline-slide-down-out{0%{opacity:1;transform:translateY(0)}60%{opacity:0;transform:translateY(120%)}to{opacity:0;transform:translateY(100%)}}.elementor-headline-animation-type-clip .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:100%;inset-block-start:0;inset-inline:auto 0;position:absolute;width:2px}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text.elementor-headline-text-active{opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-drop-in-in .8s;opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-drop-in-out .8s}@keyframes elementor-headline-drop-in-in{0%{opacity:0;transform:translateZ(100px)}to{opacity:1;transform:translateZ(0)}}@keyframes elementor-headline-drop-in-out{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translateZ(-100px)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block;transform:rotateY(180deg)}.elementor-headline-text-active .elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{transform:rotateY(0deg)}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-blinds-in .6s forwards}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-blinds-out .6s forwards}@keyframes elementor-headline-blinds-in{0%{transform:rotateY(180deg)}to{transform:rotateY(0deg)}}@keyframes elementor-headline-blinds-out{0%{transform:rotateY(0)}to{transform:rotateY(-180deg)}}.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{display:inline-block;opacity:0;transform:scale(0)}.elementor-headline-text-active .elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-wave-up .6s forwards}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-wave-down .6s forwards}@keyframes elementor-headline-wave-up{0%{opacity:0;transform:scale(0)}60%{opacity:1;transform:scale(1.2)}to{opacity:1;transform:scale(1)}}@keyframes elementor-headline-wave-down{0%{opacity:1;transform:scale(1)}60%{opacity:0;transform:scale(0)}}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-in .6s;opacity:1}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-out .6s}@keyframes elementor-headline-slide-in{0%{opacity:0;transform:translateX(-100%)}60%{opacity:1;transform:translateX(10%)}to{opacity:1;transform:translateX(0)}}@keyframes elementor-headline-slide-out{0%{opacity:1;transform:translateX(0)}60%{opacity:0;transform:translateX(110%)}to{opacity:0;transform:translateX(100%)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{transition:width .5s}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{overflow:hidden}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text,.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{white-space:nowrap} \ No newline at end of file diff --git a/assets/css/templates/widget-animated-headline.min.css b/assets/css/templates/widget-animated-headline.min.css new file mode 100644 index 00000000..edaa7b2c --- /dev/null +++ b/assets/css/templates/widget-animated-headline.min.css @@ -0,0 +1 @@ +.elementor-headline{display:block;font-size:43px;line-height:1.2}.elementor-headline-dynamic-text{color:var(--dynamic-text-color,#aebcb9)}.elementor-headline--style-rotate .elementor-headline-dynamic-wrapper{text-align:start}.elementor-headline--style-highlight .elementor-headline-dynamic-wrapper{overflow:visible;text-align:inherit}.elementor-headline--style-highlight .elementor-headline-dynamic-text{z-index:1}.elementor-headline--style-highlight .elementor-headline-plain-text{position:relative;z-index:1}.elementor-headline--style-highlight svg{height:calc(100% + 20px);left:50%;overflow:visible;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% + 20px)}.elementor-headline--style-highlight svg path{stroke:red;stroke-width:9;fill:none;opacity:0;stroke-dasharray:0 1500;transition:.3s}.elementor-headline.e-animated svg path{animation:elementor-headline-dash forwards;animation-duration:var(--animation-duration,1.2s);animation-iteration-count:1}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path{animation-duration:0s}}.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:calc(var(--animation-duration, 1.2s) / 2)}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:0s}}.elementor-headline.e-hide-highlight svg path{opacity:1;stroke-dasharray:1500 1500;animation:hide-highlight .4s forwards;animation-iteration-count:1}@keyframes elementor-headline-dash{0%{stroke-dasharray:0 1500;opacity:1}to{stroke-dasharray:1500 1500;opacity:1}}@keyframes hide-highlight{0%{opacity:1;stroke-dasharray:1500 1500}to{filter:blur(10px);opacity:0}}.elementor-headline-text-wrapper{vertical-align:bottom}.elementor-headline-dynamic-wrapper{display:inline-block;position:relative}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text{display:inline-block;inset-block-start:0;inset-inline-start:0;position:absolute}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text.elementor-headline-text-active{position:relative}.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text{opacity:0;transform:rotateX(180deg);transform-origin:50% 100%}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-flip-in 1.2s;opacity:1;transform:rotateX(0deg)}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-flip-out 1.2s;transform:rotateX(180deg)}@keyframes elementor-headline-flip-in{0%{opacity:0;transform:rotateX(180deg)}35%{opacity:0;transform:rotateX(120deg)}65%{opacity:0}to{opacity:1;transform:rotateX(1turn)}}@keyframes elementor-headline-flip-out{0%{opacity:1;transform:rotateX(0deg)}35%{opacity:1;transform:rotateX(-40deg)}65%{opacity:0}to{opacity:0;transform:rotateX(180deg)}}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:90%;inset-block-start:50%;inset-inline:auto 0;position:absolute;transform:translateY(-50%);width:1px}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:not(.elementor-headline-typing-selected):after{animation:elementor-headline-pulse 1s infinite}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected{background-color:var(--typing-selected-bg-color,#0d0d0d)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected:after{visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected .elementor-headline-dynamic-text{color:var(--typing-selected-color,var(--dynamic-text-color),#aebcb9)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-text:not(.elementor-headline-text-active){visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){position:absolute;visibility:hidden}@keyframes elementor-headline-pulse{0%{opacity:1;transform:translateY(-50%) scale(1)}40%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:0;transform:translateY(-50%) scale(0)}}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text{opacity:0;transform:scaleX(1.0005)}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:0;transform:translateZ(-20px) rotateX(90deg);transform-style:preserve-3d}.elementor-headline-text-active .elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-swirl-in .4s forwards}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-swirl-out .4s forwards}@keyframes elementor-headline-swirl-in{0%{opacity:0;transform:translateZ(-20px) rotateX(90deg)}60%{opacity:1;transform:translateZ(-20px) rotateX(-10deg)}to{opacity:1;transform:translateZ(-20px) rotateX(0deg)}}@keyframes elementor-headline-swirl-out{0%{opacity:1;transform:translateZ(-20px) rotateX(0)}60%{opacity:0;transform:translateZ(-20px) rotateX(-100deg)}to{opacity:0;transform:translateZ(-20px) rotateX(-90deg)}}.elementor-headline-animation-type-slide-down .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text{opacity:0;top:.2em}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-down-in .6s;opacity:1;top:0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-down-out .6s}@keyframes elementor-headline-slide-down-in{0%{opacity:0;transform:translateY(-100%)}60%{opacity:1;transform:translateY(20%)}to{opacity:1;transform:translateY(0)}}@keyframes elementor-headline-slide-down-out{0%{opacity:1;transform:translateY(0)}60%{opacity:0;transform:translateY(120%)}to{opacity:0;transform:translateY(100%)}}.elementor-headline-animation-type-clip .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:100%;inset-block-start:0;inset-inline:auto 0;position:absolute;width:2px}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text.elementor-headline-text-active{opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-drop-in-in .8s;opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-drop-in-out .8s}@keyframes elementor-headline-drop-in-in{0%{opacity:0;transform:translateZ(100px)}to{opacity:1;transform:translateZ(0)}}@keyframes elementor-headline-drop-in-out{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translateZ(-100px)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block;transform:rotateY(180deg)}.elementor-headline-text-active .elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{transform:rotateY(0deg)}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-blinds-in .6s forwards}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-blinds-out .6s forwards}@keyframes elementor-headline-blinds-in{0%{transform:rotateY(180deg)}to{transform:rotateY(0deg)}}@keyframes elementor-headline-blinds-out{0%{transform:rotateY(0)}to{transform:rotateY(-180deg)}}.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{display:inline-block;opacity:0;transform:scale(0)}.elementor-headline-text-active .elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-wave-up .6s forwards}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-wave-down .6s forwards}@keyframes elementor-headline-wave-up{0%{opacity:0;transform:scale(0)}60%{opacity:1;transform:scale(1.2)}to{opacity:1;transform:scale(1)}}@keyframes elementor-headline-wave-down{0%{opacity:1;transform:scale(1)}60%{opacity:0;transform:scale(0)}}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-in .6s;opacity:1}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-out .6s}@keyframes elementor-headline-slide-in{0%{opacity:0;transform:translateX(-100%)}60%{opacity:1;transform:translateX(10%)}to{opacity:1;transform:translateX(0)}}@keyframes elementor-headline-slide-out{0%{opacity:1;transform:translateX(0)}60%{opacity:0;transform:translateX(110%)}to{opacity:0;transform:translateX(100%)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{transition:width .5s}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{overflow:hidden}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text,.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{white-space:nowrap} \ No newline at end of file diff --git a/assets/css/templates/widget-call-to-action-rtl.min.css b/assets/css/templates/widget-call-to-action-rtl.min.css new file mode 100644 index 00000000..ce06d67c --- /dev/null +++ b/assets/css/templates/widget-call-to-action-rtl.min.css @@ -0,0 +1 @@ +.elementor-widget-call-to-action .elementor-widget-container,.elementor-widget-call-to-action:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-cta{display:flex;overflow:hidden;position:relative;transition:.5s}.elementor-cta--skin-classic .elementor-cta{flex-wrap:wrap}.elementor-cta--skin-classic .elementor-cta__bg-wrapper{min-height:200px;position:relative;width:100%}.elementor-cta--skin-classic .elementor-cta__content{background-color:#f9fafa;transition:all .4s;width:100%}.elementor-cta--skin-classic .elementor-cta__content-item,.elementor-cta--skin-classic .elementor-cta__content-item .elementor-icon{border-color:#3f444b;color:#3f444b;fill:#3f444b}.elementor-cta--skin-classic .elementor-cta__button.elementor-button{border-color:#3f444b;color:#3f444b}.elementor-cta--skin-cover .elementor-cta{display:block}.elementor-cta--skin-cover .elementor-cta__bg-wrapper{inset:0;position:absolute;transition:all .4s;width:100%}.elementor-cta--skin-cover .elementor-cta__content{min-height:280px}.elementor-cta--skin-cover .elementor-cta__button.elementor-button,.elementor-cta--skin-cover .elementor-cta__content-item,.elementor-cta--skin-cover .elementor-cta__content-item .elementor-icon{border-color:#fff;color:#fff}.elementor-cta--layout-image-above .elementor-cta,.elementor-cta--layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--layout-image-left .elementor-cta,.elementor-cta--layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--layout-image-left .elementor-cta__content,.elementor-cta--layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--layout-image-right .elementor-cta{flex-direction:row}.elementor-cta__bg,.elementor-cta__bg-overlay{inset:0;position:absolute;transition:all .4s}.elementor-cta__bg-wrapper{overflow:hidden;z-index:1}.elementor-cta__bg{background-position:50%;background-size:cover;z-index:1}.elementor-cta__bg-overlay{z-index:2}.elementor-cta__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-cta__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-cta__title{font-size:23px}.elementor-cta__content{align-content:center;align-items:center;display:flex;flex-wrap:wrap;overflow:hidden;padding:35px;width:100%;z-index:1}.elementor-cta__content,.elementor-cta__content-item{color:#fff;position:relative;transition:.5s}.elementor-cta__content-item{margin:0;width:100%}.elementor-cta__content-item:not(:last-child){margin-bottom:15px}.elementor-cta__content-item .elementor-icon{color:#fff}.elementor-cta--valign-top .elementor-cta__content{align-content:flex-start;align-items:flex-start}.elementor-cta--valign-middle .elementor-cta__content{align-content:center;align-items:center}.elementor-cta--valign-bottom .elementor-cta__content{align-content:flex-end;align-items:flex-end}.elementor-cta:hover .elementor-cta__bg-overlay{background-color:rgba(0,0,0,.3)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-cta{cursor:pointer}}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-cta--widescreen-layout-image-above .elementor-cta,.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--widescreen-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--widescreen-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--widescreen-layout-image-left .elementor-cta,.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--widescreen-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--widescreen-layout-image-left .elementor-cta__content,.elementor-cta--widescreen-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--widescreen-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-cta--laptop-layout-image-above .elementor-cta,.elementor-cta--laptop-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--laptop-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--laptop-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--laptop-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--laptop-layout-image-left .elementor-cta,.elementor-cta--laptop-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--laptop-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--laptop-layout-image-left .elementor-cta__content,.elementor-cta--laptop-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--laptop-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--laptop-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-cta--tablet_extra-layout-image-above .elementor-cta,.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet_extra-layout-image-left .elementor-cta,.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__content,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet_extra-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-cta--tablet-layout-image-above .elementor-cta,.elementor-cta--tablet-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet-layout-image-left .elementor-cta,.elementor-cta--tablet-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet-layout-image-left .elementor-cta__content,.elementor-cta--tablet-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--tablet-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-cta--mobile_extra-layout-image-above .elementor-cta,.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile_extra-layout-image-left .elementor-cta,.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__content,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile_extra-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-cta--mobile-layout-image-above .elementor-cta,.elementor-cta--mobile-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile-layout-image-left .elementor-cta,.elementor-cta--mobile-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile-layout-image-left .elementor-cta__content,.elementor-cta--mobile-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--mobile-layout-image-right .elementor-cta{flex-direction:row}}.elementor-bg-transform .elementor-bg{will-change:transform}.elementor-bg-transform-zoom-in:hover .elementor-bg,.elementor-bg-transform-zoom-out .elementor-bg{transform:scale(1.2)}.elementor-bg-transform-zoom-out:hover .elementor-bg{transform:scale(1)}.elementor-bg-transform-move-left .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-left:hover .elementor-bg,.elementor-bg-transform-move-right .elementor-bg{transform:scale(1.2) translateX(-8%)}.elementor-bg-transform-move-right:hover .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-up .elementor-bg{transform:scale(1.2) translateY(8%)}.elementor-bg-transform-move-down .elementor-bg,.elementor-bg-transform-move-up:hover .elementor-bg{transform:scale(1.2) translateY(-8%)}.elementor-bg-transform-move-down:hover .elementor-bg{transform:scale(1.2) translateY(8%)} \ No newline at end of file diff --git a/assets/css/templates/widget-call-to-action.min.css b/assets/css/templates/widget-call-to-action.min.css new file mode 100644 index 00000000..fa1d027f --- /dev/null +++ b/assets/css/templates/widget-call-to-action.min.css @@ -0,0 +1 @@ +.elementor-widget-call-to-action .elementor-widget-container,.elementor-widget-call-to-action:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-cta{display:flex;overflow:hidden;position:relative;transition:.5s}.elementor-cta--skin-classic .elementor-cta{flex-wrap:wrap}.elementor-cta--skin-classic .elementor-cta__bg-wrapper{min-height:200px;position:relative;width:100%}.elementor-cta--skin-classic .elementor-cta__content{background-color:#f9fafa;transition:all .4s;width:100%}.elementor-cta--skin-classic .elementor-cta__content-item,.elementor-cta--skin-classic .elementor-cta__content-item .elementor-icon{border-color:#3f444b;color:#3f444b;fill:#3f444b}.elementor-cta--skin-classic .elementor-cta__button.elementor-button{border-color:#3f444b;color:#3f444b}.elementor-cta--skin-cover .elementor-cta{display:block}.elementor-cta--skin-cover .elementor-cta__bg-wrapper{inset:0;position:absolute;transition:all .4s;width:100%}.elementor-cta--skin-cover .elementor-cta__content{min-height:280px}.elementor-cta--skin-cover .elementor-cta__button.elementor-button,.elementor-cta--skin-cover .elementor-cta__content-item,.elementor-cta--skin-cover .elementor-cta__content-item .elementor-icon{border-color:#fff;color:#fff}.elementor-cta--layout-image-above .elementor-cta,.elementor-cta--layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--layout-image-left .elementor-cta,.elementor-cta--layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--layout-image-left .elementor-cta__content,.elementor-cta--layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--layout-image-right .elementor-cta{flex-direction:row-reverse}.elementor-cta__bg,.elementor-cta__bg-overlay{inset:0;position:absolute;transition:all .4s}.elementor-cta__bg-wrapper{overflow:hidden;z-index:1}.elementor-cta__bg{background-position:50%;background-size:cover;z-index:1}.elementor-cta__bg-overlay{z-index:2}.elementor-cta__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-cta__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-cta__title{font-size:23px}.elementor-cta__content{align-content:center;align-items:center;display:flex;flex-wrap:wrap;overflow:hidden;padding:35px;width:100%;z-index:1}.elementor-cta__content,.elementor-cta__content-item{color:#fff;position:relative;transition:.5s}.elementor-cta__content-item{margin:0;width:100%}.elementor-cta__content-item:not(:last-child){margin-bottom:15px}.elementor-cta__content-item .elementor-icon{color:#fff}.elementor-cta--valign-top .elementor-cta__content{align-content:flex-start;align-items:flex-start}.elementor-cta--valign-middle .elementor-cta__content{align-content:center;align-items:center}.elementor-cta--valign-bottom .elementor-cta__content{align-content:flex-end;align-items:flex-end}.elementor-cta:hover .elementor-cta__bg-overlay{background-color:rgba(0,0,0,.3)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-cta{cursor:pointer}}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-cta--widescreen-layout-image-above .elementor-cta,.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--widescreen-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--widescreen-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--widescreen-layout-image-left .elementor-cta,.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--widescreen-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--widescreen-layout-image-left .elementor-cta__content,.elementor-cta--widescreen-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--widescreen-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-cta--laptop-layout-image-above .elementor-cta,.elementor-cta--laptop-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--laptop-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--laptop-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--laptop-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--laptop-layout-image-left .elementor-cta,.elementor-cta--laptop-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--laptop-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--laptop-layout-image-left .elementor-cta__content,.elementor-cta--laptop-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--laptop-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--laptop-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-cta--tablet_extra-layout-image-above .elementor-cta,.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet_extra-layout-image-left .elementor-cta,.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__content,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet_extra-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-cta--tablet-layout-image-above .elementor-cta,.elementor-cta--tablet-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet-layout-image-left .elementor-cta,.elementor-cta--tablet-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet-layout-image-left .elementor-cta__content,.elementor-cta--tablet-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--tablet-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-cta--mobile_extra-layout-image-above .elementor-cta,.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile_extra-layout-image-left .elementor-cta,.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__content,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile_extra-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-cta--mobile-layout-image-above .elementor-cta,.elementor-cta--mobile-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile-layout-image-left .elementor-cta,.elementor-cta--mobile-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile-layout-image-left .elementor-cta__content,.elementor-cta--mobile-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--mobile-layout-image-right .elementor-cta{flex-direction:row-reverse}}.elementor-bg-transform .elementor-bg{will-change:transform}.elementor-bg-transform-zoom-in:hover .elementor-bg,.elementor-bg-transform-zoom-out .elementor-bg{transform:scale(1.2)}.elementor-bg-transform-zoom-out:hover .elementor-bg{transform:scale(1)}.elementor-bg-transform-move-left .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-left:hover .elementor-bg,.elementor-bg-transform-move-right .elementor-bg{transform:scale(1.2) translateX(-8%)}.elementor-bg-transform-move-right:hover .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-up .elementor-bg{transform:scale(1.2) translateY(8%)}.elementor-bg-transform-move-down .elementor-bg,.elementor-bg-transform-move-up:hover .elementor-bg{transform:scale(1.2) translateY(-8%)}.elementor-bg-transform-move-down:hover .elementor-bg{transform:scale(1.2) translateY(8%)} \ No newline at end of file diff --git a/assets/css/templates/widget-code-highlight-rtl.min.css b/assets/css/templates/widget-code-highlight-rtl.min.css new file mode 100644 index 00000000..d7194757 --- /dev/null +++ b/assets/css/templates/widget-code-highlight-rtl.min.css @@ -0,0 +1 @@ +.prismjs-dark code[class*=language-],.prismjs-dark pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-dark pre[class*=language-]{background:#4c3f33;border:.3em solid #7a6651;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-dark :not(pre)>code[class*=language-]{border:.13em solid #7a6651;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-dark .token.cdata,.prismjs-dark .token.doctype,.prismjs-dark .token.prolog,.token.comment{color:#997f66}.prismjs-dark .token.namespace,.prismjs-dark .token.punctuation{opacity:.7}.prismjs-dark .token.boolean,.prismjs-dark .token.constant,.prismjs-dark .token.number,.prismjs-dark .token.property,.prismjs-dark .token.symbol,.prismjs-dark .token.tag{color:#d1939e}.prismjs-dark .token.attr-name,.prismjs-dark .token.builtin,.prismjs-dark .token.char,.prismjs-dark .token.inserted,.prismjs-dark .token.selector,.prismjs-dark .token.string{color:#bce051}.prismjs-dark .language-css .token.string,.prismjs-dark .style .token.string,.prismjs-dark .token.entity,.prismjs-dark .token.operator,.prismjs-dark .token.url,.token.variable{color:#f4b73d}.prismjs-dark .token.atrule,.prismjs-dark .token.attr-value,.prismjs-dark .token.keyword{color:#d1939e}.prismjs-dark .token.important,.prismjs-dark .token.regex{color:#e90}.prismjs-dark .token.bold,.prismjs-dark .token.important{font-weight:700}.prismjs-dark .token.italic{font-style:italic}.prismjs-dark .token.entity{cursor:help}.prismjs-dark .token.deleted{color:red}.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{background:0 0;color:#000;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px #fff;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-default code[class*=language-] ::-moz-selection,.prismjs-default code[class*=language-]::-moz-selection,.prismjs-default pre[class*=language-] ::-moz-selection,.prismjs-default pre[class*=language-]::-moz-selection{background:#b3d4fc;text-shadow:none}.prismjs-default code[class*=language-] ::selection,.prismjs-default code[class*=language-]::selection,.prismjs-default pre[class*=language-] ::selection,.prismjs-default pre[class*=language-]::selection{background:#b3d4fc;text-shadow:none}@media print{.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{text-shadow:none}}.prismjs-default pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-default :not(pre)>code[class*=language-],.prismjs-default pre[class*=language-]{background:#f5f2f0}.prismjs-default :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-default .token.cdata,.prismjs-default .token.comment,.prismjs-default .token.doctype,.prismjs-default .token.prolog{color:#708090}.prismjs-default .token.punctuation{color:#999}.prismjs-default .token.namespace{opacity:.7}.prismjs-default .token.boolean,.prismjs-default .token.constant,.prismjs-default .token.deleted,.prismjs-default .token.number,.prismjs-default .token.property,.prismjs-default .token.symbol,.prismjs-default .token.tag{color:#905}.prismjs-default .token.attr-name,.prismjs-default .token.builtin,.prismjs-default .token.char,.prismjs-default .token.inserted,.prismjs-default .token.selector,.prismjs-default .token.string{color:#690}.prismjs-default .language-css .token.string,.prismjs-default .style .token.string,.prismjs-default .token.entity,.prismjs-default .token.operator,.prismjs-default .token.url{background:hsla(0,0%,100%,.5);color:#9a6e3a}.prismjs-default .token.atrule,.prismjs-default .token.attr-value,.prismjs-default .token.keyword{color:#07a}.prismjs-default .token.class-name,.prismjs-default .token.function{color:#dd4a68}.prismjs-default .token.important,.prismjs-default .token.regex,.prismjs-default .token.variable{color:#e90}.prismjs-default .token.bold,.prismjs-default .token.important{font-weight:700}.prismjs-default .token.italic{font-style:italic}.prismjs-default .token.entity{cursor:help}.prismjs-okaidia code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:0 0;color:#f8f8f2;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px rgba(0,0,0,.3);white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-okaidia pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-okaidia :not(pre)>code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:#272822}.prismjs-okaidia :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-okaidia .token.cdata,.prismjs-okaidia .token.comment,.prismjs-okaidia .token.doctype,.prismjs-okaidia .token.prolog{color:#8292a2}.prismjs-okaidia .token.punctuation{color:#f8f8f2}.prismjs-okaidia .token.namespace{opacity:.7}.prismjs-okaidia .token.constant,.prismjs-okaidia .token.deleted,.prismjs-okaidia .token.property,.prismjs-okaidia .token.symbol,.prismjs-okaidia .token.tag{color:#f92672}.prismjs-okaidia .token.boolean,.prismjs-okaidia .token.number{color:#ae81ff}.prismjs-okaidia .token.attr-name,.prismjs-okaidia .token.builtin,.prismjs-okaidia .token.char,.prismjs-okaidia .token.inserted,.prismjs-okaidia .token.selector,.prismjs-okaidia .token.string{color:#a6e22e}.prismjs-okaidia .language-css .token.string,.prismjs-okaidia .style .token.string,.prismjs-okaidia .token.entity,.prismjs-okaidia .token.operator,.prismjs-okaidia .token.url,.prismjs-okaidia .token.variable{color:#f8f8f2}.prismjs-okaidia .token.atrule,.prismjs-okaidia .token.attr-value,.prismjs-okaidia .token.class-name,.prismjs-okaidia .token.function{color:#e6db74}.prismjs-okaidia .token.keyword{color:#66d9ef}.prismjs-okaidia .token.important,.prismjs-okaidia .token.regex{color:#fd971f}.prismjs-okaidia .token.bold,.prismjs-okaidia .token.important{font-weight:700}.prismjs-okaidia .token.italic{font-style:italic}.prismjs-okaidia .token.entity{cursor:help}.prismjs-solarizedlight code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{color:#657b83;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-solarizedlight code[class*=language-] ::-moz-selection,.prismjs-solarizedlight code[class*=language-]::-moz-selection,.prismjs-solarizedlight pre[class*=language-] ::-moz-selection,.prismjs-solarizedlight pre[class*=language-]::-moz-selection{background:#073642}.prismjs-solarizedlight code[class*=language-] ::selection,.prismjs-solarizedlight code[class*=language-]::selection,.prismjs-solarizedlight pre[class*=language-] ::selection,.prismjs-solarizedlight pre[class*=language-]::selection{background:#073642}.prismjs-solarizedlight pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-solarizedlight :not(pre)>code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{background-color:#fdf6e3}.prismjs-solarizedlight :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em}.prismjs-solarizedlight .token.cdata,.prismjs-solarizedlight .token.comment,.prismjs-solarizedlight .token.doctype,.prismjs-solarizedlight .token.prolog{color:#93a1a1}.prismjs-solarizedlight .token.punctuation{color:#586e75}.prismjs-solarizedlight .token.namespace{opacity:.7}.prismjs-solarizedlight .token.boolean,.prismjs-solarizedlight .token.constant,.prismjs-solarizedlight .token.deleted,.prismjs-solarizedlight .token.number,.prismjs-solarizedlight .token.property,.prismjs-solarizedlight .token.symbol,.token.tag{color:#268bd2}.prismjs-solarizedlight .token.attr-name,.prismjs-solarizedlight .token.builtin,.prismjs-solarizedlight .token.char,.prismjs-solarizedlight .token.inserted,.prismjs-solarizedlight .token.selector,.prismjs-solarizedlight .token.string,.prismjs-solarizedlight .token.url{color:#2aa198}.prismjs-solarizedlight .token.entity{background:#eee8d5;color:#657b83}.prismjs-solarizedlight .token.atrule,.prismjs-solarizedlight .token.attr-value,.prismjs-solarizedlight .token.keyword{color:#859900}.prismjs-solarizedlight .token.class-name,.prismjs-solarizedlight .token.function{color:#b58900}.prismjs-solarizedlight .token.important,.prismjs-solarizedlight .token.regex,.prismjs-solarizedlight .token.variable{color:#cb4b16}.prismjs-solarizedlight .token.bold,.prismjs-solarizedlight .token.important{font-weight:700}.prismjs-solarizedlight .token.italic{font-style:italic}.prismjs-solarizedlight .token.entity{cursor:help}.prismjs-tomorrow code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:0 0;color:#ccc;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-tomorrow pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-tomorrow :not(pre)>code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:#2d2d2d}.prismjs-tomorrow :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-tomorrow .token.block-comment,.prismjs-tomorrow .token.cdata,.prismjs-tomorrow .token.comment,.prismjs-tomorrow .token.doctype,.prismjs-tomorrow .token.prolog{color:#999}.prismjs-tomorrow .token.punctuation{color:#ccc}.prismjs-tomorrow .token.attr-name,.prismjs-tomorrow .token.deleted,.prismjs-tomorrow .token.namespace,.prismjs-tomorrow .token.tag{color:#e2777a}.prismjs-tomorrow .token.function-name{color:#6196cc}.prismjs-tomorrow .token.boolean,.prismjs-tomorrow .token.function,.prismjs-tomorrow .token.number{color:#f08d49}.prismjs-tomorrow .token.class-name,.prismjs-tomorrow .token.constant,.prismjs-tomorrow .token.property,.prismjs-tomorrow .token.symbol{color:#f8c555}.prismjs-tomorrow .token.atrule,.prismjs-tomorrow .token.builtin,.prismjs-tomorrow .token.important,.prismjs-tomorrow .token.keyword,.prismjs-tomorrow .token.selector{color:#cc99cd}.prismjs-tomorrow .token.attr-value,.prismjs-tomorrow .token.char,.prismjs-tomorrow .token.regex,.prismjs-tomorrow .token.string,.prismjs-tomorrow .token.variable{color:#7ec699}.prismjs-tomorrow .token.entity,.prismjs-tomorrow .token.operator,.prismjs-tomorrow .token.url{color:#67cdcc}.prismjs-tomorrow .token.bold,.prismjs-tomorrow .token.important{font-weight:700}.prismjs-tomorrow .token.italic{font-style:italic}.prismjs-tomorrow .token.entity{cursor:help}.prismjs-tomorrow .token.inserted{color:green}.prismjs-twilight code[class*=language-],.prismjs-twilight pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-twilight :not(pre)>code[class*=language-],.prismjs-twilight pre[class*=language-]{background:#141414}.prismjs-twilight pre[class*=language-]{border:.3em solid #545454;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-twilight pre[class*=language-]::-moz-selection{background:#27292a}.prismjs-twilight pre[class*=language-]::selection{background:#27292a}.prismjs-twilight code[class*=language-] ::-moz-selection,.prismjs-twilight code[class*=language-]::-moz-selection,.prismjs-twilight pre[class*=language-] ::-moz-selection,.prismjs-twilight pre[class*=language-]::-moz-selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight code[class*=language-] ::selection,.prismjs-twilight code[class*=language-]::selection,.prismjs-twilight pre[class*=language-] ::selection,.prismjs-twilight pre[class*=language-]::selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight :not(pre)>code[class*=language-]{border:.13em solid #545454;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-twilight .token.cdata,.prismjs-twilight .token.comment,.prismjs-twilight .token.doctype,.prismjs-twilight .token.prolog{color:#777}.prismjs-twilight .token.namespace,.prismjs-twilight .token.punctuation{opacity:.7}.prismjs-twilight .token.boolean,.prismjs-twilight .token.deleted,.prismjs-twilight .token.number,.prismjs-twilight .token.tag{color:#ce6849}.prismjs-twilight .token.builtin,.prismjs-twilight .token.constant,.prismjs-twilight .token.keyword,.prismjs-twilight .token.property,.prismjs-twilight .token.selector,.prismjs-twilight .token.symbol{color:#f9ed99}.prismjs-twilight .language-css .token.string,.prismjs-twilight .style .token.string,.prismjs-twilight .token.attr-name,.prismjs-twilight .token.attr-value,.prismjs-twilight .token.char,.prismjs-twilight .token.entity,.prismjs-twilight .token.inserted,.prismjs-twilight .token.operator,.prismjs-twilight .token.string,.prismjs-twilight .token.url,.prismjs-twilight .token.variable{color:#909e6a}.prismjs-twilight .token.atrule{color:#7385a5}.prismjs-twilight .token.important,.prismjs-twilight .token.regex{color:#e8c062}.prismjs-twilight .token.bold,.prismjs-twilight .token.important{font-weight:700}.prismjs-twilight .token.italic{font-style:italic}.prismjs-twilight .token.entity{cursor:help}.prismjs-twilight pre[data-line]{padding:1em;position:relative}.prismjs-twilight .language-markup .token.attr-name,.prismjs-twilight .language-markup .token.punctuation,.prismjs-twilight .language-markup .token.tag{color:#ac885c}.prismjs-twilight .token{position:relative;z-index:1}.prismjs-twilight .line-highlight{background:rgba(84,84,84,.25);background:linear-gradient(90deg,rgba(84,84,84,.1) 70%,rgba(84,84,84,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;left:0;line-height:inherit;margin-top:.75em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre;z-index:0}.prismjs-twilight .line-highlight:before,.prismjs-twilight .line-highlight[data-end]:after{background-color:#8693a6;border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.prismjs-twilight .line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.copy-to-clipboard div.code-toolbar{position:relative}.copy-to-clipboard div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out}.copy-to-clipboard div.code-toolbar:hover>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar:focus-within>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar>.toolbar .toolbar-item{display:inline-block}.copy-to-clipboard div.code-toolbar>.toolbar a{cursor:pointer}.copy-to-clipboard div.code-toolbar>.toolbar button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.copy-to-clipboard div.code-toolbar>.toolbar a,.copy-to-clipboard div.code-toolbar>.toolbar button,.copy-to-clipboard div.code-toolbar>.toolbar span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}.copy-to-clipboard div.code-toolbar>.toolbar a:focus,div.code-toolbar>.toolbar a:hover,div.code-toolbar>.toolbar button:focus,div.code-toolbar>.toolbar button:hover,div.code-toolbar>.toolbar span:focus,div.code-toolbar>.toolbar span:hover{color:inherit;text-decoration:none}:not(.copy-to-clipboard)>div.code-toolbar>.toolbar{display:none}.word-wrap code[class*=language-],.word-wrap pre[class*=language-]{white-space:pre-wrap!important}.elementor-widget-code-highlight .elementor-widget-container,.elementor-widget-code-highlight:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-widget-code-highlight pre{direction:ltr}.prismjs-twilight pre:not([data-line=""]):not(.line-numbers){padding:.8em 0 1em 2em}.prismjs-dark pre:not([data-line=""]):not(.line-numbers),.prismjs-default pre:not([data-line=""]):not(.line-numbers),.prismjs-okaidia pre:not([data-line=""]):not(.line-numbers),.prismjs-solarizedlight pre:not([data-line=""]):not(.line-numbers),.prismjs-tomorrow pre:not([data-line=""]):not(.line-numbers){padding:1em 0 1em 2em}pre[data-line]{padding:1em 0 1em 3em;position:relative}.line-highlight{background:hsla(24,20%,50%,.08);background:linear-gradient(90deg,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));left:0;line-height:inherit;margin-top:1em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{background-color:hsla(24,20%,50%,.4);border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:hsla(0,0%,50%,.2)}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right} \ No newline at end of file diff --git a/assets/css/templates/widget-code-highlight.min.css b/assets/css/templates/widget-code-highlight.min.css new file mode 100644 index 00000000..d7194757 --- /dev/null +++ b/assets/css/templates/widget-code-highlight.min.css @@ -0,0 +1 @@ +.prismjs-dark code[class*=language-],.prismjs-dark pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-dark pre[class*=language-]{background:#4c3f33;border:.3em solid #7a6651;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-dark :not(pre)>code[class*=language-]{border:.13em solid #7a6651;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-dark .token.cdata,.prismjs-dark .token.doctype,.prismjs-dark .token.prolog,.token.comment{color:#997f66}.prismjs-dark .token.namespace,.prismjs-dark .token.punctuation{opacity:.7}.prismjs-dark .token.boolean,.prismjs-dark .token.constant,.prismjs-dark .token.number,.prismjs-dark .token.property,.prismjs-dark .token.symbol,.prismjs-dark .token.tag{color:#d1939e}.prismjs-dark .token.attr-name,.prismjs-dark .token.builtin,.prismjs-dark .token.char,.prismjs-dark .token.inserted,.prismjs-dark .token.selector,.prismjs-dark .token.string{color:#bce051}.prismjs-dark .language-css .token.string,.prismjs-dark .style .token.string,.prismjs-dark .token.entity,.prismjs-dark .token.operator,.prismjs-dark .token.url,.token.variable{color:#f4b73d}.prismjs-dark .token.atrule,.prismjs-dark .token.attr-value,.prismjs-dark .token.keyword{color:#d1939e}.prismjs-dark .token.important,.prismjs-dark .token.regex{color:#e90}.prismjs-dark .token.bold,.prismjs-dark .token.important{font-weight:700}.prismjs-dark .token.italic{font-style:italic}.prismjs-dark .token.entity{cursor:help}.prismjs-dark .token.deleted{color:red}.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{background:0 0;color:#000;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px #fff;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-default code[class*=language-] ::-moz-selection,.prismjs-default code[class*=language-]::-moz-selection,.prismjs-default pre[class*=language-] ::-moz-selection,.prismjs-default pre[class*=language-]::-moz-selection{background:#b3d4fc;text-shadow:none}.prismjs-default code[class*=language-] ::selection,.prismjs-default code[class*=language-]::selection,.prismjs-default pre[class*=language-] ::selection,.prismjs-default pre[class*=language-]::selection{background:#b3d4fc;text-shadow:none}@media print{.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{text-shadow:none}}.prismjs-default pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-default :not(pre)>code[class*=language-],.prismjs-default pre[class*=language-]{background:#f5f2f0}.prismjs-default :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-default .token.cdata,.prismjs-default .token.comment,.prismjs-default .token.doctype,.prismjs-default .token.prolog{color:#708090}.prismjs-default .token.punctuation{color:#999}.prismjs-default .token.namespace{opacity:.7}.prismjs-default .token.boolean,.prismjs-default .token.constant,.prismjs-default .token.deleted,.prismjs-default .token.number,.prismjs-default .token.property,.prismjs-default .token.symbol,.prismjs-default .token.tag{color:#905}.prismjs-default .token.attr-name,.prismjs-default .token.builtin,.prismjs-default .token.char,.prismjs-default .token.inserted,.prismjs-default .token.selector,.prismjs-default .token.string{color:#690}.prismjs-default .language-css .token.string,.prismjs-default .style .token.string,.prismjs-default .token.entity,.prismjs-default .token.operator,.prismjs-default .token.url{background:hsla(0,0%,100%,.5);color:#9a6e3a}.prismjs-default .token.atrule,.prismjs-default .token.attr-value,.prismjs-default .token.keyword{color:#07a}.prismjs-default .token.class-name,.prismjs-default .token.function{color:#dd4a68}.prismjs-default .token.important,.prismjs-default .token.regex,.prismjs-default .token.variable{color:#e90}.prismjs-default .token.bold,.prismjs-default .token.important{font-weight:700}.prismjs-default .token.italic{font-style:italic}.prismjs-default .token.entity{cursor:help}.prismjs-okaidia code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:0 0;color:#f8f8f2;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px rgba(0,0,0,.3);white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-okaidia pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-okaidia :not(pre)>code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:#272822}.prismjs-okaidia :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-okaidia .token.cdata,.prismjs-okaidia .token.comment,.prismjs-okaidia .token.doctype,.prismjs-okaidia .token.prolog{color:#8292a2}.prismjs-okaidia .token.punctuation{color:#f8f8f2}.prismjs-okaidia .token.namespace{opacity:.7}.prismjs-okaidia .token.constant,.prismjs-okaidia .token.deleted,.prismjs-okaidia .token.property,.prismjs-okaidia .token.symbol,.prismjs-okaidia .token.tag{color:#f92672}.prismjs-okaidia .token.boolean,.prismjs-okaidia .token.number{color:#ae81ff}.prismjs-okaidia .token.attr-name,.prismjs-okaidia .token.builtin,.prismjs-okaidia .token.char,.prismjs-okaidia .token.inserted,.prismjs-okaidia .token.selector,.prismjs-okaidia .token.string{color:#a6e22e}.prismjs-okaidia .language-css .token.string,.prismjs-okaidia .style .token.string,.prismjs-okaidia .token.entity,.prismjs-okaidia .token.operator,.prismjs-okaidia .token.url,.prismjs-okaidia .token.variable{color:#f8f8f2}.prismjs-okaidia .token.atrule,.prismjs-okaidia .token.attr-value,.prismjs-okaidia .token.class-name,.prismjs-okaidia .token.function{color:#e6db74}.prismjs-okaidia .token.keyword{color:#66d9ef}.prismjs-okaidia .token.important,.prismjs-okaidia .token.regex{color:#fd971f}.prismjs-okaidia .token.bold,.prismjs-okaidia .token.important{font-weight:700}.prismjs-okaidia .token.italic{font-style:italic}.prismjs-okaidia .token.entity{cursor:help}.prismjs-solarizedlight code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{color:#657b83;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-solarizedlight code[class*=language-] ::-moz-selection,.prismjs-solarizedlight code[class*=language-]::-moz-selection,.prismjs-solarizedlight pre[class*=language-] ::-moz-selection,.prismjs-solarizedlight pre[class*=language-]::-moz-selection{background:#073642}.prismjs-solarizedlight code[class*=language-] ::selection,.prismjs-solarizedlight code[class*=language-]::selection,.prismjs-solarizedlight pre[class*=language-] ::selection,.prismjs-solarizedlight pre[class*=language-]::selection{background:#073642}.prismjs-solarizedlight pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-solarizedlight :not(pre)>code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{background-color:#fdf6e3}.prismjs-solarizedlight :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em}.prismjs-solarizedlight .token.cdata,.prismjs-solarizedlight .token.comment,.prismjs-solarizedlight .token.doctype,.prismjs-solarizedlight .token.prolog{color:#93a1a1}.prismjs-solarizedlight .token.punctuation{color:#586e75}.prismjs-solarizedlight .token.namespace{opacity:.7}.prismjs-solarizedlight .token.boolean,.prismjs-solarizedlight .token.constant,.prismjs-solarizedlight .token.deleted,.prismjs-solarizedlight .token.number,.prismjs-solarizedlight .token.property,.prismjs-solarizedlight .token.symbol,.token.tag{color:#268bd2}.prismjs-solarizedlight .token.attr-name,.prismjs-solarizedlight .token.builtin,.prismjs-solarizedlight .token.char,.prismjs-solarizedlight .token.inserted,.prismjs-solarizedlight .token.selector,.prismjs-solarizedlight .token.string,.prismjs-solarizedlight .token.url{color:#2aa198}.prismjs-solarizedlight .token.entity{background:#eee8d5;color:#657b83}.prismjs-solarizedlight .token.atrule,.prismjs-solarizedlight .token.attr-value,.prismjs-solarizedlight .token.keyword{color:#859900}.prismjs-solarizedlight .token.class-name,.prismjs-solarizedlight .token.function{color:#b58900}.prismjs-solarizedlight .token.important,.prismjs-solarizedlight .token.regex,.prismjs-solarizedlight .token.variable{color:#cb4b16}.prismjs-solarizedlight .token.bold,.prismjs-solarizedlight .token.important{font-weight:700}.prismjs-solarizedlight .token.italic{font-style:italic}.prismjs-solarizedlight .token.entity{cursor:help}.prismjs-tomorrow code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:0 0;color:#ccc;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-tomorrow pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-tomorrow :not(pre)>code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:#2d2d2d}.prismjs-tomorrow :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-tomorrow .token.block-comment,.prismjs-tomorrow .token.cdata,.prismjs-tomorrow .token.comment,.prismjs-tomorrow .token.doctype,.prismjs-tomorrow .token.prolog{color:#999}.prismjs-tomorrow .token.punctuation{color:#ccc}.prismjs-tomorrow .token.attr-name,.prismjs-tomorrow .token.deleted,.prismjs-tomorrow .token.namespace,.prismjs-tomorrow .token.tag{color:#e2777a}.prismjs-tomorrow .token.function-name{color:#6196cc}.prismjs-tomorrow .token.boolean,.prismjs-tomorrow .token.function,.prismjs-tomorrow .token.number{color:#f08d49}.prismjs-tomorrow .token.class-name,.prismjs-tomorrow .token.constant,.prismjs-tomorrow .token.property,.prismjs-tomorrow .token.symbol{color:#f8c555}.prismjs-tomorrow .token.atrule,.prismjs-tomorrow .token.builtin,.prismjs-tomorrow .token.important,.prismjs-tomorrow .token.keyword,.prismjs-tomorrow .token.selector{color:#cc99cd}.prismjs-tomorrow .token.attr-value,.prismjs-tomorrow .token.char,.prismjs-tomorrow .token.regex,.prismjs-tomorrow .token.string,.prismjs-tomorrow .token.variable{color:#7ec699}.prismjs-tomorrow .token.entity,.prismjs-tomorrow .token.operator,.prismjs-tomorrow .token.url{color:#67cdcc}.prismjs-tomorrow .token.bold,.prismjs-tomorrow .token.important{font-weight:700}.prismjs-tomorrow .token.italic{font-style:italic}.prismjs-tomorrow .token.entity{cursor:help}.prismjs-tomorrow .token.inserted{color:green}.prismjs-twilight code[class*=language-],.prismjs-twilight pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-twilight :not(pre)>code[class*=language-],.prismjs-twilight pre[class*=language-]{background:#141414}.prismjs-twilight pre[class*=language-]{border:.3em solid #545454;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-twilight pre[class*=language-]::-moz-selection{background:#27292a}.prismjs-twilight pre[class*=language-]::selection{background:#27292a}.prismjs-twilight code[class*=language-] ::-moz-selection,.prismjs-twilight code[class*=language-]::-moz-selection,.prismjs-twilight pre[class*=language-] ::-moz-selection,.prismjs-twilight pre[class*=language-]::-moz-selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight code[class*=language-] ::selection,.prismjs-twilight code[class*=language-]::selection,.prismjs-twilight pre[class*=language-] ::selection,.prismjs-twilight pre[class*=language-]::selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight :not(pre)>code[class*=language-]{border:.13em solid #545454;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-twilight .token.cdata,.prismjs-twilight .token.comment,.prismjs-twilight .token.doctype,.prismjs-twilight .token.prolog{color:#777}.prismjs-twilight .token.namespace,.prismjs-twilight .token.punctuation{opacity:.7}.prismjs-twilight .token.boolean,.prismjs-twilight .token.deleted,.prismjs-twilight .token.number,.prismjs-twilight .token.tag{color:#ce6849}.prismjs-twilight .token.builtin,.prismjs-twilight .token.constant,.prismjs-twilight .token.keyword,.prismjs-twilight .token.property,.prismjs-twilight .token.selector,.prismjs-twilight .token.symbol{color:#f9ed99}.prismjs-twilight .language-css .token.string,.prismjs-twilight .style .token.string,.prismjs-twilight .token.attr-name,.prismjs-twilight .token.attr-value,.prismjs-twilight .token.char,.prismjs-twilight .token.entity,.prismjs-twilight .token.inserted,.prismjs-twilight .token.operator,.prismjs-twilight .token.string,.prismjs-twilight .token.url,.prismjs-twilight .token.variable{color:#909e6a}.prismjs-twilight .token.atrule{color:#7385a5}.prismjs-twilight .token.important,.prismjs-twilight .token.regex{color:#e8c062}.prismjs-twilight .token.bold,.prismjs-twilight .token.important{font-weight:700}.prismjs-twilight .token.italic{font-style:italic}.prismjs-twilight .token.entity{cursor:help}.prismjs-twilight pre[data-line]{padding:1em;position:relative}.prismjs-twilight .language-markup .token.attr-name,.prismjs-twilight .language-markup .token.punctuation,.prismjs-twilight .language-markup .token.tag{color:#ac885c}.prismjs-twilight .token{position:relative;z-index:1}.prismjs-twilight .line-highlight{background:rgba(84,84,84,.25);background:linear-gradient(90deg,rgba(84,84,84,.1) 70%,rgba(84,84,84,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;left:0;line-height:inherit;margin-top:.75em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre;z-index:0}.prismjs-twilight .line-highlight:before,.prismjs-twilight .line-highlight[data-end]:after{background-color:#8693a6;border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.prismjs-twilight .line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.copy-to-clipboard div.code-toolbar{position:relative}.copy-to-clipboard div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out}.copy-to-clipboard div.code-toolbar:hover>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar:focus-within>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar>.toolbar .toolbar-item{display:inline-block}.copy-to-clipboard div.code-toolbar>.toolbar a{cursor:pointer}.copy-to-clipboard div.code-toolbar>.toolbar button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.copy-to-clipboard div.code-toolbar>.toolbar a,.copy-to-clipboard div.code-toolbar>.toolbar button,.copy-to-clipboard div.code-toolbar>.toolbar span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}.copy-to-clipboard div.code-toolbar>.toolbar a:focus,div.code-toolbar>.toolbar a:hover,div.code-toolbar>.toolbar button:focus,div.code-toolbar>.toolbar button:hover,div.code-toolbar>.toolbar span:focus,div.code-toolbar>.toolbar span:hover{color:inherit;text-decoration:none}:not(.copy-to-clipboard)>div.code-toolbar>.toolbar{display:none}.word-wrap code[class*=language-],.word-wrap pre[class*=language-]{white-space:pre-wrap!important}.elementor-widget-code-highlight .elementor-widget-container,.elementor-widget-code-highlight:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-widget-code-highlight pre{direction:ltr}.prismjs-twilight pre:not([data-line=""]):not(.line-numbers){padding:.8em 0 1em 2em}.prismjs-dark pre:not([data-line=""]):not(.line-numbers),.prismjs-default pre:not([data-line=""]):not(.line-numbers),.prismjs-okaidia pre:not([data-line=""]):not(.line-numbers),.prismjs-solarizedlight pre:not([data-line=""]):not(.line-numbers),.prismjs-tomorrow pre:not([data-line=""]):not(.line-numbers){padding:1em 0 1em 2em}pre[data-line]{padding:1em 0 1em 3em;position:relative}.line-highlight{background:hsla(24,20%,50%,.08);background:linear-gradient(90deg,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));left:0;line-height:inherit;margin-top:1em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{background-color:hsla(24,20%,50%,.4);border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:hsla(0,0%,50%,.2)}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right} \ No newline at end of file diff --git a/assets/css/templates/widget-flip-box-rtl.min.css b/assets/css/templates/widget-flip-box-rtl.min.css new file mode 100644 index 00000000..afd2fde1 --- /dev/null +++ b/assets/css/templates/widget-flip-box-rtl.min.css @@ -0,0 +1 @@ +.elementor-flip-box{height:280px;perspective:1000px;position:relative;transform-style:preserve-3d}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-flip-box{cursor:pointer}}.elementor-flip-box__front{background-color:#1abc9c}.elementor-flip-box__back{background-color:#4054b2;display:block}.elementor-flip-box__layer{height:100%;position:absolute;transition:all .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.elementor-flip-box__layer{transition-duration:0s}}.elementor-flip-box__layer__overlay{align-items:stretch;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:center;padding:35px;text-align:center;width:100%}.elementor-flip-box__layer__title{font-size:21px}.elementor-flip-box__layer__description{font-size:14px}.elementor-flip-box__layer__description:not(:last-child),.elementor-flip-box__layer__title:not(:last-child){margin:0 0 20px;padding:0}.elementor-flip-box__layer__title{font-weight:600;line-height:1}.elementor-flip-box,.elementor-flip-box .elementor-view-framed,.elementor-flip-box .elementor-view-stacked{--e-flip-box-view-framed-stacked-icon-color:#fff}.elementor-flip-box .elementor-icon,.elementor-flip-box .elementor-view-framed .elementor-icon,.elementor-flip-box .elementor-view-stacked .elementor-icon{color:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-icon svg,.elementor-flip-box .elementor-view-framed .elementor-icon svg,.elementor-flip-box .elementor-view-stacked .elementor-icon svg{fill:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-view-framed .elementor-icon{border-color:#fff}.elementor-flip-box .elementor-view-stacked .elementor-icon{background-color:rgba(0,0,0,.5)}.elementor-flip-box__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-flip-box__button.elementor-button:focus-visible,.elementor-flip-box__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-flip-box__image{display:inline-block;margin:0 0 20px;width:100%}.elementor-flip-box__image img{width:50%}.elementor-flip-box .elementor-icon-wrapper{margin-bottom:20px}.elementor-flip-box--3d .elementor-flip-box__layer__inner{transform:translateZ(90px) scale(.91)}.elementor-flip-box--3d .elementor-flip-box__layer__overlay{transform:translateZ(.1px);transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box{perspective:1000px;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__layer{backface-visibility:hidden;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__front{transform:none;z-index:1}.elementor-flip-box--effect-flip .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-flip .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box__back{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box__back{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box__back{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box__back{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-push .elementor-flip-box__front{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push .elementor-flip-box,.elementor-flip-box--effect-slide .elementor-flip-box{overflow:hidden}.elementor-flip-box--effect-push .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-push .elementor-flip-box:hover .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-right .elementor-flip-box__back{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-left .elementor-flip-box__back{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-up .elementor-flip-box__back{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-down .elementor-flip-box__back{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{opacity:1;transform:scale(1);transition:transform .7s,opacity .35s,width .1ms;width:100%;z-index:1}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{transition-duration:0s}}.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{opacity:0;transform:scale(.7);transition:transform .8s,opacity .7s .1s,width .1ms .7s;width:0}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{opacity:0;transform:scale(.7);transition:transform .7s,opacity .5s .2s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{opacity:1;transform:scale(1);transition:transform .7s,opacity .5s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{transition-duration:0s}}.elementor-flip-box--effect-fade .elementor-flip-box .elementor-flip-box__back{opacity:0}.elementor-flip-box--effect-fade .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-fade .elementor-flip-box:hover .elementor-flip-box__back{opacity:1}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__front,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__front{display:none}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__back,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__back{opacity:1;transform:none}.e-con-inner>.elementor-widget-flip-box,.e-con>.elementor-widget-flip-box{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/templates/widget-flip-box.min.css b/assets/css/templates/widget-flip-box.min.css new file mode 100644 index 00000000..afd2fde1 --- /dev/null +++ b/assets/css/templates/widget-flip-box.min.css @@ -0,0 +1 @@ +.elementor-flip-box{height:280px;perspective:1000px;position:relative;transform-style:preserve-3d}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-flip-box{cursor:pointer}}.elementor-flip-box__front{background-color:#1abc9c}.elementor-flip-box__back{background-color:#4054b2;display:block}.elementor-flip-box__layer{height:100%;position:absolute;transition:all .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.elementor-flip-box__layer{transition-duration:0s}}.elementor-flip-box__layer__overlay{align-items:stretch;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:center;padding:35px;text-align:center;width:100%}.elementor-flip-box__layer__title{font-size:21px}.elementor-flip-box__layer__description{font-size:14px}.elementor-flip-box__layer__description:not(:last-child),.elementor-flip-box__layer__title:not(:last-child){margin:0 0 20px;padding:0}.elementor-flip-box__layer__title{font-weight:600;line-height:1}.elementor-flip-box,.elementor-flip-box .elementor-view-framed,.elementor-flip-box .elementor-view-stacked{--e-flip-box-view-framed-stacked-icon-color:#fff}.elementor-flip-box .elementor-icon,.elementor-flip-box .elementor-view-framed .elementor-icon,.elementor-flip-box .elementor-view-stacked .elementor-icon{color:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-icon svg,.elementor-flip-box .elementor-view-framed .elementor-icon svg,.elementor-flip-box .elementor-view-stacked .elementor-icon svg{fill:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-view-framed .elementor-icon{border-color:#fff}.elementor-flip-box .elementor-view-stacked .elementor-icon{background-color:rgba(0,0,0,.5)}.elementor-flip-box__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-flip-box__button.elementor-button:focus-visible,.elementor-flip-box__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-flip-box__image{display:inline-block;margin:0 0 20px;width:100%}.elementor-flip-box__image img{width:50%}.elementor-flip-box .elementor-icon-wrapper{margin-bottom:20px}.elementor-flip-box--3d .elementor-flip-box__layer__inner{transform:translateZ(90px) scale(.91)}.elementor-flip-box--3d .elementor-flip-box__layer__overlay{transform:translateZ(.1px);transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box{perspective:1000px;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__layer{backface-visibility:hidden;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__front{transform:none;z-index:1}.elementor-flip-box--effect-flip .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-flip .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box__back{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box__back{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box__back{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box__back{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-push .elementor-flip-box__front{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push .elementor-flip-box,.elementor-flip-box--effect-slide .elementor-flip-box{overflow:hidden}.elementor-flip-box--effect-push .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-push .elementor-flip-box:hover .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-right .elementor-flip-box__back{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-left .elementor-flip-box__back{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-up .elementor-flip-box__back{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-down .elementor-flip-box__back{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{opacity:1;transform:scale(1);transition:transform .7s,opacity .35s,width .1ms;width:100%;z-index:1}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{transition-duration:0s}}.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{opacity:0;transform:scale(.7);transition:transform .8s,opacity .7s .1s,width .1ms .7s;width:0}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{opacity:0;transform:scale(.7);transition:transform .7s,opacity .5s .2s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{opacity:1;transform:scale(1);transition:transform .7s,opacity .5s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{transition-duration:0s}}.elementor-flip-box--effect-fade .elementor-flip-box .elementor-flip-box__back{opacity:0}.elementor-flip-box--effect-fade .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-fade .elementor-flip-box:hover .elementor-flip-box__back{opacity:1}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__front,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__front{display:none}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__back,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__back{opacity:1;transform:none}.e-con-inner>.elementor-widget-flip-box,.e-con>.elementor-widget-flip-box{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/templates/widget-loop-grid-rtl.min.css b/assets/css/templates/widget-loop-grid-rtl.min.css new file mode 100644 index 00000000..838e9c7d --- /dev/null +++ b/assets/css/templates/widget-loop-grid-rtl.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.elementor-widget-loop-grid{scroll-margin-top:var(--auto-scroll-offset,initial)}.elementor-widget-loop-grid-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-widget-loop-grid-widescreen-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-widget-loop-grid-laptop-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-widget-loop-grid-tablet_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-loop-grid-tablet-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-widget-loop-grid-mobile_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-loop-grid-mobile-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}.elementor-widget-loop-grid .elementor-grid{grid-column-gap:var(--grid-column-gap,30px);grid-row-gap:var(--grid-row-gap,30px)}.elementor-widget-loop-grid.e-loading-overlay{animation:loadingOpacityAnimation 1s infinite alternate}.elementor-widget-loop-grid .e-loop__load-more{text-align:var(--load-more-button-align)}.elementor-widget-loop-grid .e-loop__load-more .elementor-button{width:var(--load-more-button-width)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-loop-grid.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-loop-grid.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative}.elementor-widget-loop-grid .e-loop-nothing-found-message{color:var(--e-loop-nothing-found-message-color,#1f2124);padding-block-end:var(--e-loop-nothing-found-message-space-from-bottom,30px);padding-block-start:var(--e-loop-nothing-found-message-space-from-top,30px);text-align:var(--e-loop-nothing-found-message-align,center)}.elementor-loop-container.elementor-posts-masonry{align-items:flex-start}.elementor-loop-container:not(.elementor-posts-masonry){align-items:stretch}@keyframes loadingOpacityAnimation{0%,to{opacity:1}50%{opacity:.6}} \ No newline at end of file diff --git a/assets/css/templates/widget-loop-grid.min.css b/assets/css/templates/widget-loop-grid.min.css new file mode 100644 index 00000000..838e9c7d --- /dev/null +++ b/assets/css/templates/widget-loop-grid.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.elementor-widget-loop-grid{scroll-margin-top:var(--auto-scroll-offset,initial)}.elementor-widget-loop-grid-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-widget-loop-grid-widescreen-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-widget-loop-grid-laptop-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-widget-loop-grid-tablet_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-loop-grid-tablet-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-widget-loop-grid-mobile_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-loop-grid-mobile-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}.elementor-widget-loop-grid .elementor-grid{grid-column-gap:var(--grid-column-gap,30px);grid-row-gap:var(--grid-row-gap,30px)}.elementor-widget-loop-grid.e-loading-overlay{animation:loadingOpacityAnimation 1s infinite alternate}.elementor-widget-loop-grid .e-loop__load-more{text-align:var(--load-more-button-align)}.elementor-widget-loop-grid .e-loop__load-more .elementor-button{width:var(--load-more-button-width)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-loop-grid.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-loop-grid.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative}.elementor-widget-loop-grid .e-loop-nothing-found-message{color:var(--e-loop-nothing-found-message-color,#1f2124);padding-block-end:var(--e-loop-nothing-found-message-space-from-bottom,30px);padding-block-start:var(--e-loop-nothing-found-message-space-from-top,30px);text-align:var(--e-loop-nothing-found-message-align,center)}.elementor-loop-container.elementor-posts-masonry{align-items:flex-start}.elementor-loop-container:not(.elementor-posts-masonry){align-items:stretch}@keyframes loadingOpacityAnimation{0%,to{opacity:1}50%{opacity:.6}} \ No newline at end of file diff --git a/assets/css/templates/widget-mega-menu-rtl.min.css b/assets/css/templates/widget-mega-menu-rtl.min.css new file mode 100644 index 00000000..6d3e548a --- /dev/null +++ b/assets/css/templates/widget-mega-menu-rtl.min.css @@ -0,0 +1 @@ +.elementor-widget-n-menu{--n-menu-direction:column;--n-menu-wrapper-display:flex;--n-menu-heading-justify-content:initial;--n-menu-title-color-normal:#1f2124;--n-menu-title-color-active:#58d0f5;--n-menu-icon-color:var(--n-menu-title-color-normal);--n-menu-icon-color-active:var(--n-menu-title-color-active);--n-menu-icon-color-hover:var(--n-menu-title-color-hover);--n-menu-title-normal-color-dropdown:var(--n-menu-title-color-normal);--n-menu-title-active-color-dropdown:var(--n-menu-title-color-active);--n-menu-title-hover-color-fallback:#1f2124;--n-menu-title-font-size:1rem;--n-menu-title-justify-content:initial;--n-menu-title-flex-grow:initial;--n-menu-title-justify-content-mobile:initial;--n-menu-title-space-between:0px;--n-menu-title-distance-from-content:0px;--n-menu-title-color-hover:#1f2124;--n-menu-title-padding:0.5rem 1rem;--n-menu-title-transition:0.3s;--n-menu-title-line-height:1.5;--n-menu-title-order:initial;--n-menu-title-direction:initial;--n-menu-title-align-items:center;--n-menu-toggle-align:center;--n-menu-toggle-icon-wrapper-animation-duration:500ms;--n-menu-toggle-icon-hover-duration:500ms;--n-menu-toggle-icon-size:20px;--n-menu-toggle-icon-color:#1f2124;--n-menu-toggle-icon-color-hover:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-color-active:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-border-radius:initial;--n-menu-toggle-icon-padding:initial;--n-menu-toggle-icon-distance-from-dropdown:0px;--n-menu-icon-align-items:center;--n-menu-icon-order:initial;--n-menu-icon-gap:5px;--n-menu-dropdown-icon-gap:5px;--n-menu-dropdown-indicator-size:initial;--n-menu-dropdown-indicator-rotate:initial;--n-menu-dropdown-indicator-space:initial;--n-menu-dropdown-indicator-color-normal:initial;--n-menu-dropdown-indicator-color-hover:initial;--n-menu-dropdown-indicator-color-active:initial;--n-menu-dropdown-content-max-width:initial;--n-menu-dropdown-content-box-border-color:#fff;--n-menu-dropdown-content-box-border-inline-start-width:medium;--n-menu-dropdown-content-box-border-block-end-width:medium;--n-menu-dropdown-content-box-border-block-start-width:medium;--n-menu-dropdown-content-box-border-inline-end-width:medium;--n-menu-dropdown-content-box-border-style:none;--n-menu-dropdown-headings-height:0px;--n-menu-divider-border-width:var(--n-menu-divider-width,2px);--n-menu-open-animation-duration:500ms;--n-menu-heading-overflow-x:initial;--n-menu-heading-wrap:wrap;--stretch-width:100%;--stretch-left:initial;--stretch-right:initial}.elementor-widget-n-menu .e-n-menu{display:flex;flex-direction:column;position:relative}.elementor-widget-n-menu .e-n-menu-wrapper{display:var(--n-menu-wrapper-display);flex-direction:column}.elementor-widget-n-menu .e-n-menu-heading{display:flex;flex-direction:row;flex-wrap:var(--n-menu-heading-wrap);justify-content:var(--n-menu-heading-justify-content);margin:initial;overflow-x:var(--n-menu-heading-overflow-x);padding:initial;row-gap:var(--n-menu-title-space-between);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-n-menu .e-n-menu-heading::-webkit-scrollbar{display:none}.elementor-widget-n-menu .e-n-menu-heading.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active{position:relative}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-n-menu .e-n-menu-heading>.e-con,.elementor-widget-n-menu .e-n-menu-heading>.e-n-menu-item>.e-con{display:none}.elementor-widget-n-menu .e-n-menu-item{display:flex;list-style:none;margin-block:initial;padding-block:initial}.elementor-widget-n-menu .e-n-menu-item .e-n-menu-title{position:relative}.elementor-widget-n-menu .e-n-menu-item:not(:last-of-type) .e-n-menu-title:after{align-self:center;border-color:var(--n-menu-divider-color,#000);border-inline-start-style:var(--n-menu-divider-style,solid);border-inline-start-width:var(--n-menu-divider-border-width);content:var(--n-menu-divider-content,none);height:var(--n-menu-divider-height,35%);inset-inline-end:calc(var(--n-menu-title-space-between) / 2 * -1 - var(--n-menu-divider-border-width) / 2);position:absolute}.elementor-widget-n-menu .e-n-menu-content{background-color:transparent;display:flex;flex-direction:column;min-width:0;z-index:2147483620}.elementor-widget-n-menu .e-n-menu-content>.e-con{animation-duration:var(--n-menu-open-animation-duration);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}:where(.elementor-widget-n-menu .e-n-menu-content>.e-con){background-color:#fff}.elementor-widget-n-menu .e-n-menu-content>.e-con:not(.e-active){display:none}.elementor-widget-n-menu .e-n-menu-title{align-items:center;border:#fff;color:var(--n-menu-title-color-normal);display:flex;flex-direction:row;flex-grow:var(--n-menu-title-flex-grow);font-weight:500;gap:var(--n-menu-dropdown-indicator-space);justify-content:var(--n-menu-title-justify-content);margin:initial;padding:var(--n-menu-title-padding);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.elementor-widget-n-menu .e-n-menu-title.e-click,.elementor-widget-n-menu .e-n-menu-title.e-click *{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container{align-items:var(--n-menu-title-align-items);align-self:var(--n-menu-icon-align-items);display:flex;flex-direction:var(--n-menu-title-direction);gap:var(--n-menu-icon-gap);justify-content:var(--n-menu-title-justify-content)}.elementor-widget-n-menu .e-n-menu-title-container.e-link{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link),.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link) *{cursor:default}.elementor-widget-n-menu .e-n-menu-title-text{align-items:center;display:flex;font-size:var(--n-menu-title-font-size);line-height:var(--n-menu-title-line-height);transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon{align-items:center;display:flex;flex-direction:column;order:var(--n-menu-icon-order)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span{align-items:center;display:flex;justify-content:center;transition:transform 0s}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span i{font-size:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span svg{fill:var(--n-menu-title-color-normal);height:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-icon-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon{align-self:var(--n-menu-icon-align-items);background-color:initial;border:initial;color:inherit;display:flex;flex-direction:column;height:calc(var(--n-menu-title-font-size) * var(--n-menu-title-line-height));justify-content:center;margin-inline-start:var(--n-menu-dropdown-icon-gap);padding:initial;position:relative;text-align:center;transform:var(--n-menu-dropdown-indicator-rotate);transition:all var(--n-menu-title-transition);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span i{font-size:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span svg{height:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-opened{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-closed{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-closed{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-opened{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-color-normal)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon i{color:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon svg{fill:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current) .icon-active{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current span>svg{fill:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu-title.e-current a{color:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .icon-inactive{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>i{color:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>svg{fill:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-title-container:not(.e-link){cursor:default}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) svg{fill:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) i{color:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current),.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) a{color:var(--n-menu-title-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon i{color:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon svg{fill:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-toggle{align-self:var(--n-menu-toggle-align);background-color:initial;border:initial;color:inherit;display:none;padding:initial;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1000}.elementor-widget-n-menu .e-n-menu-toggle:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-toggle i{color:var(--n-menu-toggle-icon-color);font-size:var(--n-menu-toggle-icon-size);transition:all var(--n-menu-toggle-icon-hover-duration)}.elementor-widget-n-menu .e-n-menu-toggle svg{fill:var(--n-menu-toggle-icon-color);height:auto;transition:all var(--n-menu-toggle-icon-hover-duration);width:var(--n-menu-toggle-icon-size)}.elementor-widget-n-menu .e-n-menu-toggle span{align-items:center;border-radius:var(--n-menu-toggle-icon-border-radius);display:flex;justify-content:center;padding:var(--n-menu-toggle-icon-padding);text-align:center}.elementor-widget-n-menu .e-n-menu-toggle span.e-close{height:100%;inset:0;opacity:0;position:absolute;width:100%}.elementor-widget-n-menu .e-n-menu-toggle span.e-close svg{height:100%;-o-object-fit:contain;object-fit:contain}.elementor-widget-n-menu .e-n-menu-toggle [class^=elementor-animation-]{animation-duration:var(--n-menu-toggle-icon-wrapper-animation-duration);transition-duration:var(--n-menu-toggle-icon-wrapper-animation-duration)}.elementor-widget-n-menu .e-n-menu-toggle:hover i{color:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle:hover svg{fill:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-open{opacity:0}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-close{opacity:1}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] i{color:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] svg{fill:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-item:not(:last-child){margin-inline-end:var(--n-menu-title-space-between)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-content{left:var(--stretch-left);position:absolute;right:var(--stretch-right);width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]):not(.content-above) .e-active.e-n-menu-content{padding-block-start:var(--n-menu-title-distance-from-content);top:100%}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]).content-above .e-active.e-n-menu-content{bottom:100%;padding-block-end:var(--n-menu-title-distance-from-content)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown]{gap:0}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-wrapper{animation:hide-scroll .3s backwards;background-color:transparent;border-block-end:var(--n-menu-dropdown-content-box-border-width-block-end);border-block-start:var(--n-menu-dropdown-content-box-border-width-block-start);border-inline-end:var(--n-menu-dropdown-content-box-border-width-inline-end);border-inline-start:var(--n-menu-dropdown-content-box-border-width-inline-start);border-color:var(--n-menu-dropdown-content-box-border-color);border-radius:var(--n-menu-dropdown-content-box-border-radius);border-style:var(--n-menu-dropdown-content-box-border-style);box-shadow:var(--n-menu-dropdown-content-box-shadow-horizontal) var(--n-menu-dropdown-content-box-shadow-vertical) var(--n-menu-dropdown-content-box-shadow-blur) var(--n-menu-dropdown-content-box-shadow-spread) var(--n-menu-dropdown-content-box-shadow-color) var(--n-menu-dropdown-content-box-shadow-position, );flex-direction:column;left:var(--stretch-left);margin-block-start:var(--n-menu-toggle-icon-distance-from-dropdown);max-height:var(--n-menu-dropdown-content-box-height);min-width:0;overflow-x:hidden;overflow-y:auto;position:absolute;right:var(--stretch-right);top:100%;transition:max-height .3s;width:var(--stretch-width);z-index:2147483640}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-item{display:flex;flex-direction:column;width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title{background-color:#fff;flex-wrap:wrap;justify-content:var(--n-menu-title-justify-content-mobile);white-space:normal;width:auto}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-normal-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current a{color:var(--n-menu-title-active-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content{overflow:hidden;width:var(--stretch-width);--n-menu-dropdown-content-max-width:initial}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con{margin-block-start:var(--n-menu-title-distance-from-content);width:var(--width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con .elementor-empty-view{min-width:auto;width:100%}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con-inner{max-width:var(--content-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-toggle[aria-expanded=true]+.e-n-menu-wrapper{--n-menu-wrapper-display:flex}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con){--width:fit-content}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con).e-empty{--empty-top-level-menu-content-container-min-width:400px;--width:var(--empty-top-level-menu-content-container-min-width)}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con) .e-con.e-empty{--nested-containers-min-width-for-dropzone:150px;min-width:var(--nested-containers-min-width-for-dropzone)}.elementor-widget-n-menu.elementor-loading{pointer-events:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown .e-n-menu-toggle{display:flex}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop .e-n-menu-toggle{display:flex}}@keyframes hide-scroll{0%,to{overflow:hidden}}.e-con-inner>.elementor-widget-n-menu,.e-con>.elementor-widget-n-menu{--flex-grow:var(--container-widget-flex-grow)}[data-core-v316-plus=true] .elementor-widget-n-menu .e-n-menu .e-n-menu-content>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/templates/widget-mega-menu.min.css b/assets/css/templates/widget-mega-menu.min.css new file mode 100644 index 00000000..6d3e548a --- /dev/null +++ b/assets/css/templates/widget-mega-menu.min.css @@ -0,0 +1 @@ +.elementor-widget-n-menu{--n-menu-direction:column;--n-menu-wrapper-display:flex;--n-menu-heading-justify-content:initial;--n-menu-title-color-normal:#1f2124;--n-menu-title-color-active:#58d0f5;--n-menu-icon-color:var(--n-menu-title-color-normal);--n-menu-icon-color-active:var(--n-menu-title-color-active);--n-menu-icon-color-hover:var(--n-menu-title-color-hover);--n-menu-title-normal-color-dropdown:var(--n-menu-title-color-normal);--n-menu-title-active-color-dropdown:var(--n-menu-title-color-active);--n-menu-title-hover-color-fallback:#1f2124;--n-menu-title-font-size:1rem;--n-menu-title-justify-content:initial;--n-menu-title-flex-grow:initial;--n-menu-title-justify-content-mobile:initial;--n-menu-title-space-between:0px;--n-menu-title-distance-from-content:0px;--n-menu-title-color-hover:#1f2124;--n-menu-title-padding:0.5rem 1rem;--n-menu-title-transition:0.3s;--n-menu-title-line-height:1.5;--n-menu-title-order:initial;--n-menu-title-direction:initial;--n-menu-title-align-items:center;--n-menu-toggle-align:center;--n-menu-toggle-icon-wrapper-animation-duration:500ms;--n-menu-toggle-icon-hover-duration:500ms;--n-menu-toggle-icon-size:20px;--n-menu-toggle-icon-color:#1f2124;--n-menu-toggle-icon-color-hover:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-color-active:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-border-radius:initial;--n-menu-toggle-icon-padding:initial;--n-menu-toggle-icon-distance-from-dropdown:0px;--n-menu-icon-align-items:center;--n-menu-icon-order:initial;--n-menu-icon-gap:5px;--n-menu-dropdown-icon-gap:5px;--n-menu-dropdown-indicator-size:initial;--n-menu-dropdown-indicator-rotate:initial;--n-menu-dropdown-indicator-space:initial;--n-menu-dropdown-indicator-color-normal:initial;--n-menu-dropdown-indicator-color-hover:initial;--n-menu-dropdown-indicator-color-active:initial;--n-menu-dropdown-content-max-width:initial;--n-menu-dropdown-content-box-border-color:#fff;--n-menu-dropdown-content-box-border-inline-start-width:medium;--n-menu-dropdown-content-box-border-block-end-width:medium;--n-menu-dropdown-content-box-border-block-start-width:medium;--n-menu-dropdown-content-box-border-inline-end-width:medium;--n-menu-dropdown-content-box-border-style:none;--n-menu-dropdown-headings-height:0px;--n-menu-divider-border-width:var(--n-menu-divider-width,2px);--n-menu-open-animation-duration:500ms;--n-menu-heading-overflow-x:initial;--n-menu-heading-wrap:wrap;--stretch-width:100%;--stretch-left:initial;--stretch-right:initial}.elementor-widget-n-menu .e-n-menu{display:flex;flex-direction:column;position:relative}.elementor-widget-n-menu .e-n-menu-wrapper{display:var(--n-menu-wrapper-display);flex-direction:column}.elementor-widget-n-menu .e-n-menu-heading{display:flex;flex-direction:row;flex-wrap:var(--n-menu-heading-wrap);justify-content:var(--n-menu-heading-justify-content);margin:initial;overflow-x:var(--n-menu-heading-overflow-x);padding:initial;row-gap:var(--n-menu-title-space-between);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-n-menu .e-n-menu-heading::-webkit-scrollbar{display:none}.elementor-widget-n-menu .e-n-menu-heading.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active{position:relative}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-n-menu .e-n-menu-heading>.e-con,.elementor-widget-n-menu .e-n-menu-heading>.e-n-menu-item>.e-con{display:none}.elementor-widget-n-menu .e-n-menu-item{display:flex;list-style:none;margin-block:initial;padding-block:initial}.elementor-widget-n-menu .e-n-menu-item .e-n-menu-title{position:relative}.elementor-widget-n-menu .e-n-menu-item:not(:last-of-type) .e-n-menu-title:after{align-self:center;border-color:var(--n-menu-divider-color,#000);border-inline-start-style:var(--n-menu-divider-style,solid);border-inline-start-width:var(--n-menu-divider-border-width);content:var(--n-menu-divider-content,none);height:var(--n-menu-divider-height,35%);inset-inline-end:calc(var(--n-menu-title-space-between) / 2 * -1 - var(--n-menu-divider-border-width) / 2);position:absolute}.elementor-widget-n-menu .e-n-menu-content{background-color:transparent;display:flex;flex-direction:column;min-width:0;z-index:2147483620}.elementor-widget-n-menu .e-n-menu-content>.e-con{animation-duration:var(--n-menu-open-animation-duration);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}:where(.elementor-widget-n-menu .e-n-menu-content>.e-con){background-color:#fff}.elementor-widget-n-menu .e-n-menu-content>.e-con:not(.e-active){display:none}.elementor-widget-n-menu .e-n-menu-title{align-items:center;border:#fff;color:var(--n-menu-title-color-normal);display:flex;flex-direction:row;flex-grow:var(--n-menu-title-flex-grow);font-weight:500;gap:var(--n-menu-dropdown-indicator-space);justify-content:var(--n-menu-title-justify-content);margin:initial;padding:var(--n-menu-title-padding);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.elementor-widget-n-menu .e-n-menu-title.e-click,.elementor-widget-n-menu .e-n-menu-title.e-click *{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container{align-items:var(--n-menu-title-align-items);align-self:var(--n-menu-icon-align-items);display:flex;flex-direction:var(--n-menu-title-direction);gap:var(--n-menu-icon-gap);justify-content:var(--n-menu-title-justify-content)}.elementor-widget-n-menu .e-n-menu-title-container.e-link{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link),.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link) *{cursor:default}.elementor-widget-n-menu .e-n-menu-title-text{align-items:center;display:flex;font-size:var(--n-menu-title-font-size);line-height:var(--n-menu-title-line-height);transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon{align-items:center;display:flex;flex-direction:column;order:var(--n-menu-icon-order)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span{align-items:center;display:flex;justify-content:center;transition:transform 0s}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span i{font-size:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span svg{fill:var(--n-menu-title-color-normal);height:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-icon-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon{align-self:var(--n-menu-icon-align-items);background-color:initial;border:initial;color:inherit;display:flex;flex-direction:column;height:calc(var(--n-menu-title-font-size) * var(--n-menu-title-line-height));justify-content:center;margin-inline-start:var(--n-menu-dropdown-icon-gap);padding:initial;position:relative;text-align:center;transform:var(--n-menu-dropdown-indicator-rotate);transition:all var(--n-menu-title-transition);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span i{font-size:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span svg{height:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-opened{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-closed{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-closed{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-opened{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-color-normal)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon i{color:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon svg{fill:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current) .icon-active{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current span>svg{fill:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu-title.e-current a{color:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .icon-inactive{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>i{color:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>svg{fill:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-title-container:not(.e-link){cursor:default}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) svg{fill:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) i{color:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current),.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) a{color:var(--n-menu-title-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon i{color:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon svg{fill:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-toggle{align-self:var(--n-menu-toggle-align);background-color:initial;border:initial;color:inherit;display:none;padding:initial;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1000}.elementor-widget-n-menu .e-n-menu-toggle:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-toggle i{color:var(--n-menu-toggle-icon-color);font-size:var(--n-menu-toggle-icon-size);transition:all var(--n-menu-toggle-icon-hover-duration)}.elementor-widget-n-menu .e-n-menu-toggle svg{fill:var(--n-menu-toggle-icon-color);height:auto;transition:all var(--n-menu-toggle-icon-hover-duration);width:var(--n-menu-toggle-icon-size)}.elementor-widget-n-menu .e-n-menu-toggle span{align-items:center;border-radius:var(--n-menu-toggle-icon-border-radius);display:flex;justify-content:center;padding:var(--n-menu-toggle-icon-padding);text-align:center}.elementor-widget-n-menu .e-n-menu-toggle span.e-close{height:100%;inset:0;opacity:0;position:absolute;width:100%}.elementor-widget-n-menu .e-n-menu-toggle span.e-close svg{height:100%;-o-object-fit:contain;object-fit:contain}.elementor-widget-n-menu .e-n-menu-toggle [class^=elementor-animation-]{animation-duration:var(--n-menu-toggle-icon-wrapper-animation-duration);transition-duration:var(--n-menu-toggle-icon-wrapper-animation-duration)}.elementor-widget-n-menu .e-n-menu-toggle:hover i{color:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle:hover svg{fill:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-open{opacity:0}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-close{opacity:1}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] i{color:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] svg{fill:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-item:not(:last-child){margin-inline-end:var(--n-menu-title-space-between)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-content{left:var(--stretch-left);position:absolute;right:var(--stretch-right);width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]):not(.content-above) .e-active.e-n-menu-content{padding-block-start:var(--n-menu-title-distance-from-content);top:100%}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]).content-above .e-active.e-n-menu-content{bottom:100%;padding-block-end:var(--n-menu-title-distance-from-content)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown]{gap:0}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-wrapper{animation:hide-scroll .3s backwards;background-color:transparent;border-block-end:var(--n-menu-dropdown-content-box-border-width-block-end);border-block-start:var(--n-menu-dropdown-content-box-border-width-block-start);border-inline-end:var(--n-menu-dropdown-content-box-border-width-inline-end);border-inline-start:var(--n-menu-dropdown-content-box-border-width-inline-start);border-color:var(--n-menu-dropdown-content-box-border-color);border-radius:var(--n-menu-dropdown-content-box-border-radius);border-style:var(--n-menu-dropdown-content-box-border-style);box-shadow:var(--n-menu-dropdown-content-box-shadow-horizontal) var(--n-menu-dropdown-content-box-shadow-vertical) var(--n-menu-dropdown-content-box-shadow-blur) var(--n-menu-dropdown-content-box-shadow-spread) var(--n-menu-dropdown-content-box-shadow-color) var(--n-menu-dropdown-content-box-shadow-position, );flex-direction:column;left:var(--stretch-left);margin-block-start:var(--n-menu-toggle-icon-distance-from-dropdown);max-height:var(--n-menu-dropdown-content-box-height);min-width:0;overflow-x:hidden;overflow-y:auto;position:absolute;right:var(--stretch-right);top:100%;transition:max-height .3s;width:var(--stretch-width);z-index:2147483640}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-item{display:flex;flex-direction:column;width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title{background-color:#fff;flex-wrap:wrap;justify-content:var(--n-menu-title-justify-content-mobile);white-space:normal;width:auto}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-normal-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current a{color:var(--n-menu-title-active-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content{overflow:hidden;width:var(--stretch-width);--n-menu-dropdown-content-max-width:initial}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con{margin-block-start:var(--n-menu-title-distance-from-content);width:var(--width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con .elementor-empty-view{min-width:auto;width:100%}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con-inner{max-width:var(--content-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-toggle[aria-expanded=true]+.e-n-menu-wrapper{--n-menu-wrapper-display:flex}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con){--width:fit-content}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con).e-empty{--empty-top-level-menu-content-container-min-width:400px;--width:var(--empty-top-level-menu-content-container-min-width)}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con) .e-con.e-empty{--nested-containers-min-width-for-dropzone:150px;min-width:var(--nested-containers-min-width-for-dropzone)}.elementor-widget-n-menu.elementor-loading{pointer-events:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown .e-n-menu-toggle{display:flex}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra .e-n-menu-toggle{display:flex}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop .e-n-menu-toggle{display:flex}}@keyframes hide-scroll{0%,to{overflow:hidden}}.e-con-inner>.elementor-widget-n-menu,.e-con>.elementor-widget-n-menu{--flex-grow:var(--container-widget-flex-grow)}[data-core-v316-plus=true] .elementor-widget-n-menu .e-n-menu .e-n-menu-content>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/templates/widget-nav-menu-rtl.min.css b/assets/css/templates/widget-nav-menu-rtl.min.css new file mode 100644 index 00000000..2a4f0c16 --- /dev/null +++ b/assets/css/templates/widget-nav-menu-rtl.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.site-main .menu-navigation-container{overflow:visible}.elementor-item:after,.elementor-item:before{display:block;position:absolute;transition:.3s;transition-timing-function:cubic-bezier(.58,.3,.005,1)}.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{opacity:0}.elementor-item-active:after,.elementor-item-active:before,.elementor-item.highlighted:after,.elementor-item.highlighted:before,.elementor-item:focus:after,.elementor-item:focus:before,.elementor-item:hover:after,.elementor-item:hover:before{transform:scale(1)}.e--pointer-double-line .elementor-item:after,.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:after,.e--pointer-overline .elementor-item:before,.e--pointer-underline .elementor-item:after,.e--pointer-underline .elementor-item:before{background-color:#3f444b;height:3px;left:0;width:100%;z-index:2}.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{height:0;left:50%;width:0}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:10px}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:-10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:-10px}.e--pointer-double-line.e--animation-none,.e--pointer-double-line.e--animation-none .elementor-item,.e--pointer-double-line.e--animation-none .elementor-item:after,.e--pointer-double-line.e--animation-none .elementor-item:before,.e--pointer-double-line.e--animation-none .elementor-item:focus,.e--pointer-double-line.e--animation-none .elementor-item:hover,.e--pointer-double-line.e--animation-none:after,.e--pointer-double-line.e--animation-none:before,.e--pointer-double-line.e--animation-none:focus,.e--pointer-double-line.e--animation-none:hover,.e--pointer-overline.e--animation-none,.e--pointer-overline.e--animation-none .elementor-item,.e--pointer-overline.e--animation-none .elementor-item:after,.e--pointer-overline.e--animation-none .elementor-item:before,.e--pointer-overline.e--animation-none .elementor-item:focus,.e--pointer-overline.e--animation-none .elementor-item:hover,.e--pointer-overline.e--animation-none:after,.e--pointer-overline.e--animation-none:before,.e--pointer-overline.e--animation-none:focus,.e--pointer-overline.e--animation-none:hover,.e--pointer-underline.e--animation-none,.e--pointer-underline.e--animation-none .elementor-item,.e--pointer-underline.e--animation-none .elementor-item:after,.e--pointer-underline.e--animation-none .elementor-item:before,.e--pointer-underline.e--animation-none .elementor-item:focus,.e--pointer-underline.e--animation-none .elementor-item:hover,.e--pointer-underline.e--animation-none:after,.e--pointer-underline.e--animation-none:before,.e--pointer-underline.e--animation-none:focus,.e--pointer-underline.e--animation-none:hover{transition-duration:0s}.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:before{content:"";top:0}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:-20px;width:10px}.e--pointer-double-line .elementor-item:after,.e--pointer-underline .elementor-item:after{bottom:0;content:""}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{inset-inline-start:100%;width:10px}.e--pointer-framed .elementor-item:after,.e--pointer-framed .elementor-item:before{background:transparent;border:3px solid #3f444b;bottom:0;left:0;right:0;top:0}.e--pointer-framed .elementor-item:before{content:""}.e--pointer-framed.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(.75)}.e--pointer-framed.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.25)}.e--pointer-framed.e--animation-grow .elementor-item:before,.e--pointer-framed.e--animation-shrink .elementor-item:before{transition:opacity .2s,transform .4s}.e--pointer-framed.e--animation-draw .elementor-item:after,.e--pointer-framed.e--animation-draw .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-draw .elementor-item:before{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:0;border-inline-start-width:3px;transition:width .1s .2s,height .1s .3s,opacity .12s .22s}.e--pointer-framed.e--animation-draw .elementor-item:after{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto;transition:width .1s,height .1s .1s,opacity .02s .18s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{height:100%;width:100%}.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{transition:opacity .02s,height .1s,width .1s .1s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:after{transition:opacity .02s .2s,height .1s .2s,width .1s .3s}.e--pointer-framed.e--animation-corners .elementor-item:after,.e--pointer-framed.e--animation-corners .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-corners .elementor-item:before{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:0;border-inline-start-width:3px}.e--pointer-framed.e--animation-corners .elementor-item:after{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto}.e--pointer-framed.e--animation-corners .elementor-item-active:after,.e--pointer-framed.e--animation-corners .elementor-item-active:before,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:after,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:before,.e--pointer-framed.e--animation-corners .elementor-item:focus:after,.e--pointer-framed.e--animation-corners .elementor-item:focus:before,.e--pointer-framed.e--animation-corners .elementor-item:hover:after,.e--pointer-framed.e--animation-corners .elementor-item:hover:before{height:100%;transition:opacity 2ms,width .4s,height .4s;width:100%}.e--pointer-framed.e--animation-none,.e--pointer-framed.e--animation-none .elementor-item,.e--pointer-framed.e--animation-none .elementor-item:after,.e--pointer-framed.e--animation-none .elementor-item:before,.e--pointer-framed.e--animation-none .elementor-item:focus,.e--pointer-framed.e--animation-none .elementor-item:hover,.e--pointer-framed.e--animation-none:after,.e--pointer-framed.e--animation-none:before,.e--pointer-framed.e--animation-none:focus,.e--pointer-framed.e--animation-none:hover{transition-duration:0s}.e--pointer-background .elementor-item:after,.e--pointer-background .elementor-item:before{content:"";transition:.3s}.e--pointer-background .elementor-item:before{background:#3f444b;inset:0;z-index:-1}.e--pointer-background .elementor-item-active,.e--pointer-background .elementor-item.highlighted,.e--pointer-background .elementor-item:focus,.e--pointer-background .elementor-item:hover{color:#fff}.e--pointer-background.e--animation-grow .elementor-item:before{transform:scale(.5)}.e--pointer-background.e--animation-grow .elementor-item-active:before,.e--pointer-background.e--animation-grow .elementor-item.highlighted:before,.e--pointer-background.e--animation-grow .elementor-item:focus:before,.e--pointer-background.e--animation-grow .elementor-item:hover:before{opacity:1;transform:scale(1)}.e--pointer-background.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.2);transition:.3s}.e--pointer-background.e--animation-shrink .elementor-item-active:before,.e--pointer-background.e--animation-shrink .elementor-item.highlighted:before,.e--pointer-background.e--animation-shrink .elementor-item:focus:before,.e--pointer-background.e--animation-shrink .elementor-item:hover:before{transition:opacity .15s,transform .4s}.e--pointer-background.e--animation-sweep-left .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:100%}.e--pointer-background.e--animation-sweep-right .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{right:100%}.e--pointer-background.e--animation-sweep-up .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:100%}.e--pointer-background.e--animation-sweep-down .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:100%}.e--pointer-background.e--animation-shutter-out-vertical .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:50%;top:50%}.e--pointer-background.e--animation-shutter-out-horizontal .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:50%;right:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{background:#3f444b;inset:0;z-index:-1}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:before{bottom:100%;top:0}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{bottom:0;top:100%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:before{bottom:50%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:after{top:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:before{left:100%;right:0}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after{left:0;right:100%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:before{left:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:after{right:50%}.e--pointer-background.e--animation-none,.e--pointer-background.e--animation-none .elementor-item,.e--pointer-background.e--animation-none .elementor-item:after,.e--pointer-background.e--animation-none .elementor-item:before,.e--pointer-background.e--animation-none .elementor-item:focus,.e--pointer-background.e--animation-none .elementor-item:hover,.e--pointer-background.e--animation-none:after,.e--pointer-background.e--animation-none:before,.e--pointer-background.e--animation-none:focus,.e--pointer-background.e--animation-none:hover{transition-duration:0s}.e--pointer-text.e--animation-skew .elementor-item:focus,.e--pointer-text.e--animation-skew .elementor-item:hover{transform:skew(-8deg)}.e--pointer-text.e--animation-grow .elementor-item:focus,.e--pointer-text.e--animation-grow .elementor-item:hover{transform:scale(1.2)}.e--pointer-text.e--animation-shrink .elementor-item:focus,.e--pointer-text.e--animation-shrink .elementor-item:hover{transform:scale(.8)}.e--pointer-text.e--animation-float .elementor-item:focus,.e--pointer-text.e--animation-float .elementor-item:hover{transform:translateY(-8px)}.e--pointer-text.e--animation-sink .elementor-item:focus,.e--pointer-text.e--animation-sink .elementor-item:hover{transform:translateY(8px)}.e--pointer-text.e--animation-rotate .elementor-item:focus,.e--pointer-text.e--animation-rotate .elementor-item:hover{transform:rotate(6deg)}.e--pointer-text.e--animation-none,.e--pointer-text.e--animation-none .elementor-item,.e--pointer-text.e--animation-none .elementor-item:after,.e--pointer-text.e--animation-none .elementor-item:before,.e--pointer-text.e--animation-none .elementor-item:focus,.e--pointer-text.e--animation-none .elementor-item:hover,.e--pointer-text.e--animation-none:after,.e--pointer-text.e--animation-none:before,.e--pointer-text.e--animation-none:focus,.e--pointer-text.e--animation-none:hover{transition-duration:0s}.elementor-nav-menu--main .elementor-nav-menu a{transition:.4s}.elementor-nav-menu--main .elementor-nav-menu a,.elementor-nav-menu--main .elementor-nav-menu a.highlighted,.elementor-nav-menu--main .elementor-nav-menu a:focus,.elementor-nav-menu--main .elementor-nav-menu a:hover{padding:13px 20px}.elementor-nav-menu--main .elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu--main .elementor-nav-menu a.disabled{background:#3f444b;color:#88909b}.elementor-nav-menu--main .elementor-nav-menu ul{border-style:solid;border-width:0;padding:0;position:absolute;width:12em}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up{background:#fff;display:none;height:20px;overflow:hidden;position:absolute;visibility:hidden}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up-arrow{border:8px dashed transparent;border-bottom:8px solid #33373d;height:0;inset-block-start:-2px;inset-inline-start:50%;margin-inline-start:-8px;overflow:hidden;position:absolute;width:0}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow{border-color:#33373d transparent transparent;border-style:solid dashed dashed;top:6px}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg,.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i{transform:rotate(calc(-90deg * var(--direction-multiplier, 1)))}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg{fill:currentColor;height:1em;width:1em}.elementor-nav-menu--layout-horizontal{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu{display:flex;flex-wrap:wrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu a{flex-grow:1;white-space:nowrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li ul,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>.scroll-down{top:100%!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>a{margin-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-down,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-up,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>ul{inset-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child)>a{margin-inline-end:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child):after{align-self:center;border-color:var(--e-nav-menu-divider-color,#000);border-left-style:var(--e-nav-menu-divider-style,solid);border-left-width:var(--e-nav-menu-divider-width,2px);content:var(--e-nav-menu-divider-content,none);height:var(--e-nav-menu-divider-height,35%)}.elementor-nav-menu__align-right .elementor-nav-menu{justify-content:flex-start;margin-left:auto}.elementor-nav-menu__align-right .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-left .elementor-nav-menu{justify-content:flex-end;margin-right:auto}.elementor-nav-menu__align-left .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-start .elementor-nav-menu{justify-content:flex-start;margin-inline-end:auto}.elementor-nav-menu__align-start .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-end .elementor-nav-menu{justify-content:flex-end;margin-inline-start:auto}.elementor-nav-menu__align-end .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-center .elementor-nav-menu{justify-content:center;margin-inline-end:auto;margin-inline-start:auto}.elementor-nav-menu__align-center .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:center}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu{width:100%}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{flex-grow:1}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>a{justify-content:center}.elementor-widget-nav-menu:not(.elementor-nav-menu--toggle) .elementor-menu-toggle{display:none}.elementor-widget-nav-menu .elementor-widget-container,.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*=elementor-hidden-]){display:flex;flex-direction:column}.elementor-nav-menu{position:relative;z-index:2}.elementor-nav-menu:after{clear:both;content:" ";display:block;font:0/0 serif;height:0;overflow:hidden;visibility:hidden}.elementor-nav-menu,.elementor-nav-menu li,.elementor-nav-menu ul{display:block;line-height:normal;list-style:none;margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.elementor-nav-menu ul{display:none}.elementor-nav-menu ul ul a,.elementor-nav-menu ul ul a:active,.elementor-nav-menu ul ul a:focus,.elementor-nav-menu ul ul a:hover{border-left:16px solid transparent}.elementor-nav-menu ul ul ul a,.elementor-nav-menu ul ul ul a:active,.elementor-nav-menu ul ul ul a:focus,.elementor-nav-menu ul ul ul a:hover{border-left:24px solid transparent}.elementor-nav-menu ul ul ul ul a,.elementor-nav-menu ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul a:hover{border-left:32px solid transparent}.elementor-nav-menu ul ul ul ul ul a,.elementor-nav-menu ul ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul ul a:hover{border-left:40px solid transparent}.elementor-nav-menu a,.elementor-nav-menu li{position:relative}.elementor-nav-menu li{border-width:0}.elementor-nav-menu a{align-items:center;display:flex}.elementor-nav-menu a,.elementor-nav-menu a:focus,.elementor-nav-menu a:hover{line-height:20px;padding:10px 20px}.elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu a.disabled{color:#88909b;cursor:not-allowed}.elementor-nav-menu .e-plus-icon:before{content:"+"}.elementor-nav-menu .sub-arrow{align-items:center;display:flex;line-height:1;margin-block-end:-10px;margin-block-start:-10px;padding:10px;padding-inline-end:0}.elementor-nav-menu .sub-arrow i{pointer-events:none}.elementor-nav-menu .sub-arrow .fa.fa-chevron-down,.elementor-nav-menu .sub-arrow .fas.fa-chevron-down{font-size:.7em}.elementor-nav-menu .sub-arrow .e-font-icon-svg{height:1em;width:1em}.elementor-nav-menu .sub-arrow .e-font-icon-svg.fa-svg-chevron-down{height:.7em;width:.7em}.elementor-nav-menu--dropdown .elementor-item.elementor-item-active,.elementor-nav-menu--dropdown .elementor-item.highlighted,.elementor-nav-menu--dropdown .elementor-item:focus,.elementor-nav-menu--dropdown .elementor-item:hover,.elementor-sub-item.elementor-item-active,.elementor-sub-item.highlighted,.elementor-sub-item:focus,.elementor-sub-item:hover{background-color:#3f444b;color:#fff}.elementor-menu-toggle{align-items:center;background-color:rgba(0,0,0,.05);border:0 solid;border-radius:3px;color:#33373d;cursor:pointer;display:flex;font-size:var(--nav-menu-icon-size,22px);justify-content:center;padding:.25em}.elementor-menu-toggle.elementor-active .elementor-menu-toggle__icon--open,.elementor-menu-toggle:not(.elementor-active) .elementor-menu-toggle__icon--close{display:none}.elementor-menu-toggle .e-font-icon-svg{fill:#33373d;height:1em;width:1em}.elementor-menu-toggle svg{height:auto;width:1em;fill:var(--nav-menu-icon-color,currentColor)}span.elementor-menu-toggle__icon--close,span.elementor-menu-toggle__icon--open{line-height:1}.elementor-nav-menu--dropdown{background-color:#fff;font-size:13px}.elementor-nav-menu--dropdown-none .elementor-menu-toggle,.elementor-nav-menu--dropdown-none .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown.elementor-nav-menu__container{margin-top:10px;overflow-x:hidden;overflow-y:auto;transform-origin:top;transition:max-height .3s,transform .3s}.elementor-nav-menu--dropdown.elementor-nav-menu__container .elementor-sub-item{font-size:.85em}.elementor-nav-menu--dropdown a{color:#33373d}.elementor-nav-menu--dropdown a.current{background:#1f2124;color:#fff}.elementor-nav-menu--dropdown a.disabled{color:#b3b3b3}ul.elementor-nav-menu--dropdown a,ul.elementor-nav-menu--dropdown a:focus,ul.elementor-nav-menu--dropdown a:hover{border-inline-start:8px solid transparent;text-shadow:none}.elementor-nav-menu__text-align-center .elementor-nav-menu--dropdown .elementor-nav-menu a{justify-content:center}.elementor-nav-menu--toggle{--menu-height:100vh}.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{max-height:0;overflow:hidden;transform:scaleY(0)}.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{animation:hide-scroll .3s backwards;max-height:var(--menu-height);transform:scaleY(1)}.elementor-nav-menu--stretch .elementor-nav-menu__container.elementor-nav-menu--dropdown{position:absolute;z-index:9997}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_MOBILE_NEXT){.elementor-nav-menu--dropdown-mobile .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_NEXT){.elementor-nav-menu--dropdown-mobile_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-nav-menu--dropdown-tablet .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_TABLET_EXTRA_NEXT){.elementor-nav-menu--dropdown-tablet_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@keyframes hide-scroll{0%,to{overflow:hidden}} \ No newline at end of file diff --git a/assets/css/templates/widget-nav-menu.min.css b/assets/css/templates/widget-nav-menu.min.css new file mode 100644 index 00000000..e469f141 --- /dev/null +++ b/assets/css/templates/widget-nav-menu.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.site-main .menu-navigation-container{overflow:visible}.elementor-item:after,.elementor-item:before{display:block;position:absolute;transition:.3s;transition-timing-function:cubic-bezier(.58,.3,.005,1)}.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{opacity:0}.elementor-item-active:after,.elementor-item-active:before,.elementor-item.highlighted:after,.elementor-item.highlighted:before,.elementor-item:focus:after,.elementor-item:focus:before,.elementor-item:hover:after,.elementor-item:hover:before{transform:scale(1)}.e--pointer-double-line .elementor-item:after,.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:after,.e--pointer-overline .elementor-item:before,.e--pointer-underline .elementor-item:after,.e--pointer-underline .elementor-item:before{background-color:#3f444b;height:3px;left:0;width:100%;z-index:2}.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{height:0;left:50%;width:0}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:10px}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:-10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:-10px}.e--pointer-double-line.e--animation-none,.e--pointer-double-line.e--animation-none .elementor-item,.e--pointer-double-line.e--animation-none .elementor-item:after,.e--pointer-double-line.e--animation-none .elementor-item:before,.e--pointer-double-line.e--animation-none .elementor-item:focus,.e--pointer-double-line.e--animation-none .elementor-item:hover,.e--pointer-double-line.e--animation-none:after,.e--pointer-double-line.e--animation-none:before,.e--pointer-double-line.e--animation-none:focus,.e--pointer-double-line.e--animation-none:hover,.e--pointer-overline.e--animation-none,.e--pointer-overline.e--animation-none .elementor-item,.e--pointer-overline.e--animation-none .elementor-item:after,.e--pointer-overline.e--animation-none .elementor-item:before,.e--pointer-overline.e--animation-none .elementor-item:focus,.e--pointer-overline.e--animation-none .elementor-item:hover,.e--pointer-overline.e--animation-none:after,.e--pointer-overline.e--animation-none:before,.e--pointer-overline.e--animation-none:focus,.e--pointer-overline.e--animation-none:hover,.e--pointer-underline.e--animation-none,.e--pointer-underline.e--animation-none .elementor-item,.e--pointer-underline.e--animation-none .elementor-item:after,.e--pointer-underline.e--animation-none .elementor-item:before,.e--pointer-underline.e--animation-none .elementor-item:focus,.e--pointer-underline.e--animation-none .elementor-item:hover,.e--pointer-underline.e--animation-none:after,.e--pointer-underline.e--animation-none:before,.e--pointer-underline.e--animation-none:focus,.e--pointer-underline.e--animation-none:hover{transition-duration:0s}.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:before{content:"";top:0}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:-20px;width:10px}.e--pointer-double-line .elementor-item:after,.e--pointer-underline .elementor-item:after{bottom:0;content:""}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{inset-inline-start:100%;width:10px}.e--pointer-framed .elementor-item:after,.e--pointer-framed .elementor-item:before{background:transparent;border:3px solid #3f444b;bottom:0;left:0;right:0;top:0}.e--pointer-framed .elementor-item:before{content:""}.e--pointer-framed.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(.75)}.e--pointer-framed.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.25)}.e--pointer-framed.e--animation-grow .elementor-item:before,.e--pointer-framed.e--animation-shrink .elementor-item:before{transition:opacity .2s,transform .4s}.e--pointer-framed.e--animation-draw .elementor-item:after,.e--pointer-framed.e--animation-draw .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-draw .elementor-item:before{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:0;border-inline-start-width:3px;transition:width .1s .2s,height .1s .3s,opacity .12s .22s}.e--pointer-framed.e--animation-draw .elementor-item:after{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto;transition:width .1s,height .1s .1s,opacity .02s .18s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{height:100%;width:100%}.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{transition:opacity .02s,height .1s,width .1s .1s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:after{transition:opacity .02s .2s,height .1s .2s,width .1s .3s}.e--pointer-framed.e--animation-corners .elementor-item:after,.e--pointer-framed.e--animation-corners .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-corners .elementor-item:before{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:0;border-inline-start-width:3px}.e--pointer-framed.e--animation-corners .elementor-item:after{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto}.e--pointer-framed.e--animation-corners .elementor-item-active:after,.e--pointer-framed.e--animation-corners .elementor-item-active:before,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:after,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:before,.e--pointer-framed.e--animation-corners .elementor-item:focus:after,.e--pointer-framed.e--animation-corners .elementor-item:focus:before,.e--pointer-framed.e--animation-corners .elementor-item:hover:after,.e--pointer-framed.e--animation-corners .elementor-item:hover:before{height:100%;transition:opacity 2ms,width .4s,height .4s;width:100%}.e--pointer-framed.e--animation-none,.e--pointer-framed.e--animation-none .elementor-item,.e--pointer-framed.e--animation-none .elementor-item:after,.e--pointer-framed.e--animation-none .elementor-item:before,.e--pointer-framed.e--animation-none .elementor-item:focus,.e--pointer-framed.e--animation-none .elementor-item:hover,.e--pointer-framed.e--animation-none:after,.e--pointer-framed.e--animation-none:before,.e--pointer-framed.e--animation-none:focus,.e--pointer-framed.e--animation-none:hover{transition-duration:0s}.e--pointer-background .elementor-item:after,.e--pointer-background .elementor-item:before{content:"";transition:.3s}.e--pointer-background .elementor-item:before{background:#3f444b;inset:0;z-index:-1}.e--pointer-background .elementor-item-active,.e--pointer-background .elementor-item.highlighted,.e--pointer-background .elementor-item:focus,.e--pointer-background .elementor-item:hover{color:#fff}.e--pointer-background.e--animation-grow .elementor-item:before{transform:scale(.5)}.e--pointer-background.e--animation-grow .elementor-item-active:before,.e--pointer-background.e--animation-grow .elementor-item.highlighted:before,.e--pointer-background.e--animation-grow .elementor-item:focus:before,.e--pointer-background.e--animation-grow .elementor-item:hover:before{opacity:1;transform:scale(1)}.e--pointer-background.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.2);transition:.3s}.e--pointer-background.e--animation-shrink .elementor-item-active:before,.e--pointer-background.e--animation-shrink .elementor-item.highlighted:before,.e--pointer-background.e--animation-shrink .elementor-item:focus:before,.e--pointer-background.e--animation-shrink .elementor-item:hover:before{transition:opacity .15s,transform .4s}.e--pointer-background.e--animation-sweep-left .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:100%}.e--pointer-background.e--animation-sweep-right .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{right:100%}.e--pointer-background.e--animation-sweep-up .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:100%}.e--pointer-background.e--animation-sweep-down .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:100%}.e--pointer-background.e--animation-shutter-out-vertical .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:50%;top:50%}.e--pointer-background.e--animation-shutter-out-horizontal .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:50%;right:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{background:#3f444b;inset:0;z-index:-1}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:before{bottom:100%;top:0}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{bottom:0;top:100%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:before{bottom:50%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:after{top:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:before{left:100%;right:0}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after{left:0;right:100%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:before{left:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:after{right:50%}.e--pointer-background.e--animation-none,.e--pointer-background.e--animation-none .elementor-item,.e--pointer-background.e--animation-none .elementor-item:after,.e--pointer-background.e--animation-none .elementor-item:before,.e--pointer-background.e--animation-none .elementor-item:focus,.e--pointer-background.e--animation-none .elementor-item:hover,.e--pointer-background.e--animation-none:after,.e--pointer-background.e--animation-none:before,.e--pointer-background.e--animation-none:focus,.e--pointer-background.e--animation-none:hover{transition-duration:0s}.e--pointer-text.e--animation-skew .elementor-item:focus,.e--pointer-text.e--animation-skew .elementor-item:hover{transform:skew(-8deg)}.e--pointer-text.e--animation-grow .elementor-item:focus,.e--pointer-text.e--animation-grow .elementor-item:hover{transform:scale(1.2)}.e--pointer-text.e--animation-shrink .elementor-item:focus,.e--pointer-text.e--animation-shrink .elementor-item:hover{transform:scale(.8)}.e--pointer-text.e--animation-float .elementor-item:focus,.e--pointer-text.e--animation-float .elementor-item:hover{transform:translateY(-8px)}.e--pointer-text.e--animation-sink .elementor-item:focus,.e--pointer-text.e--animation-sink .elementor-item:hover{transform:translateY(8px)}.e--pointer-text.e--animation-rotate .elementor-item:focus,.e--pointer-text.e--animation-rotate .elementor-item:hover{transform:rotate(6deg)}.e--pointer-text.e--animation-none,.e--pointer-text.e--animation-none .elementor-item,.e--pointer-text.e--animation-none .elementor-item:after,.e--pointer-text.e--animation-none .elementor-item:before,.e--pointer-text.e--animation-none .elementor-item:focus,.e--pointer-text.e--animation-none .elementor-item:hover,.e--pointer-text.e--animation-none:after,.e--pointer-text.e--animation-none:before,.e--pointer-text.e--animation-none:focus,.e--pointer-text.e--animation-none:hover{transition-duration:0s}.elementor-nav-menu--main .elementor-nav-menu a{transition:.4s}.elementor-nav-menu--main .elementor-nav-menu a,.elementor-nav-menu--main .elementor-nav-menu a.highlighted,.elementor-nav-menu--main .elementor-nav-menu a:focus,.elementor-nav-menu--main .elementor-nav-menu a:hover{padding:13px 20px}.elementor-nav-menu--main .elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu--main .elementor-nav-menu a.disabled{background:#3f444b;color:#88909b}.elementor-nav-menu--main .elementor-nav-menu ul{border-style:solid;border-width:0;padding:0;position:absolute;width:12em}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up{background:#fff;display:none;height:20px;overflow:hidden;position:absolute;visibility:hidden}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up-arrow{border:8px dashed transparent;border-bottom:8px solid #33373d;height:0;inset-block-start:-2px;inset-inline-start:50%;margin-inline-start:-8px;overflow:hidden;position:absolute;width:0}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow{border-color:#33373d transparent transparent;border-style:solid dashed dashed;top:6px}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg,.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i{transform:rotate(calc(-90deg * var(--direction-multiplier, 1)))}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg{fill:currentColor;height:1em;width:1em}.elementor-nav-menu--layout-horizontal{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu{display:flex;flex-wrap:wrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu a{flex-grow:1;white-space:nowrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li ul,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>.scroll-down{top:100%!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>a{margin-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-down,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-up,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>ul{inset-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child)>a{margin-inline-end:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child):after{align-self:center;border-color:var(--e-nav-menu-divider-color,#000);border-left-style:var(--e-nav-menu-divider-style,solid);border-left-width:var(--e-nav-menu-divider-width,2px);content:var(--e-nav-menu-divider-content,none);height:var(--e-nav-menu-divider-height,35%)}.elementor-nav-menu__align-right .elementor-nav-menu{justify-content:flex-end;margin-left:auto}.elementor-nav-menu__align-right .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-left .elementor-nav-menu{justify-content:flex-start;margin-right:auto}.elementor-nav-menu__align-left .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-start .elementor-nav-menu{justify-content:flex-start;margin-inline-end:auto}.elementor-nav-menu__align-start .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-end .elementor-nav-menu{justify-content:flex-end;margin-inline-start:auto}.elementor-nav-menu__align-end .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-center .elementor-nav-menu{justify-content:center;margin-inline-end:auto;margin-inline-start:auto}.elementor-nav-menu__align-center .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:center}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu{width:100%}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{flex-grow:1}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>a{justify-content:center}.elementor-widget-nav-menu:not(.elementor-nav-menu--toggle) .elementor-menu-toggle{display:none}.elementor-widget-nav-menu .elementor-widget-container,.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*=elementor-hidden-]){display:flex;flex-direction:column}.elementor-nav-menu{position:relative;z-index:2}.elementor-nav-menu:after{clear:both;content:" ";display:block;font:0/0 serif;height:0;overflow:hidden;visibility:hidden}.elementor-nav-menu,.elementor-nav-menu li,.elementor-nav-menu ul{display:block;line-height:normal;list-style:none;margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.elementor-nav-menu ul{display:none}.elementor-nav-menu ul ul a,.elementor-nav-menu ul ul a:active,.elementor-nav-menu ul ul a:focus,.elementor-nav-menu ul ul a:hover{border-left:16px solid transparent}.elementor-nav-menu ul ul ul a,.elementor-nav-menu ul ul ul a:active,.elementor-nav-menu ul ul ul a:focus,.elementor-nav-menu ul ul ul a:hover{border-left:24px solid transparent}.elementor-nav-menu ul ul ul ul a,.elementor-nav-menu ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul a:hover{border-left:32px solid transparent}.elementor-nav-menu ul ul ul ul ul a,.elementor-nav-menu ul ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul ul a:hover{border-left:40px solid transparent}.elementor-nav-menu a,.elementor-nav-menu li{position:relative}.elementor-nav-menu li{border-width:0}.elementor-nav-menu a{align-items:center;display:flex}.elementor-nav-menu a,.elementor-nav-menu a:focus,.elementor-nav-menu a:hover{line-height:20px;padding:10px 20px}.elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu a.disabled{color:#88909b;cursor:not-allowed}.elementor-nav-menu .e-plus-icon:before{content:"+"}.elementor-nav-menu .sub-arrow{align-items:center;display:flex;line-height:1;margin-block-end:-10px;margin-block-start:-10px;padding:10px;padding-inline-end:0}.elementor-nav-menu .sub-arrow i{pointer-events:none}.elementor-nav-menu .sub-arrow .fa.fa-chevron-down,.elementor-nav-menu .sub-arrow .fas.fa-chevron-down{font-size:.7em}.elementor-nav-menu .sub-arrow .e-font-icon-svg{height:1em;width:1em}.elementor-nav-menu .sub-arrow .e-font-icon-svg.fa-svg-chevron-down{height:.7em;width:.7em}.elementor-nav-menu--dropdown .elementor-item.elementor-item-active,.elementor-nav-menu--dropdown .elementor-item.highlighted,.elementor-nav-menu--dropdown .elementor-item:focus,.elementor-nav-menu--dropdown .elementor-item:hover,.elementor-sub-item.elementor-item-active,.elementor-sub-item.highlighted,.elementor-sub-item:focus,.elementor-sub-item:hover{background-color:#3f444b;color:#fff}.elementor-menu-toggle{align-items:center;background-color:rgba(0,0,0,.05);border:0 solid;border-radius:3px;color:#33373d;cursor:pointer;display:flex;font-size:var(--nav-menu-icon-size,22px);justify-content:center;padding:.25em}.elementor-menu-toggle.elementor-active .elementor-menu-toggle__icon--open,.elementor-menu-toggle:not(.elementor-active) .elementor-menu-toggle__icon--close{display:none}.elementor-menu-toggle .e-font-icon-svg{fill:#33373d;height:1em;width:1em}.elementor-menu-toggle svg{height:auto;width:1em;fill:var(--nav-menu-icon-color,currentColor)}span.elementor-menu-toggle__icon--close,span.elementor-menu-toggle__icon--open{line-height:1}.elementor-nav-menu--dropdown{background-color:#fff;font-size:13px}.elementor-nav-menu--dropdown-none .elementor-menu-toggle,.elementor-nav-menu--dropdown-none .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown.elementor-nav-menu__container{margin-top:10px;overflow-x:hidden;overflow-y:auto;transform-origin:top;transition:max-height .3s,transform .3s}.elementor-nav-menu--dropdown.elementor-nav-menu__container .elementor-sub-item{font-size:.85em}.elementor-nav-menu--dropdown a{color:#33373d}.elementor-nav-menu--dropdown a.current{background:#1f2124;color:#fff}.elementor-nav-menu--dropdown a.disabled{color:#b3b3b3}ul.elementor-nav-menu--dropdown a,ul.elementor-nav-menu--dropdown a:focus,ul.elementor-nav-menu--dropdown a:hover{border-inline-start:8px solid transparent;text-shadow:none}.elementor-nav-menu__text-align-center .elementor-nav-menu--dropdown .elementor-nav-menu a{justify-content:center}.elementor-nav-menu--toggle{--menu-height:100vh}.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{max-height:0;overflow:hidden;transform:scaleY(0)}.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{animation:hide-scroll .3s backwards;max-height:var(--menu-height);transform:scaleY(1)}.elementor-nav-menu--stretch .elementor-nav-menu__container.elementor-nav-menu--dropdown{position:absolute;z-index:9997}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_MOBILE_NEXT){.elementor-nav-menu--dropdown-mobile .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_NEXT){.elementor-nav-menu--dropdown-mobile_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-nav-menu--dropdown-tablet .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--main{display:none}}@media (min-width:ELEMENTOR_SCREEN_TABLET_EXTRA_NEXT){.elementor-nav-menu--dropdown-tablet_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@keyframes hide-scroll{0%,to{overflow:hidden}} \ No newline at end of file diff --git a/assets/css/templates/widget-slides-rtl.min.css b/assets/css/templates/widget-slides-rtl.min.css new file mode 100644 index 00000000..26405e5d --- /dev/null +++ b/assets/css/templates/widget-slides-rtl.min.css @@ -0,0 +1 @@ +.elementor-slides .swiper-slide-bg{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%}.elementor-slides .swiper-slide-inner{background-position:50%;background-repeat:no-repeat;inset:0;margin:auto;padding:50px;position:absolute}.elementor-slides .swiper-slide-inner,.elementor-slides .swiper-slide-inner:hover{color:#fff;display:flex}.elementor-slides .swiper-slide-inner .elementor-background-overlay{inset:0;position:absolute;z-index:0}.elementor-slides .swiper-slide-inner .elementor-slide-content{position:relative;width:100%;z-index:1}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:35px;font-weight:700;line-height:1}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:17px;line-height:1.4}.elementor-slides .swiper-slide-inner .elementor-slide-description:not(:last-child),.elementor-slides .swiper-slide-inner .elementor-slide-heading:not(:last-child){margin-bottom:30px}.elementor-slides .swiper-slide-inner .elementor-slide-button{background:transparent;border:2px solid #fff;color:#fff;display:inline-block}.elementor-slides .swiper-slide-inner .elementor-slide-button,.elementor-slides .swiper-slide-inner .elementor-slide-button:hover{background:transparent;color:inherit;text-decoration:none}.elementor--v-position-top .swiper-slide-inner{align-items:flex-start}.elementor--v-position-bottom .swiper-slide-inner{align-items:flex-end}.elementor--v-position-middle .swiper-slide-inner{align-items:center}.elementor--h-position-left .swiper-slide-inner{justify-content:flex-end}.elementor--h-position-right .swiper-slide-inner{justify-content:flex-start}.elementor--h-position-center .swiper-slide-inner{justify-content:center}body.rtl .elementor-widget-slides .elementor-swiper-button-next{left:10px;right:auto}body.rtl .elementor-widget-slides .elementor-swiper-button-prev{left:auto;right:10px}.elementor-slides-wrapper div:not(.swiper-slide)>.swiper-slide-inner{display:none}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-slides .swiper-slide-inner{padding:30px}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:23px;line-height:1;margin-bottom:15px}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:13px;line-height:1.4;margin-bottom:15px}} \ No newline at end of file diff --git a/assets/css/templates/widget-slides.min.css b/assets/css/templates/widget-slides.min.css new file mode 100644 index 00000000..fa36cc91 --- /dev/null +++ b/assets/css/templates/widget-slides.min.css @@ -0,0 +1 @@ +.elementor-slides .swiper-slide-bg{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%}.elementor-slides .swiper-slide-inner{background-position:50%;background-repeat:no-repeat;inset:0;margin:auto;padding:50px;position:absolute}.elementor-slides .swiper-slide-inner,.elementor-slides .swiper-slide-inner:hover{color:#fff;display:flex}.elementor-slides .swiper-slide-inner .elementor-background-overlay{inset:0;position:absolute;z-index:0}.elementor-slides .swiper-slide-inner .elementor-slide-content{position:relative;width:100%;z-index:1}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:35px;font-weight:700;line-height:1}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:17px;line-height:1.4}.elementor-slides .swiper-slide-inner .elementor-slide-description:not(:last-child),.elementor-slides .swiper-slide-inner .elementor-slide-heading:not(:last-child){margin-bottom:30px}.elementor-slides .swiper-slide-inner .elementor-slide-button{background:transparent;border:2px solid #fff;color:#fff;display:inline-block}.elementor-slides .swiper-slide-inner .elementor-slide-button,.elementor-slides .swiper-slide-inner .elementor-slide-button:hover{background:transparent;color:inherit;text-decoration:none}.elementor--v-position-top .swiper-slide-inner{align-items:flex-start}.elementor--v-position-bottom .swiper-slide-inner{align-items:flex-end}.elementor--v-position-middle .swiper-slide-inner{align-items:center}.elementor--h-position-left .swiper-slide-inner{justify-content:flex-start}.elementor--h-position-right .swiper-slide-inner{justify-content:flex-end}.elementor--h-position-center .swiper-slide-inner{justify-content:center}body.rtl .elementor-widget-slides .elementor-swiper-button-next{left:10px;right:auto}body.rtl .elementor-widget-slides .elementor-swiper-button-prev{left:auto;right:10px}.elementor-slides-wrapper div:not(.swiper-slide)>.swiper-slide-inner{display:none}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-slides .swiper-slide-inner{padding:30px}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:23px;line-height:1;margin-bottom:15px}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:13px;line-height:1.4;margin-bottom:15px}} \ No newline at end of file diff --git a/assets/css/templates/widget-testimonial-carousel-rtl.min.css b/assets/css/templates/widget-testimonial-carousel-rtl.min.css new file mode 100644 index 00000000..527c0bf4 --- /dev/null +++ b/assets/css/templates/widget-testimonial-carousel-rtl.min.css @@ -0,0 +1 @@ +.elementor-testimonial__image{flex-shrink:0}.elementor-testimonial__image img{border-radius:999px;box-sizing:content-box;-o-object-fit:cover;object-fit:cover}.elementor-testimonial__footer,.elementor-testimonial__header{display:flex}.elementor-testimonial__footer cite,.elementor-testimonial__header cite{display:flex;flex-direction:column;font-size:14px;font-style:normal;line-height:1.5}.elementor-testimonial__name{font-weight:700}.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{align-items:center}.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline-start:20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__footer{flex-direction:row}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__footer{flex-direction:row-reverse}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{margin-top:25px}.elementor-testimonial--layout-image_above .elementor-testimonial{display:flex;flex-direction:column-reverse}.elementor-testimonial--layout-image_above .elementor-testimonial__footer{margin-bottom:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer{flex-wrap:wrap;margin-top:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial cite,.elementor-testimonial--layout-image_stacked .elementor-testimonial__image{margin-top:15px;width:100%}.elementor-testimonial--layout-image_left .elementor-testimonial,.elementor-testimonial--layout-image_right .elementor-testimonial{align-items:stretch;display:flex}.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--layout-image_right .elementor-testimonial__footer{flex-direction:column;flex-shrink:0;text-align:center}.elementor-testimonial--layout-image_left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_right .elementor-testimonial__image+cite{margin-top:15px}.elementor-testimonial--layout-image_left.elementor-testimonial--align-center .elementor-testimonial__footer,.elementor-testimonial--layout-image_right.elementor-testimonial--align-center .elementor-testimonial__footer{justify-content:flex-start}.elementor-testimonial--layout-image_left .elementor-testimonial{flex-direction:row}.elementor-testimonial--layout-image_left .elementor-testimonial__footer{padding-inline-end:20px}.elementor-testimonial--layout-image_right .elementor-testimonial{flex-direction:row-reverse}.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-inline-start:20px}.elementor-testimonial--align-right .elementor-testimonial{text-align:right}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--align-left .elementor-testimonial{text-align:left}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--align-center .elementor-testimonial{text-align:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--skin-default.elementor-testimonial--layout-image_above .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_left .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_right .elementor-testimonial__cite{display:flex;flex-direction:column;margin-top:25px;width:100%}.elementor-testimonial--skin-bubble .elementor-testimonial__content{background-color:#f9fafa;padding:20px;position:relative}.elementor-testimonial--skin-bubble .elementor-testimonial__content:after{background-color:#f9fafa;border-width:0;box-sizing:content-box;content:"";display:block;height:14px;inset-inline-start:calc(20px + 50px / 2);position:absolute;transform:scaleX(.75) rotate(45deg);width:14px}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above .elementor-testimonial__content:after{bottom:calc(100% - 7px);transform:scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked .elementor-testimonial__content:after{top:calc(100% - 7px)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-center .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-left .elementor-testimonial__content:after{left:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-right .elementor-testimonial__content:after{right:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after{left:-8px;transform:scaleY(.75) rotate(135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{right:-8px;transform:scaleY(.75) rotate(-45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{top:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-top:20px}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-testimonial--widescreen-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--widescreen-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--widescreen-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-testimonial--laptop-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--laptop-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--laptop-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-testimonial--tablet_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-testimonial--tablet-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-testimonial--mobile_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-testimonial--mobile-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}.elementor-widget-testimonial-carousel .swiper-slide{padding:20px}.elementor-widget-testimonial-carousel .elementor-testimonial__text{font-size:1.3em;font-style:italic;line-height:1.5}.elementor-widget-testimonial-carousel .elementor-testimonial__image img{height:50px;width:50px} \ No newline at end of file diff --git a/assets/css/templates/widget-testimonial-carousel.min.css b/assets/css/templates/widget-testimonial-carousel.min.css new file mode 100644 index 00000000..6df4c478 --- /dev/null +++ b/assets/css/templates/widget-testimonial-carousel.min.css @@ -0,0 +1 @@ +.elementor-testimonial__image{flex-shrink:0}.elementor-testimonial__image img{border-radius:999px;box-sizing:content-box;-o-object-fit:cover;object-fit:cover}.elementor-testimonial__footer,.elementor-testimonial__header{display:flex}.elementor-testimonial__footer cite,.elementor-testimonial__header cite{display:flex;flex-direction:column;font-size:14px;font-style:normal;line-height:1.5}.elementor-testimonial__name{font-weight:700}.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{align-items:center}.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline-start:20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__footer{flex-direction:row-reverse}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__footer{flex-direction:row}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{margin-top:25px}.elementor-testimonial--layout-image_above .elementor-testimonial{display:flex;flex-direction:column-reverse}.elementor-testimonial--layout-image_above .elementor-testimonial__footer{margin-bottom:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer{flex-wrap:wrap;margin-top:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial cite,.elementor-testimonial--layout-image_stacked .elementor-testimonial__image{margin-top:15px;width:100%}.elementor-testimonial--layout-image_left .elementor-testimonial,.elementor-testimonial--layout-image_right .elementor-testimonial{align-items:stretch;display:flex}.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--layout-image_right .elementor-testimonial__footer{flex-direction:column;flex-shrink:0;text-align:center}.elementor-testimonial--layout-image_left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_right .elementor-testimonial__image+cite{margin-top:15px}.elementor-testimonial--layout-image_left.elementor-testimonial--align-center .elementor-testimonial__footer,.elementor-testimonial--layout-image_right.elementor-testimonial--align-center .elementor-testimonial__footer{justify-content:flex-start}.elementor-testimonial--layout-image_left .elementor-testimonial{flex-direction:row-reverse}.elementor-testimonial--layout-image_left .elementor-testimonial__footer{padding-inline-end:20px}.elementor-testimonial--layout-image_right .elementor-testimonial{flex-direction:row}.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-inline-start:20px}.elementor-testimonial--align-right .elementor-testimonial{text-align:right}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--align-left .elementor-testimonial{text-align:left}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--align-center .elementor-testimonial{text-align:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--skin-default.elementor-testimonial--layout-image_above .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_left .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_right .elementor-testimonial__cite{display:flex;flex-direction:column;margin-top:25px;width:100%}.elementor-testimonial--skin-bubble .elementor-testimonial__content{background-color:#f9fafa;padding:20px;position:relative}.elementor-testimonial--skin-bubble .elementor-testimonial__content:after{background-color:#f9fafa;border-width:0;box-sizing:content-box;content:"";display:block;height:14px;inset-inline-start:calc(20px + 50px / 2);position:absolute;transform:scaleX(.75) rotate(45deg);width:14px}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above .elementor-testimonial__content:after{bottom:calc(100% - 7px);transform:scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked .elementor-testimonial__content:after{top:calc(100% - 7px)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-center .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-left .elementor-testimonial__content:after{left:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-right .elementor-testimonial__content:after{right:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after{left:-8px;transform:scaleY(.75) rotate(135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{right:-8px;transform:scaleY(.75) rotate(-45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{top:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-top:20px}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){.elementor-testimonial--widescreen-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--widescreen-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--widescreen-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){.elementor-testimonial--laptop-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--laptop-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--laptop-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){.elementor-testimonial--tablet_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-testimonial--tablet-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){.elementor-testimonial--mobile_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-testimonial--mobile-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}.elementor-widget-testimonial-carousel .swiper-slide{padding:20px}.elementor-widget-testimonial-carousel .elementor-testimonial__text{font-size:1.3em;font-style:italic;line-height:1.5}.elementor-widget-testimonial-carousel .elementor-testimonial__image img{height:50px;width:50px} \ No newline at end of file diff --git a/assets/css/templates/widget-video-playlist-rtl.min.css b/assets/css/templates/widget-video-playlist-rtl.min.css new file mode 100644 index 00000000..b31dd1a9 --- /dev/null +++ b/assets/css/templates/widget-video-playlist-rtl.min.css @@ -0,0 +1 @@ +.e-tabs-inner-tabs{font-size:16px;text-align:start}.e-tabs-inner-tabs .e-tab-content{padding-top:32px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:flex;overflow:hidden;position:relative;z-index:1}.e-tabs-inner-tabs .e-inner-tabs-wrapper :after{background-color:var(--inner-tabs-border-color,#d5d8dc);bottom:0;content:"";height:var(--inner-tabs-border-height,1px);position:absolute;width:100%;z-index:-1}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title{box-sizing:content-box;font-weight:700;height:38px;line-height:38px;min-width:140px}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a{color:#3f444b;display:block;padding:0 36px;text-align:center}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active{border-color:#0c0d0e #0c0d0e transparent;border-bottom:1px solid #0c0d0e;border-left-width:0;border-right-width:0;border-top-width:0}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active a{color:#0c0d0e}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{display:none;padding:20px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text{color:#1f2124}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.e-inner-tab-active{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons{display:none;margin-top:24px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons button{background:transparent;border:none;display:none;font-weight:500;line-height:24px;padding:0;text-decoration:underline}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible .e-inner-tab-text{overflow:hidden}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button.show-button,.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible.show-inner-tab-buttons .e-inner-tab-buttons{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.show-full-height div.e-inner-tab-text{height:auto}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-tabs-inner-tabs>.e-tab-content:first-child{padding-top:24px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper{border:solid #d5d8dc;border-width:1px 1px 0}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{border:solid #d5d8dc;border-width:0 0 1px;cursor:pointer;display:block;font-size:16px;font-weight:700;height:38px;line-height:38px;overflow:hidden;padding:0 10px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{border:solid #d5d8dc;border-width:0 0 1px;padding:20px}}.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:row}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:column-reverse}}.elementor-widget-video-playlist .e-tabs{display:flex;flex-direction:column}.elementor-widget-video-playlist .e-tabs-main-area{display:flex;flex-direction:row-reverse;height:434px}.elementor-widget-video-playlist .e-tabs-wrapper{display:flex;flex-direction:column;height:100%;width:33%}.elementor-widget-video-playlist .e-tabs-header{background-color:var(--e-a-bg-default);border-bottom:1px solid #d5d8dc;display:flex;flex:0 0 auto;justify-content:space-between;min-height:56px;padding:0 16px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-header-right-side{display:inline-flex;flex-shrink:0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-title{font-family:Roboto,Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;-webkit-hyphens:auto;hyphens:auto;margin:auto 0;overflow-wrap:anywhere;padding:10px 0;text-overflow:ellipsis}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{align-self:flex-start;flex-shrink:0;font-size:14px;font-weight:400;line-height:20px;padding:18px 0 0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{cursor:pointer;display:none;margin:auto 0 auto 8px;padding:0 4px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button.e-font-icon-svg{height:1em;width:1em}.elementor-widget-video-playlist .e-tabs-header .rotate-up{transform:rotate(-180deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-header .rotate-down{transform:rotate(0deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-items-wrapper{background-color:var(--e-a-bg-default);height:100%;overflow:hidden;position:relative}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{height:100%;overflow:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-section-title{border-color:#d5d8dc;border-width:0;box-sizing:content-box;font-size:14px;height:36px;line-height:36px;margin:0;overflow:hidden;padding:0 16px;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title{background-clip:padding-box;background-color:var(--e-a-bg-default);border-color:#d5d8dc;border-width:0 0 1px;box-sizing:content-box;cursor:pointer;display:flex;font-size:14px;height:55px;line-height:55px;outline:none;padding:0 16px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i{color:#fff;font-size:var(--playlist-item-icon-size,16px);text-shadow:0 0 3px #000}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{color:#fff;text-shadow:0 0 3px #000;fill:#fff;height:var(--playlist-item-icon-size,16px);width:var(--playlist-item-icon-size,16px)}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg path{fill:#fff}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover{background-color:#f1f2f3;border-color:#d5d8dc}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active .e-tab-title-text,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover .e-tab-title-text{font-size:14px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-play,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched{display:inline-flex}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail{background-color:#d5d8dc;flex-shrink:0;height:42px;margin:auto 0;position:relative;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail img{height:42px;-o-object-fit:fill;object-fit:fill;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail svg{bottom:4px;font-weight:900;position:absolute;right:4px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text{flex-grow:1;font-size:14px;margin:auto 8px;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text button{background:none;border:none;border-radius:0;padding:0;text-align:start;transition-duration:unset;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{margin:auto 0;vertical-align:middle}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-duration{font-size:14px;margin:auto 0}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-play{display:none}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-watched{display:block}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-top{background:linear-gradient(0deg,transparent,#fff);display:none;height:98px;pointer-events:none;position:absolute;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-bottom{background:linear-gradient(180deg,transparent,#fff);bottom:0;display:none;height:98px;pointer-events:none;position:absolute;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper.bottom-shadow .shadow-bottom,.elementor-widget-video-playlist .e-tabs-items-wrapper.top-shadow .shadow-top{display:block}.elementor-widget-video-playlist .e-tabs-content-wrapper{flex-grow:1;height:100%;position:relative}.elementor-widget-video-playlist .e-tabs-content-wrapper .elementor-custom-embed-image-overlay{background-position:50%;background-size:cover;cursor:pointer;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-mobile-title{display:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content{background-color:#000;display:none;height:100%;outline:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content>div{height:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content iframe{display:flex;height:100%;max-height:100%!important}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content video{background-color:#000;height:100%}.elementor-widget-video-playlist .e-tabs-inner-tabs .e-tab-content{display:none;outline:none}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-video-playlist .e-tabs-main-area{flex-direction:column-reverse;height:auto}.elementor-widget-video-playlist .e-tabs-main-area .e-tabs-content-wrapper{border:none;height:38%}.elementor-widget-video-playlist .e-tabs-wrapper{height:62%;width:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{max-height:248px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items .e-tab-title{border:none}.elementor-widget-video-playlist .e-tabs-header{min-height:48px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{display:inline-flex}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{margin:0 6px;padding:14px 0 0}.elementor-widget-video-playlist .e-tab-content{border:none;display:flex;padding:0}} \ No newline at end of file diff --git a/assets/css/templates/widget-video-playlist.min.css b/assets/css/templates/widget-video-playlist.min.css new file mode 100644 index 00000000..b31dd1a9 --- /dev/null +++ b/assets/css/templates/widget-video-playlist.min.css @@ -0,0 +1 @@ +.e-tabs-inner-tabs{font-size:16px;text-align:start}.e-tabs-inner-tabs .e-tab-content{padding-top:32px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:flex;overflow:hidden;position:relative;z-index:1}.e-tabs-inner-tabs .e-inner-tabs-wrapper :after{background-color:var(--inner-tabs-border-color,#d5d8dc);bottom:0;content:"";height:var(--inner-tabs-border-height,1px);position:absolute;width:100%;z-index:-1}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title{box-sizing:content-box;font-weight:700;height:38px;line-height:38px;min-width:140px}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a{color:#3f444b;display:block;padding:0 36px;text-align:center}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active{border-color:#0c0d0e #0c0d0e transparent;border-bottom:1px solid #0c0d0e;border-left-width:0;border-right-width:0;border-top-width:0}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active a{color:#0c0d0e}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{display:none;padding:20px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text{color:#1f2124}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.e-inner-tab-active{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons{display:none;margin-top:24px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons button{background:transparent;border:none;display:none;font-weight:500;line-height:24px;padding:0;text-decoration:underline}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible .e-inner-tab-text{overflow:hidden}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button.show-button,.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible.show-inner-tab-buttons .e-inner-tab-buttons{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.show-full-height div.e-inner-tab-text{height:auto}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-tabs-inner-tabs>.e-tab-content:first-child{padding-top:24px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper{border:solid #d5d8dc;border-width:1px 1px 0}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{border:solid #d5d8dc;border-width:0 0 1px;cursor:pointer;display:block;font-size:16px;font-weight:700;height:38px;line-height:38px;overflow:hidden;padding:0 10px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{border:solid #d5d8dc;border-width:0 0 1px;padding:20px}}.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:row}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:column-reverse}}.elementor-widget-video-playlist .e-tabs{display:flex;flex-direction:column}.elementor-widget-video-playlist .e-tabs-main-area{display:flex;flex-direction:row-reverse;height:434px}.elementor-widget-video-playlist .e-tabs-wrapper{display:flex;flex-direction:column;height:100%;width:33%}.elementor-widget-video-playlist .e-tabs-header{background-color:var(--e-a-bg-default);border-bottom:1px solid #d5d8dc;display:flex;flex:0 0 auto;justify-content:space-between;min-height:56px;padding:0 16px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-header-right-side{display:inline-flex;flex-shrink:0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-title{font-family:Roboto,Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;-webkit-hyphens:auto;hyphens:auto;margin:auto 0;overflow-wrap:anywhere;padding:10px 0;text-overflow:ellipsis}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{align-self:flex-start;flex-shrink:0;font-size:14px;font-weight:400;line-height:20px;padding:18px 0 0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{cursor:pointer;display:none;margin:auto 0 auto 8px;padding:0 4px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button.e-font-icon-svg{height:1em;width:1em}.elementor-widget-video-playlist .e-tabs-header .rotate-up{transform:rotate(-180deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-header .rotate-down{transform:rotate(0deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-items-wrapper{background-color:var(--e-a-bg-default);height:100%;overflow:hidden;position:relative}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{height:100%;overflow:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-section-title{border-color:#d5d8dc;border-width:0;box-sizing:content-box;font-size:14px;height:36px;line-height:36px;margin:0;overflow:hidden;padding:0 16px;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title{background-clip:padding-box;background-color:var(--e-a-bg-default);border-color:#d5d8dc;border-width:0 0 1px;box-sizing:content-box;cursor:pointer;display:flex;font-size:14px;height:55px;line-height:55px;outline:none;padding:0 16px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i{color:#fff;font-size:var(--playlist-item-icon-size,16px);text-shadow:0 0 3px #000}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{color:#fff;text-shadow:0 0 3px #000;fill:#fff;height:var(--playlist-item-icon-size,16px);width:var(--playlist-item-icon-size,16px)}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg path{fill:#fff}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover{background-color:#f1f2f3;border-color:#d5d8dc}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active .e-tab-title-text,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover .e-tab-title-text{font-size:14px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-play,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched{display:inline-flex}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail{background-color:#d5d8dc;flex-shrink:0;height:42px;margin:auto 0;position:relative;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail img{height:42px;-o-object-fit:fill;object-fit:fill;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail svg{bottom:4px;font-weight:900;position:absolute;right:4px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text{flex-grow:1;font-size:14px;margin:auto 8px;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text button{background:none;border:none;border-radius:0;padding:0;text-align:start;transition-duration:unset;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{margin:auto 0;vertical-align:middle}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-duration{font-size:14px;margin:auto 0}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-play{display:none}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-watched{display:block}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-top{background:linear-gradient(0deg,transparent,#fff);display:none;height:98px;pointer-events:none;position:absolute;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-bottom{background:linear-gradient(180deg,transparent,#fff);bottom:0;display:none;height:98px;pointer-events:none;position:absolute;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper.bottom-shadow .shadow-bottom,.elementor-widget-video-playlist .e-tabs-items-wrapper.top-shadow .shadow-top{display:block}.elementor-widget-video-playlist .e-tabs-content-wrapper{flex-grow:1;height:100%;position:relative}.elementor-widget-video-playlist .e-tabs-content-wrapper .elementor-custom-embed-image-overlay{background-position:50%;background-size:cover;cursor:pointer;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-mobile-title{display:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content{background-color:#000;display:none;height:100%;outline:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content>div{height:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content iframe{display:flex;height:100%;max-height:100%!important}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content video{background-color:#000;height:100%}.elementor-widget-video-playlist .e-tabs-inner-tabs .e-tab-content{display:none;outline:none}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-video-playlist .e-tabs-main-area{flex-direction:column-reverse;height:auto}.elementor-widget-video-playlist .e-tabs-main-area .e-tabs-content-wrapper{border:none;height:38%}.elementor-widget-video-playlist .e-tabs-wrapper{height:62%;width:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{max-height:248px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items .e-tab-title{border:none}.elementor-widget-video-playlist .e-tabs-header{min-height:48px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{display:inline-flex}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{margin:0 6px;padding:14px 0 0}.elementor-widget-video-playlist .e-tab-content{border:none;display:flex;padding:0}} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-cart-rtl.min.css b/assets/css/templates/widget-woocommerce-cart-rtl.min.css new file mode 100644 index 00000000..e282ff38 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-cart-rtl.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-cart.e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart table tbody tr:hover>td,.elementor-widget-woocommerce-cart table tbody tr:hover>th{background-color:inherit}.elementor-widget-woocommerce-cart .e-clear{height:0;overflow:hidden;width:0}.elementor-widget-woocommerce-cart .e-cart-section{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;margin:var(--sections-margin,0 0 30px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-cart .e-cart-section--no-coupon{margin:var(--sections-margin,0 0 0 0)}@media (min-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .e-cart-section:last-child{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-cart .e-cart-content{color:var(--sections-descriptions-color,#69727d);font-size:15px;font-weight:400;letter-spacing:0;line-height:23px}.elementor-widget-woocommerce-cart .e-cart__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:59% auto;grid-column-gap:var(--sections-margin,30px);grid-row-gap:var(--sections-margin,30px)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .e-cart__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-cart .e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart .select2-container{margin-bottom:4px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,initial);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-inline:1rem}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-cart .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-cart .woocommerce{font-family:Roboto,sans-serif}.elementor-widget-woocommerce-cart .woocommerce button.button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem);width:var(--forms-buttons-width,auto)}.elementor-widget-woocommerce-cart .woocommerce button.button:hover{border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]{color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]:hover{background-color:var(--forms-buttons-hover-background-color,#fff);border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li input{vertical-align:middle}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form{margin-top:var(--sections-descriptions-spacing,15px)}.elementor-widget-woocommerce-cart .woocommerce .woocommerce-shipping-destination{color:var(--sections-descriptions-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tbody th,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tbody th{display:none}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td{text-align:start!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before{margin-bottom:10px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td{text-align:end!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td:before{content:attr(data-title);float:inline-start;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{text-align:var(--totals-title-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td{padding-bottom:var(--totals-rows-gap-bottom,9px);padding-top:var(--totals-rows-gap-top,12px)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td .woocommerce-Price-amount,.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td:before{color:var(--totals-color,#69727d);font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table tr.order-total td{border-top-color:var(--totals-divider-color,#69727d);border-top-width:var(--totals-divider-weight,0)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .form-row{margin-bottom:var(--forms-rows-gap,6px)}.elementor-widget-woocommerce-cart .woocommerce .product-name a{color:var(--product-link-normal-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .product-name a:hover{color:var(--product-link-hover-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .form-row{margin:0;padding:3px 0}.elementor-widget-woocommerce-cart .woocommerce .input-text,.elementor-widget-woocommerce-cart .woocommerce select{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,3px);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-cart .woocommerce .input-text::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text::placeholder,.elementor-widget-woocommerce-cart .woocommerce select::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus,.elementor-widget-woocommerce-cart .woocommerce select:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,transparent);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::-moz-placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text.qty{background-color:transparent;border-color:var(--order-summary-quantity-border-color,#d5d8dc);border-radius:3px;border-style:solid;border-width:var(--order-summary-quantity-border-weight,1px);color:var(--order-summary-color,#000);font-size:14px;max-height:28px;min-height:28px;padding:1px 2px;text-align:start}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;padding-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button{background-color:#5bc0de;border-radius:var(--checkout-button-border-radius,3px);color:var(--checkout-button-normal-text-color,#fff);font-size:15px;margin-bottom:0;min-height:auto;padding:var(--checkout-button-padding,15px 1em);text-align:center;width:var(--checkout-button-width,auto)}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button:hover{background-color:#5bc0de;border-color:var(--checkout-button-hover-border-color,#5bc0de);color:var(--checkout-button-hover-text-color,#fff);transition-duration:var(--checkout-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .remove{background:transparent;color:var(--order-summary-remove-icon-normal-color,#000)!important;width:auto}.elementor-widget-woocommerce-cart .woocommerce .remove:hover{background:transparent;color:var(--order-summary-remove-icon-hover-color,#5bc0de)!important}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals{float:none;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals td{padding-inline-start:0}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals .woocommerce-shipping-totals td{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:inline-end;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .form-row{padding:0}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:flex}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{flex:2;padding-inline-end:30px}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{padding-inline-end:0}}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{flex:1}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{text-align:var(--apply-coupon-button-alignment,center)}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:block}.elementor-widget-woocommerce-cart .woocommerce .coupon{margin:var(--sections-margin,0)}.elementor-widget-woocommerce-cart .woocommerce .coupon #coupon_code{margin-inline-end:0;margin-bottom:15px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:none;width:var(--apply-coupon-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .button{float:inline-start;font-size:14px;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions{display:table-cell;text-align:var(--update-cart-button-alignment,start)!important}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{display:inline-block!important;float:none;width:var(--update-cart-button-width,auto)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{width:var(--update-cart-button-width,100%)!important}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form p:last-of-type{text-align:var(--update-shipping-button-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{float:none;width:var(--update-shipping-button-width,auto)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{width:var(--update-shipping-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table th,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .actions{padding:16px 0 0}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .product-remove a{display:inline-block}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart tbody tr:last-child{display:var(--update-cart-automatically-display,table-row)}.elementor-widget-woocommerce-cart .woocommerce table.cart{margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce table.cart img{display:block;height:auto;width:55px}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-bottom:var(--order-summary-rows-gap-bottom,20px);padding-top:var(--order-summary-rows-gap-top,20px);padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce table.cart td span{color:var(--order-summary-color,#000);font-size:14px;font-weight:400}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top:var(--order-summary-items-divider-weight,1px) solid var(--order-summary-items-divider-color,#d5d8dc)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MIN){.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top-width:0}}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove{padding-inline:0}@media (min-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart tbody tr:first-child td{border-top:none}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart.product-remove{position:relative}.elementor-widget-woocommerce-cart .woocommerce table.cart.product-name{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{border-top-color:var(--order-summary-items-divider-color,#d5d8dc);border-top-width:var(--order-summary-items-divider-weight,1px)}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MIN){.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart{padding:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{padding:16px 28px}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions{padding:0}}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward){color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward):hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce .cart th,.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{font-size:14px;font-weight:700;margin-top:0;padding-bottom:8px;padding-top:0;padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{color:var(--sections-title-color,#000);margin-bottom:var(--sections-title-spacing,1rem)}.elementor-widget-woocommerce-cart .woocommerce .cart th{color:var(--order-summary-title-color,#000);padding-bottom:var(--order-summary-title-spacing,8px)}.elementor-widget-woocommerce-cart .woocommerce .cart td:before{color:var(--order-summary-title-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-button:after{display:none}.elementor-widget-woocommerce-cart .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table_responsive tr:nth-child(2n) td,.elementor-widget-woocommerce-cart .woocommerce-page table.shop_table_responsive tr:nth-child(2n) td{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .shop_table_responsive td{padding-inline-start:0}}.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce #shipping_method input,.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form button[name=calc_shipping]{pointer-events:none}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-cart.min.css b/assets/css/templates/widget-woocommerce-cart.min.css new file mode 100644 index 00000000..e282ff38 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-cart.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-cart.e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart table tbody tr:hover>td,.elementor-widget-woocommerce-cart table tbody tr:hover>th{background-color:inherit}.elementor-widget-woocommerce-cart .e-clear{height:0;overflow:hidden;width:0}.elementor-widget-woocommerce-cart .e-cart-section{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;margin:var(--sections-margin,0 0 30px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-cart .e-cart-section--no-coupon{margin:var(--sections-margin,0 0 0 0)}@media (min-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .e-cart-section:last-child{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-cart .e-cart-content{color:var(--sections-descriptions-color,#69727d);font-size:15px;font-weight:400;letter-spacing:0;line-height:23px}.elementor-widget-woocommerce-cart .e-cart__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:59% auto;grid-column-gap:var(--sections-margin,30px);grid-row-gap:var(--sections-margin,30px)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .e-cart__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-cart .e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart .select2-container{margin-bottom:4px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,initial);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-inline:1rem}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-cart .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-cart .woocommerce{font-family:Roboto,sans-serif}.elementor-widget-woocommerce-cart .woocommerce button.button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem);width:var(--forms-buttons-width,auto)}.elementor-widget-woocommerce-cart .woocommerce button.button:hover{border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]{color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]:hover{background-color:var(--forms-buttons-hover-background-color,#fff);border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li input{vertical-align:middle}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form{margin-top:var(--sections-descriptions-spacing,15px)}.elementor-widget-woocommerce-cart .woocommerce .woocommerce-shipping-destination{color:var(--sections-descriptions-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tbody th,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tbody th{display:none}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td{text-align:start!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before{margin-bottom:10px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td{text-align:end!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td:before{content:attr(data-title);float:inline-start;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{text-align:var(--totals-title-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td{padding-bottom:var(--totals-rows-gap-bottom,9px);padding-top:var(--totals-rows-gap-top,12px)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td .woocommerce-Price-amount,.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td:before{color:var(--totals-color,#69727d);font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table tr.order-total td{border-top-color:var(--totals-divider-color,#69727d);border-top-width:var(--totals-divider-weight,0)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .form-row{margin-bottom:var(--forms-rows-gap,6px)}.elementor-widget-woocommerce-cart .woocommerce .product-name a{color:var(--product-link-normal-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .product-name a:hover{color:var(--product-link-hover-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .form-row{margin:0;padding:3px 0}.elementor-widget-woocommerce-cart .woocommerce .input-text,.elementor-widget-woocommerce-cart .woocommerce select{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,3px);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-cart .woocommerce .input-text::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text::placeholder,.elementor-widget-woocommerce-cart .woocommerce select::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus,.elementor-widget-woocommerce-cart .woocommerce select:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,transparent);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::-moz-placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text.qty{background-color:transparent;border-color:var(--order-summary-quantity-border-color,#d5d8dc);border-radius:3px;border-style:solid;border-width:var(--order-summary-quantity-border-weight,1px);color:var(--order-summary-color,#000);font-size:14px;max-height:28px;min-height:28px;padding:1px 2px;text-align:start}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;padding-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button{background-color:#5bc0de;border-radius:var(--checkout-button-border-radius,3px);color:var(--checkout-button-normal-text-color,#fff);font-size:15px;margin-bottom:0;min-height:auto;padding:var(--checkout-button-padding,15px 1em);text-align:center;width:var(--checkout-button-width,auto)}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button:hover{background-color:#5bc0de;border-color:var(--checkout-button-hover-border-color,#5bc0de);color:var(--checkout-button-hover-text-color,#fff);transition-duration:var(--checkout-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .remove{background:transparent;color:var(--order-summary-remove-icon-normal-color,#000)!important;width:auto}.elementor-widget-woocommerce-cart .woocommerce .remove:hover{background:transparent;color:var(--order-summary-remove-icon-hover-color,#5bc0de)!important}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals{float:none;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals td{padding-inline-start:0}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals .woocommerce-shipping-totals td{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:inline-end;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .form-row{padding:0}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:flex}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{flex:2;padding-inline-end:30px}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{padding-inline-end:0}}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{flex:1}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{text-align:var(--apply-coupon-button-alignment,center)}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:block}.elementor-widget-woocommerce-cart .woocommerce .coupon{margin:var(--sections-margin,0)}.elementor-widget-woocommerce-cart .woocommerce .coupon #coupon_code{margin-inline-end:0;margin-bottom:15px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:none;width:var(--apply-coupon-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .button{float:inline-start;font-size:14px;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions{display:table-cell;text-align:var(--update-cart-button-alignment,start)!important}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{display:inline-block!important;float:none;width:var(--update-cart-button-width,auto)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{width:var(--update-cart-button-width,100%)!important}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form p:last-of-type{text-align:var(--update-shipping-button-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{float:none;width:var(--update-shipping-button-width,auto)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{width:var(--update-shipping-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table th,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .actions{padding:16px 0 0}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .product-remove a{display:inline-block}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart tbody tr:last-child{display:var(--update-cart-automatically-display,table-row)}.elementor-widget-woocommerce-cart .woocommerce table.cart{margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce table.cart img{display:block;height:auto;width:55px}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-bottom:var(--order-summary-rows-gap-bottom,20px);padding-top:var(--order-summary-rows-gap-top,20px);padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce table.cart td span{color:var(--order-summary-color,#000);font-size:14px;font-weight:400}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top:var(--order-summary-items-divider-weight,1px) solid var(--order-summary-items-divider-color,#d5d8dc)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MIN){.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top-width:0}}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove{padding-inline:0}@media (min-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart tbody tr:first-child td{border-top:none}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart.product-remove{position:relative}.elementor-widget-woocommerce-cart .woocommerce table.cart.product-name{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{border-top-color:var(--order-summary-items-divider-color,#d5d8dc);border-top-width:var(--order-summary-items-divider-weight,1px)}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MIN){.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-cart .woocommerce table.cart{padding:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{padding:16px 28px}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions{padding:0}}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward){color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward):hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce .cart th,.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{font-size:14px;font-weight:700;margin-top:0;padding-bottom:8px;padding-top:0;padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{color:var(--sections-title-color,#000);margin-bottom:var(--sections-title-spacing,1rem)}.elementor-widget-woocommerce-cart .woocommerce .cart th{color:var(--order-summary-title-color,#000);padding-bottom:var(--order-summary-title-spacing,8px)}.elementor-widget-woocommerce-cart .woocommerce .cart td:before{color:var(--order-summary-title-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-button:after{display:none}.elementor-widget-woocommerce-cart .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-cart .woocommerce table.shop_table_responsive tr:nth-child(2n) td,.elementor-widget-woocommerce-cart .woocommerce-page table.shop_table_responsive tr:nth-child(2n) td{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .shop_table_responsive td{padding-inline-start:0}}.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce #shipping_method input,.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form button[name=calc_shipping]{pointer-events:none}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-checkout-page-rtl.min.css b/assets/css/templates/widget-woocommerce-checkout-page-rtl.min.css new file mode 100644 index 00000000..bf83c226 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-checkout-page-rtl.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-checkout-page{background-color:transparent;color:#69727d;font-family:Roboto,sans-serif;font-size:14px;line-height:21px}.elementor-widget-woocommerce-checkout-page.e-checkout-layout-one-column .e-checkout__container{grid-template-columns:auto}.elementor-widget-woocommerce-checkout-page ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page table tbody tr:hover>td,.elementor-widget-woocommerce-checkout-page table tbody tr:hover>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .e-description{color:var(--sections-descriptions-color,#69727d);font-size:14px;font-weight:400;padding-bottom:var(--sections-descriptions-spacing,0)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section{margin-bottom:24px}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section .e-checkout-secondary-title{text-align:var(--login-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-nudge{margin-bottom:15px;margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor{margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-box{margin-top:24px}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor-description{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .e-login-wrap{align-items:center;display:flex}.elementor-widget-woocommerce-checkout-page .e-login-wrap-start{flex:75%}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{flex:20%;text-align:end}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-login-wrap{display:block}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{margin-top:15px;text-align:var(--login-button-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end label.e-login-label{display:none}}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap{display:flex;justify-content:space-between;margin-top:6px}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:12px;margin-bottom:0}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:11px}}.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:90%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:var(--coupon-button-width,auto)}}.elementor-widget-woocommerce-checkout-page .e-checkout__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:56% auto;grid-column-gap:var(--sections-margin,24px);grid-row-gap:var(--sections-margin,24px)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-checkout__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-checkout-page .e-checkout-secondary-title{color:var(--sections-secondary-title-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-checkout-page .e-woocommerce-coupon-nudge{text-align:var(--coupon-title-alignment,start)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address{margin-top:13px;padding-inline-start:var(--shipping-heading-padding-start,30px)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address span{font-weight:400}.elementor-widget-woocommerce-checkout-page a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row{margin-left:var(--forms-columns-gap-margin,0);margin-right:var(--forms-columns-gap-margin,0);padding-left:var(--forms-columns-gap-padding,0);padding-right:var(--forms-columns-gap-padding,0)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;font-weight:400;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea:focus{background-color:#f9fafa;border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_phone_field input{direction:inherit}.elementor-widget-woocommerce-checkout-page .woocommerce .create-account,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row{margin-bottom:0!important}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li input,.elementor-widget-woocommerce-checkout-page .woocommerce .input-radio{vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__label-for-checkbox span{color:var(--sections-checkboxes-color,#69727d);position:relative;top:2px}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li label,.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{display:inline}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#6f6f6f);padding:1rem}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button:hover{color:var(--forms-buttons-hover-text-color,#6f6f6f);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-right:1%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-bottom:15px;margin-right:0;width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-info{background-color:transparent;border-top-color:transparent;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-privacy-policy-text p{font-size:12px;font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login-toggle .woocommerce-info{font-weight:400;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout__order_review,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-section,.elementor-widget-woocommerce-checkout-page .woocommerce .shipping_address,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment{background:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;display:block;margin:var(--sections-margin,0 0 24px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{display:var(--additional-information-display,none)}@media (min-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout-message,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment .payment_box,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text{color:var(--sections-messages-color,#69727d);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text p{margin-top:25px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-1{margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-2{padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce #order_review_heading{text-align:var(--order-review-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table{border:0;font-size:14px;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead tr th{padding-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td{color:#000}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td .product-quantity{font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot th{color:#69727d}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr{border:0;padding-bottom:15px;padding-left:0;padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total tr{padding-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td{border-bottom:var(--order-summary-items-divider-weight,0) solid var(--order-summary-items-divider-color,#69727d);color:var(--order-summary-items-color,#000);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-name{max-width:150px;padding-inline-end:40px}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-total{vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table th{padding-bottom:var(--order-summary-rows-gap-bottom,15px);padding-top:var(--order-summary-rows-gap-top,15px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot th,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table thead th{color:var(--order-summary-totals-color,#69727d);vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total th{border-top:var(--order-summary-totals-divider-weight,0) solid var(--order-summary-totals-divider-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-totals td{max-width:70px}.elementor-widget-woocommerce-checkout-page .woocommerce h3{color:var(--sections-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--sections-title-spacing,30px);margin-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row>span{color:#69727d;font-size:14px;font-weight:400;margin-bottom:3px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:48%}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row .input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields h3{text-align:var(--billing-details-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row{margin-bottom:var(--forms-rows-gap,5px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row:last-child{margin-bottom:15px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout.login{background:#fff;border-top-width:0;color:#69727d;margin-bottom:0;margin-top:-8px;position:relative;z-index:999}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-form-coupon-toggle{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:85%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:var(--login-button-width,35%)}}.elementor-widget-woocommerce-checkout-page .woocommerce-additional-fields h3{text-align:var(--additional-fields-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-fields .shipping_address{margin-bottom:var(--sections-margin,20px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment{margin-top:24px;padding:15px 25px 25px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods{border-bottom:none;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li{line-height:21px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{font-size:12px;padding-inline-start:15px}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{float:none;font-size:11px;padding-left:10px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label img{width:55px}}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .place-order{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;margin-bottom:0;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order{background-color:#5bc0de;border-radius:var(--purchase-button-border-radius,3px);color:var(--purchase-button-normal-text-color,#fff);float:none;min-height:auto;padding:var(--purchase-button-padding,1em 1em);width:var(--purchase-button-width,auto)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order:hover{background-color:#5bc0de;border-color:var(--purchase-button-hover-border-color,#5bc0de);color:var(--purchase-button-hover-text-color,#fff);transition-duration:var(--purchase-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .woocommerce-info:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-2{float:none;width:auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{align-items:center;display:grid;grid-template-columns:auto auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:end}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{display:block}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:var(--coupon-button-alignment,start)}}.elementor-widget-woocommerce-checkout-page .woocommerce #account_password_field{margin-bottom:10px}.elementor-widget-woocommerce-checkout-page .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000);font-size:14px;font-style:normal;letter-spacing:normal;line-height:21px;text-decoration:none;text-transform:none}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-checkout-page.min.css b/assets/css/templates/widget-woocommerce-checkout-page.min.css new file mode 100644 index 00000000..bf83c226 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-checkout-page.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-checkout-page{background-color:transparent;color:#69727d;font-family:Roboto,sans-serif;font-size:14px;line-height:21px}.elementor-widget-woocommerce-checkout-page.e-checkout-layout-one-column .e-checkout__container{grid-template-columns:auto}.elementor-widget-woocommerce-checkout-page ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page table tbody tr:hover>td,.elementor-widget-woocommerce-checkout-page table tbody tr:hover>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .e-description{color:var(--sections-descriptions-color,#69727d);font-size:14px;font-weight:400;padding-bottom:var(--sections-descriptions-spacing,0)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section{margin-bottom:24px}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section .e-checkout-secondary-title{text-align:var(--login-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-nudge{margin-bottom:15px;margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor{margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-box{margin-top:24px}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor-description{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .e-login-wrap{align-items:center;display:flex}.elementor-widget-woocommerce-checkout-page .e-login-wrap-start{flex:75%}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{flex:20%;text-align:end}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-login-wrap{display:block}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{margin-top:15px;text-align:var(--login-button-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end label.e-login-label{display:none}}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap{display:flex;justify-content:space-between;margin-top:6px}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:12px;margin-bottom:0}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:11px}}.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:90%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:var(--coupon-button-width,auto)}}.elementor-widget-woocommerce-checkout-page .e-checkout__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:56% auto;grid-column-gap:var(--sections-margin,24px);grid-row-gap:var(--sections-margin,24px)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .e-checkout__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-checkout-page .e-checkout-secondary-title{color:var(--sections-secondary-title-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-checkout-page .e-woocommerce-coupon-nudge{text-align:var(--coupon-title-alignment,start)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address{margin-top:13px;padding-inline-start:var(--shipping-heading-padding-start,30px)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address span{font-weight:400}.elementor-widget-woocommerce-checkout-page a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row{margin-left:var(--forms-columns-gap-margin,0);margin-right:var(--forms-columns-gap-margin,0);padding-left:var(--forms-columns-gap-padding,0);padding-right:var(--forms-columns-gap-padding,0)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;font-weight:400;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea:focus{background-color:#f9fafa;border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_phone_field input{direction:inherit}.elementor-widget-woocommerce-checkout-page .woocommerce .create-account,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row{margin-bottom:0!important}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li input,.elementor-widget-woocommerce-checkout-page .woocommerce .input-radio{vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__label-for-checkbox span{color:var(--sections-checkboxes-color,#69727d);position:relative;top:2px}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li label,.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{display:inline}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#6f6f6f);padding:1rem}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button:hover{color:var(--forms-buttons-hover-text-color,#6f6f6f);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-right:1%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-bottom:15px;margin-right:0;width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-info{background-color:transparent;border-top-color:transparent;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-privacy-policy-text p{font-size:12px;font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login-toggle .woocommerce-info{font-weight:400;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout__order_review,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-section,.elementor-widget-woocommerce-checkout-page .woocommerce .shipping_address,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment{background:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;display:block;margin:var(--sections-margin,0 0 24px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{display:var(--additional-information-display,none)}@media (min-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout-message,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment .payment_box,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text{color:var(--sections-messages-color,#69727d);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text p{margin-top:25px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-1{margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-2{padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce #order_review_heading{text-align:var(--order-review-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table{border:0;font-size:14px;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead tr th{padding-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td{color:#000}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td .product-quantity{font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot th{color:#69727d}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr{border:0;padding-bottom:15px;padding-left:0;padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total tr{padding-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td{border-bottom:var(--order-summary-items-divider-weight,0) solid var(--order-summary-items-divider-color,#69727d);color:var(--order-summary-items-color,#000);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-name{max-width:150px;padding-inline-end:40px}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-total{vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table th{padding-bottom:var(--order-summary-rows-gap-bottom,15px);padding-top:var(--order-summary-rows-gap-top,15px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot th,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table thead th{color:var(--order-summary-totals-color,#69727d);vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total th{border-top:var(--order-summary-totals-divider-weight,0) solid var(--order-summary-totals-divider-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-totals td{max-width:70px}.elementor-widget-woocommerce-checkout-page .woocommerce h3{color:var(--sections-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--sections-title-spacing,30px);margin-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row>span{color:#69727d;font-size:14px;font-weight:400;margin-bottom:3px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:48%}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row .input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields h3{text-align:var(--billing-details-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row{margin-bottom:var(--forms-rows-gap,5px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row:last-child{margin-bottom:15px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout.login{background:#fff;border-top-width:0;color:#69727d;margin-bottom:0;margin-top:-8px;position:relative;z-index:999}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-form-coupon-toggle{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:85%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:var(--login-button-width,35%)}}.elementor-widget-woocommerce-checkout-page .woocommerce-additional-fields h3{text-align:var(--additional-fields-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-fields .shipping_address{margin-bottom:var(--sections-margin,20px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment{margin-top:24px;padding:15px 25px 25px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods{border-bottom:none;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li{line-height:21px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{font-size:12px;padding-inline-start:15px}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{float:none;font-size:11px;padding-left:10px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label img{width:55px}}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .place-order{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;margin-bottom:0;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order{background-color:#5bc0de;border-radius:var(--purchase-button-border-radius,3px);color:var(--purchase-button-normal-text-color,#fff);float:none;min-height:auto;padding:var(--purchase-button-padding,1em 1em);width:var(--purchase-button-width,auto)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order:hover{background-color:#5bc0de;border-color:var(--purchase-button-hover-border-color,#5bc0de);color:var(--purchase-button-hover-text-color,#fff);transition-duration:var(--purchase-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .woocommerce-info:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-2{float:none;width:auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{align-items:center;display:grid;grid-template-columns:auto auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:end}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{display:block}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:var(--coupon-button-alignment,start)}}.elementor-widget-woocommerce-checkout-page .woocommerce #account_password_field{margin-bottom:10px}.elementor-widget-woocommerce-checkout-page .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000);font-size:14px;font-style:normal;letter-spacing:normal;line-height:21px;text-decoration:none;text-transform:none}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-menu-cart-rtl.min.css b/assets/css/templates/widget-woocommerce-menu-cart-rtl.min.css new file mode 100644 index 00000000..e48332dd --- /dev/null +++ b/assets/css/templates/widget-woocommerce-menu-cart-rtl.min.css @@ -0,0 +1 @@ +.elementor-menu-cart__wrapper{text-align:var(--main-alignment,start)}.elementor-menu-cart__toggle_wrapper{display:inline-block;position:relative}.elementor-menu-cart__toggle{display:inline-block}.elementor-menu-cart__toggle .elementor-button{align-items:center;background-color:var(--toggle-button-background-color,transparent);border-color:var(--toggle-button-border-color,#69727d);border-radius:var(--toggle-button-border-radius,0);border-style:var(--toggle-button-border-type,solid);border-width:var(--toggle-button-border-width,1px);color:var(--toggle-button-text-color,#69727d);display:inline-flex;flex-direction:row;gap:.3em;padding:var(--toggle-icon-padding,12px 24px)}.elementor-menu-cart__toggle .elementor-button:hover{background-color:var(--toggle-button-hover-background-color,transparent);border-color:var(--toggle-button-hover-border-color,#69727d);color:var(--toggle-button-hover-text-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover .elementor-button-icon{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover svg{fill:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button svg{fill:var(--toggle-button-icon-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon{position:relative;transition:color .1s}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon,.elementor-menu-cart__toggle .elementor-button-icon{color:var(--toggle-button-icon-color,#69727d);font-size:var(--toggle-icon-size,inherit)}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon:hover{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon,.elementor-menu-cart__toggle .elementor-button-text{flex-grow:unset;order:unset}.elementor-menu-cart--items-indicator-bubble .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{background-color:var(--items-indicator-background-color,#d9534f);border-radius:100%;color:var(--items-indicator-text-color,#fff);display:block;font-size:10px;height:1.6em;inset-inline-end:-.7em;line-height:1.5em;min-width:1.6em;position:absolute;text-align:center;top:-.7em}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon{align-items:center;display:flex}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon i,.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon svg{line-height:unset}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:inline-block;font-weight:400}.elementor-menu-cart--items-indicator-none .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:none}.elementor-menu-cart__container{background-color:rgba(0,0,0,.25);height:100%;left:0;overflow:hidden;position:fixed;text-align:start;top:0;transform:scale(1);transition:background-color .4s,transform 0s;width:100vw;z-index:9998}.elementor-menu-cart__main{align-items:stretch;background-color:var(--cart-background-color,#fff);border-color:var(--cart-border-color,initial);border-radius:var(--cart-border-radius,0);border-style:var(--cart-border-style,none);bottom:0;box-shadow:0 0 20px rgba(0,0,0,.2);display:flex;flex-direction:column;font-size:14px;left:var(--side-cart-alignment-left,0);margin-top:var(--mini-cart-spacing,0);max-width:100%;min-height:200px;padding:var(--cart-padding,20px 30px);position:fixed;right:var(--side-cart-alignment-right,auto);top:0;transform:translateX(0);transition:.3s;width:350px}.elementor-menu-cart__main .widget_shopping_cart_content{display:flex;flex-direction:column;height:100%}.elementor-menu-cart__main .widget_shopping_cart_content .woocommerce-mini-cart__empty-message{color:var(--empty-message-color,inherit);text-align:var(--empty-message-alignment,start)}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{background-color:transparent;transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container .dialog-lightbox-close-button{display:none}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;overflow:hidden;transform:var(--side-cart-alignment-transform,translateX(calc(100% * var(--direction-multiplier, 1))))}.elementor-menu-cart__close-button{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;height:var(--cart-close-icon-size,25px);line-height:1;margin:0 0 20px;position:relative;transition:.3s;width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button:after,.elementor-menu-cart__close-button:before{background:var(--cart-close-button-color,#69727d);border-radius:1px;content:"";height:3px;left:0;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:100%}.elementor-menu-cart__close-button:hover:after,.elementor-menu-cart__close-button:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button:before{transform:rotate(45deg)}.elementor-menu-cart__close-button:after{transform:rotate(-45deg)}.elementor-menu-cart__close-button-custom{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;line-height:1;margin:0 0 20px;position:relative;transition:.3s}.elementor-menu-cart__close-button-custom:hover:after,.elementor-menu-cart__close-button-custom:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon{color:var(--cart-close-button-color,#69727d);font-size:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon:hover{color:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom svg{fill:var(--cart-close-button-color,#69727d);height:var(--cart-close-icon-size,25px);width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom svg:hover{fill:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__products{max-height:calc(100vh - 250px);overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.elementor-menu-cart__product{border-bottom-color:var(--divider-color,#d5d8dc);border-bottom-style:var(--divider-style,solid);border-width:0 0 var(--divider-width,1px);display:grid;grid-template-columns:28% auto;grid-template-rows:var(--price-quantity-position--grid-template-rows,auto auto);position:relative}.elementor-menu-cart__product .variation{color:var(--product-variations-color,#1f2124);display:grid;grid-template-columns:max-content auto;margin:10px 0}.elementor-menu-cart__product .variation dt{grid-column-start:1}.elementor-menu-cart__product .variation dd{grid-column-start:2;margin-inline-start:5px}.elementor-menu-cart__product .variation dd p{margin-bottom:0}.elementor-menu-cart__product-image{grid-row-end:3;grid-row-start:1;width:100%}.elementor-menu-cart__product-image a,.elementor-menu-cart__product-image img{display:block}.elementor-menu-cart__product-name{grid-column-end:3;grid-column-start:2;margin:0}.elementor-menu-cart__product-name a{transition:.3s}.elementor-menu-cart__product-price{align-self:var(--price-quantity-position--align-self,end);color:var(--product-price-color,#d5d8dc);font-weight:300;grid-column-end:3;grid-column-start:2}.elementor-menu-cart__product-name,.elementor-menu-cart__product-price{font-size:14px;padding-inline-start:20px}.elementor-menu-cart__product-remove{border:1px solid var(--remove-item-button-color,#d5d8dc);border-radius:var(--remove-item-button-size,22px);bottom:20px;color:#69727d;height:var(--remove-item-button-size,22px);inset-inline-end:0;overflow:hidden;position:absolute;text-align:center;transition:.3s;width:var(--remove-item-button-size,22px)}.elementor-menu-cart__product-remove:hover{border:1px solid var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:hover:after,.elementor-menu-cart__product-remove:hover:before{background:var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:after,.elementor-menu-cart__product-remove:before{background:var(--remove-item-button-color,#d5d8dc);content:"";height:1px;left:25%;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:50%;z-index:1}.elementor-menu-cart__product-remove:before{transform:rotate(45deg)}.elementor-menu-cart__product-remove:after{transform:rotate(-45deg)}.elementor-menu-cart__product-remove>a{display:block;height:100%;opacity:0;overflow:hidden;position:absolute;width:100%;z-index:2}.elementor-menu-cart__product-remove>a.remove_from_cart_button{display:var(--remove-from-cart-button,block)}.elementor-menu-cart__product-remove>a.elementor_remove_from_cart_button{display:var(--elementor-remove-from-cart-button,none)}.elementor-menu-cart__product:last-child{border:none}.elementor-menu-cart__footer-buttons,.elementor-menu-cart__product:not(:first-of-type),.elementor-menu-cart__subtotal{padding-top:var(--product-divider-gap,20px)}.elementor-menu-cart__product{padding-inline-end:30px}.elementor-menu-cart__product,.elementor-menu-cart__subtotal{padding-bottom:var(--product-divider-gap,20px)}.elementor-menu-cart__subtotal{border-color:var(--subtotal-divider-color,#d5d8dc);border-style:var(--subtotal-divider-style,solid);border-width:var(--subtotal-divider-top-width,1px) var(--subtotal-divider-right-width,1px) var(--subtotal-divider-bottom-width,1px) var(--subtotal-divider-left-width,1px);color:var(--menu-cart-subtotal-color,inherit);font-size:20px;font-weight:600;text-align:var(--menu-cart-subtotal-text-align,center)}.elementor-menu-cart__footer-buttons{display:var(--cart-footer-buttons-alignment-display,grid);font-size:20px;grid-template-columns:var(--cart-footer-layout,1fr 1fr);margin-top:var(--cart-buttons-position-margin,0);text-align:var(--cart-footer-buttons-alignment-text-align,center);grid-column-gap:var(--space-between-buttons,10px);grid-row-gap:var(--space-between-buttons,10px)}.elementor-menu-cart__footer-buttons .elementor-button{border-radius:var(--cart-footer-buttons-border-radius,0);display:inline-block;height:-moz-fit-content;height:fit-content}.elementor-menu-cart__footer-buttons .elementor-button--view-cart{background-color:var(--view-cart-button-background-color,#69727d);color:var(--view-cart-button-text-color,#fff);display:var(--view-cart-button-display,inline-block);padding:var(--view-cart-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover{background-color:var(--view-cart-button-hover-background-color,#69727d);color:var(--view-cart-button-hover-text-color,#fff)}.elementor-menu-cart__footer-buttons .elementor-button--checkout{background-color:var(--checkout-button-background-color,#69727d);color:var(--checkout-button-text-color,#fff);display:var(--checkout-button-display,inline-block);padding:var(--checkout-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--checkout:hover{background-color:var(--checkout-button-hover-background-color,#69727d);color:var(--checkout-button-hover-text-color,#fff)}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-menu-cart__footer-buttons .elementor-button{padding-left:10px;padding-right:10px}}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--empty-indicator-hide .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter="0"],.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-subtotal-yes) .elementor-menu-cart__toggle .elementor-button-text{display:none}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product{grid-template-columns:25% auto;padding-left:0;padding-right:0}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product-remove{display:none}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__product-remove{bottom:auto;top:0}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__products .cart_item:not(:first-of-type) .elementor-menu-cart__product-remove{bottom:auto;top:20px}.elementor-widget-woocommerce-menu-cart.remove-item-position--middle .elementor-menu-cart__product-remove{bottom:50%;transform:translateY(50%)}.elementor-widget-woocommerce-menu-cart.remove-item-position--bottom .elementor-menu-cart__product-remove{bottom:20px;top:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{background:none;bottom:auto;height:auto;min-width:330px;overflow:visible;position:absolute;top:100%;inset-inline:0 auto;transform:scale(1);transition:background-color .4s,transform 0s;width:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__main{height:auto;inset:auto;overflow:visible;position:relative;transform:translateY(0);transition:.3s;width:auto}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{min-width:300px}}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;transform:translateY(-10px)}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown{opacity:1}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown .elementor-menu-cart__container{z-index:9999}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-dropdown .elementor-menu-cart__container{display:none} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-menu-cart.min.css b/assets/css/templates/widget-woocommerce-menu-cart.min.css new file mode 100644 index 00000000..a9e78b9e --- /dev/null +++ b/assets/css/templates/widget-woocommerce-menu-cart.min.css @@ -0,0 +1 @@ +.elementor-menu-cart__wrapper{text-align:var(--main-alignment,start)}.elementor-menu-cart__toggle_wrapper{display:inline-block;position:relative}.elementor-menu-cart__toggle{display:inline-block}.elementor-menu-cart__toggle .elementor-button{align-items:center;background-color:var(--toggle-button-background-color,transparent);border-color:var(--toggle-button-border-color,#69727d);border-radius:var(--toggle-button-border-radius,0);border-style:var(--toggle-button-border-type,solid);border-width:var(--toggle-button-border-width,1px);color:var(--toggle-button-text-color,#69727d);display:inline-flex;flex-direction:row;gap:.3em;padding:var(--toggle-icon-padding,12px 24px)}.elementor-menu-cart__toggle .elementor-button:hover{background-color:var(--toggle-button-hover-background-color,transparent);border-color:var(--toggle-button-hover-border-color,#69727d);color:var(--toggle-button-hover-text-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover .elementor-button-icon{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover svg{fill:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button svg{fill:var(--toggle-button-icon-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon{position:relative;transition:color .1s}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon,.elementor-menu-cart__toggle .elementor-button-icon{color:var(--toggle-button-icon-color,#69727d);font-size:var(--toggle-icon-size,inherit)}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon:hover{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon,.elementor-menu-cart__toggle .elementor-button-text{flex-grow:unset;order:unset}.elementor-menu-cart--items-indicator-bubble .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{background-color:var(--items-indicator-background-color,#d9534f);border-radius:100%;color:var(--items-indicator-text-color,#fff);display:block;font-size:10px;height:1.6em;inset-inline-end:-.7em;line-height:1.5em;min-width:1.6em;position:absolute;text-align:center;top:-.7em}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon{align-items:center;display:flex}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon i,.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon svg{line-height:unset}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:inline-block;font-weight:400}.elementor-menu-cart--items-indicator-none .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:none}.elementor-menu-cart__container{background-color:rgba(0,0,0,.25);height:100%;left:0;overflow:hidden;position:fixed;text-align:start;top:0;transform:scale(1);transition:background-color .4s,transform 0s;width:100vw;z-index:9998}.elementor-menu-cart__main{align-items:stretch;background-color:var(--cart-background-color,#fff);border-color:var(--cart-border-color,initial);border-radius:var(--cart-border-radius,0);border-style:var(--cart-border-style,none);bottom:0;box-shadow:0 0 20px rgba(0,0,0,.2);display:flex;flex-direction:column;font-size:14px;left:var(--side-cart-alignment-left,auto);margin-top:var(--mini-cart-spacing,0);max-width:100%;min-height:200px;padding:var(--cart-padding,20px 30px);position:fixed;right:var(--side-cart-alignment-right,0);top:0;transform:translateX(0);transition:.3s;width:350px}.elementor-menu-cart__main .widget_shopping_cart_content{display:flex;flex-direction:column;height:100%}.elementor-menu-cart__main .widget_shopping_cart_content .woocommerce-mini-cart__empty-message{color:var(--empty-message-color,inherit);text-align:var(--empty-message-alignment,start)}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{background-color:transparent;transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container .dialog-lightbox-close-button{display:none}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;overflow:hidden;transform:var(--side-cart-alignment-transform,translateX(calc(100% * var(--direction-multiplier, 1))))}.elementor-menu-cart__close-button{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;height:var(--cart-close-icon-size,25px);line-height:1;margin:0 0 20px;position:relative;transition:.3s;width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button:after,.elementor-menu-cart__close-button:before{background:var(--cart-close-button-color,#69727d);border-radius:1px;content:"";height:3px;left:0;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:100%}.elementor-menu-cart__close-button:hover:after,.elementor-menu-cart__close-button:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button:before{transform:rotate(45deg)}.elementor-menu-cart__close-button:after{transform:rotate(-45deg)}.elementor-menu-cart__close-button-custom{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;line-height:1;margin:0 0 20px;position:relative;transition:.3s}.elementor-menu-cart__close-button-custom:hover:after,.elementor-menu-cart__close-button-custom:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon{color:var(--cart-close-button-color,#69727d);font-size:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon:hover{color:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom svg{fill:var(--cart-close-button-color,#69727d);height:var(--cart-close-icon-size,25px);width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom svg:hover{fill:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__products{max-height:calc(100vh - 250px);overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.elementor-menu-cart__product{border-bottom-color:var(--divider-color,#d5d8dc);border-bottom-style:var(--divider-style,solid);border-width:0 0 var(--divider-width,1px);display:grid;grid-template-columns:28% auto;grid-template-rows:var(--price-quantity-position--grid-template-rows,auto auto);position:relative}.elementor-menu-cart__product .variation{color:var(--product-variations-color,#1f2124);display:grid;grid-template-columns:max-content auto;margin:10px 0}.elementor-menu-cart__product .variation dt{grid-column-start:1}.elementor-menu-cart__product .variation dd{grid-column-start:2;margin-inline-start:5px}.elementor-menu-cart__product .variation dd p{margin-bottom:0}.elementor-menu-cart__product-image{grid-row-end:3;grid-row-start:1;width:100%}.elementor-menu-cart__product-image a,.elementor-menu-cart__product-image img{display:block}.elementor-menu-cart__product-name{grid-column-end:3;grid-column-start:2;margin:0}.elementor-menu-cart__product-name a{transition:.3s}.elementor-menu-cart__product-price{align-self:var(--price-quantity-position--align-self,end);color:var(--product-price-color,#d5d8dc);font-weight:300;grid-column-end:3;grid-column-start:2}.elementor-menu-cart__product-name,.elementor-menu-cart__product-price{font-size:14px;padding-inline-start:20px}.elementor-menu-cart__product-remove{border:1px solid var(--remove-item-button-color,#d5d8dc);border-radius:var(--remove-item-button-size,22px);bottom:20px;color:#69727d;height:var(--remove-item-button-size,22px);inset-inline-end:0;overflow:hidden;position:absolute;text-align:center;transition:.3s;width:var(--remove-item-button-size,22px)}.elementor-menu-cart__product-remove:hover{border:1px solid var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:hover:after,.elementor-menu-cart__product-remove:hover:before{background:var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:after,.elementor-menu-cart__product-remove:before{background:var(--remove-item-button-color,#d5d8dc);content:"";height:1px;left:25%;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:50%;z-index:1}.elementor-menu-cart__product-remove:before{transform:rotate(45deg)}.elementor-menu-cart__product-remove:after{transform:rotate(-45deg)}.elementor-menu-cart__product-remove>a{display:block;height:100%;opacity:0;overflow:hidden;position:absolute;width:100%;z-index:2}.elementor-menu-cart__product-remove>a.remove_from_cart_button{display:var(--remove-from-cart-button,block)}.elementor-menu-cart__product-remove>a.elementor_remove_from_cart_button{display:var(--elementor-remove-from-cart-button,none)}.elementor-menu-cart__product:last-child{border:none}.elementor-menu-cart__footer-buttons,.elementor-menu-cart__product:not(:first-of-type),.elementor-menu-cart__subtotal{padding-top:var(--product-divider-gap,20px)}.elementor-menu-cart__product{padding-inline-end:30px}.elementor-menu-cart__product,.elementor-menu-cart__subtotal{padding-bottom:var(--product-divider-gap,20px)}.elementor-menu-cart__subtotal{border-color:var(--subtotal-divider-color,#d5d8dc);border-style:var(--subtotal-divider-style,solid);border-width:var(--subtotal-divider-top-width,1px) var(--subtotal-divider-right-width,1px) var(--subtotal-divider-bottom-width,1px) var(--subtotal-divider-left-width,1px);color:var(--menu-cart-subtotal-color,inherit);font-size:20px;font-weight:600;text-align:var(--menu-cart-subtotal-text-align,center)}.elementor-menu-cart__footer-buttons{display:var(--cart-footer-buttons-alignment-display,grid);font-size:20px;grid-template-columns:var(--cart-footer-layout,1fr 1fr);margin-top:var(--cart-buttons-position-margin,0);text-align:var(--cart-footer-buttons-alignment-text-align,center);grid-column-gap:var(--space-between-buttons,10px);grid-row-gap:var(--space-between-buttons,10px)}.elementor-menu-cart__footer-buttons .elementor-button{border-radius:var(--cart-footer-buttons-border-radius,0);display:inline-block;height:-moz-fit-content;height:fit-content}.elementor-menu-cart__footer-buttons .elementor-button--view-cart{background-color:var(--view-cart-button-background-color,#69727d);color:var(--view-cart-button-text-color,#fff);display:var(--view-cart-button-display,inline-block);padding:var(--view-cart-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover{background-color:var(--view-cart-button-hover-background-color,#69727d);color:var(--view-cart-button-hover-text-color,#fff)}.elementor-menu-cart__footer-buttons .elementor-button--checkout{background-color:var(--checkout-button-background-color,#69727d);color:var(--checkout-button-text-color,#fff);display:var(--checkout-button-display,inline-block);padding:var(--checkout-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--checkout:hover{background-color:var(--checkout-button-hover-background-color,#69727d);color:var(--checkout-button-hover-text-color,#fff)}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-menu-cart__footer-buttons .elementor-button{padding-left:10px;padding-right:10px}}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--empty-indicator-hide .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter="0"],.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-subtotal-yes) .elementor-menu-cart__toggle .elementor-button-text{display:none}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product{grid-template-columns:25% auto;padding-left:0;padding-right:0}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product-remove{display:none}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__product-remove{bottom:auto;top:0}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__products .cart_item:not(:first-of-type) .elementor-menu-cart__product-remove{bottom:auto;top:20px}.elementor-widget-woocommerce-menu-cart.remove-item-position--middle .elementor-menu-cart__product-remove{bottom:50%;transform:translateY(50%)}.elementor-widget-woocommerce-menu-cart.remove-item-position--bottom .elementor-menu-cart__product-remove{bottom:20px;top:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{background:none;bottom:auto;height:auto;min-width:330px;overflow:visible;position:absolute;top:100%;inset-inline:0 auto;transform:scale(1);transition:background-color .4s,transform 0s;width:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__main{height:auto;inset:auto;overflow:visible;position:relative;transform:translateY(0);transition:.3s;width:auto}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{min-width:300px}}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;transform:translateY(-10px)}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown{opacity:1}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown .elementor-menu-cart__container{z-index:9999}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-dropdown .elementor-menu-cart__container{display:none} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-my-account-rtl.min.css b/assets/css/templates/widget-woocommerce-my-account-rtl.min.css new file mode 100644 index 00000000..085df912 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-my-account-rtl.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:var(--forms-fields-normal-color,#69727d);font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account{color:#69727d;font-family:Roboto,sans-serif}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{float:inline-end;padding:0;padding-inline-start:var(--tab-content-spacing,6%);width:75%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .shop_table{border:none;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{background-color:var(--sections-background-color,#fff)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content{border:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content-wrapper{border:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details{margin-bottom:40px}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-table--order-downloads{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button:hover{color:var(--tables-button-hover-text-color,#69727d);transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment .payment_methods{border-bottom:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d4d4d4);padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content>div>p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default{background-color:var(--forms-fields-normal-background-color,#f9fafa);border-radius:var(--forms-fields-border-radius,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single{background-color:var(--forms-fields-normal-background-color,#f9fafa);border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px;margin:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single:focus{background-color:var(--forms-fields-focus-background-color,#f9fafa);border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--open .select2-dropdown--below{background-color:var(--forms-fields-normal-background-color,#f9fafa)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-message{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce address{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button.alt:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button:hover{background-color:initial}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce em{color:var(--login-messages-color,#69727d);font-size:12px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row{margin-bottom:var(--forms-rows-gap,6px);margin-left:var(--forms-columns-gap-margin-left,0);margin-right:var(--forms-columns-gap-margin-right,0);padding-left:var(--forms-columns-gap-padding-left,0);padding-right:var(--forms-columns-gap-padding-right,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-privacy-policy-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-privacy-policy-text{color:var(--login-messages-color,#69727d);font-size:12px;margin-bottom:15px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:not([class]),.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register p:not([class]){color:var(--login-messages-color,#69727d);font-size:12px;margin-top:10px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-LostPassword,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-LostPassword{font-size:12px;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:50%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-first,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-last{width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);font-size:14px;padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:nth-child(3){margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__input-checkbox{vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__label-for-checkbox span{color:var(--checkboxes-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tr{border:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h2,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h3{color:var(--typography-section-titles-color,#000);font-weight:400;margin-bottom:var(--section-title-spacing,45px);margin-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .wc-item-meta,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong.wc-item-meta-label{color:var(--variations-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .product-quantity{color:var(--tables-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-order-downloads{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content h2:first-of-type{margin-top:30px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content mark{background-color:transparent;color:var(--general-text-color,#000);font-weight:700}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child th{border-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child th{border-top:0;padding-bottom:var(--tables-titles-spacing,9px);padding-inline-start:0;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>th{background-color:transparent;color:var(--tables-items-color,#69727d);padding-bottom:var(--order-summary-rows-gap-bottom,9px);padding-inline-start:0;padding-top:var(--order-summary-rows-gap-top,9px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table th{border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th span{color:var(--tables-title-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot th{color:var(--tables-title-color,#000);padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-purchase-note td{border-top:none;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);margin-bottom:0;margin-top:0;padding:var(--tables-button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .title h3,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .title h3{float:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address address,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses address{padding:var(--sections-padding,45px 30px 16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .edit,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .edit{float:inline-start;margin-inline-start:var(--edit-link-margin-start,30px);margin-top:var(--edit-link-margin-top,10px);position:absolute}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .u-columns{margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset{border:none;margin-inline-start:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset legend,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset legend{color:var(--general-text-color,#000);font-weight:700;padding:20px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);margin-top:20px;padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination{padding:16px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-OrderUpdates{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:inline-start;width:25%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul{padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li{display:inline-block;list-style-type:none;width:var(--tab-width,100%)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{background-color:var(--tabs-divider-color,#69727d);content:"";display:block;height:var(--tabs-divider-weight,0);position:relative;top:calc(var(--tabs-spacing, 2px) / 2);width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.is-active a{background:#f1f2f3;border-color:var(--tabs-active-border-color,transparent);color:var(--tabs-active-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{background:#f9fafa;border-color:var(--tabs-border-color,transparent);border-radius:var(--tabs-border-radius,0);border-style:var(--tabs-border-type,solid);border-width:0;color:var(--tabs-normal-color,#69727d);display:block;font-size:14px;font-style:normal;font-weight:700;padding:var(--tabs-padding,12px 20px);text-align:var(--tabs-alignment,start)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover{border-color:var(--tabs-hover-border-color,transparent);color:var(--tabs-hover-color,#5bc0de)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{padding:var(--tabs-padding,10px)}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout:after{display:none}.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .shop_table td{line-height:unset;vertical-align:top}.elementor-widget-woocommerce-my-account .woocommerce-MyAccount-paymentMethods .woocommerce-PaymentMethod--actions{text-align:end}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio{vertical-align:middle}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio+label{color:var(--payment-methods-radio-buttons-color,#69727d)}.e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li{margin:calc(var(--tabs-spacing, 2px) / 2) 0}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--dashboard{margin-top:0}.e-my-account-tabs-vertical .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:none;width:100%}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{float:none;padding:var(--tab-content-spacing,50px) 0 0 0;width:100%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.e-my-account-tabs-horizontal .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:flex;justify-content:var(--tabs-container-justify-content,space-between);list-style:none;margin:0;padding:0}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:block}}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{border-inline-end-color:var(--tabs-divider-color,#69727d);border-inline-end-style:solid;border-inline-end-width:var(--tabs-divider-weight,0);display:inline-block;margin:0;padding:0 calc(var(--tabs-spacing, 2px) / 2) 0 calc(var(--tabs-spacing, 2px) / 2);width:var(--tab-width,100%)}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:first-of-type{padding-inline-start:0}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:last-of-type{border-inline-end-width:0;padding-inline-end:0}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block;margin:calc(var(--tabs-spacing, 2px) / 2) 0;width:100%}}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-number a,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-number a{pointer-events:none}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button{opacity:.3;pointer-events:none}.elementor-editor-active .elementor-widget-woocommerce-my-account .woocommerce-MyAccount-content:not(:first-of-type){display:none} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-my-account.min.css b/assets/css/templates/widget-woocommerce-my-account.min.css new file mode 100644 index 00000000..085df912 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-my-account.min.css @@ -0,0 +1 @@ +.e-woo-select2-wrapper .select2-results__option{color:var(--forms-fields-normal-color,#69727d);font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account{color:#69727d;font-family:Roboto,sans-serif}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{float:inline-end;padding:0;padding-inline-start:var(--tab-content-spacing,6%);width:75%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .shop_table{border:none;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{background-color:var(--sections-background-color,#fff)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content{border:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content-wrapper{border:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details{margin-bottom:40px}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-table--order-downloads{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button:hover{color:var(--tables-button-hover-text-color,#69727d);transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment .payment_methods{border-bottom:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d4d4d4);padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content>div>p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default{background-color:var(--forms-fields-normal-background-color,#f9fafa);border-radius:var(--forms-fields-border-radius,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single{background-color:var(--forms-fields-normal-background-color,#f9fafa);border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px;margin:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single:focus{background-color:var(--forms-fields-focus-background-color,#f9fafa);border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--open .select2-dropdown--below{background-color:var(--forms-fields-normal-background-color,#f9fafa)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-message{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce address{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button.alt:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button:hover{background-color:initial}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce em{color:var(--login-messages-color,#69727d);font-size:12px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row{margin-bottom:var(--forms-rows-gap,6px);margin-left:var(--forms-columns-gap-margin-left,0);margin-right:var(--forms-columns-gap-margin-right,0);padding-left:var(--forms-columns-gap-padding-left,0);padding-right:var(--forms-columns-gap-padding-right,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-privacy-policy-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-privacy-policy-text{color:var(--login-messages-color,#69727d);font-size:12px;margin-bottom:15px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:not([class]),.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register p:not([class]){color:var(--login-messages-color,#69727d);font-size:12px;margin-top:10px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-LostPassword,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-LostPassword{font-size:12px;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:50%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-first,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-last{width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);font-size:14px;padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:nth-child(3){margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__input-checkbox{vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__label-for-checkbox span{color:var(--checkboxes-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tr{border:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h2,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h3{color:var(--typography-section-titles-color,#000);font-weight:400;margin-bottom:var(--section-title-spacing,45px);margin-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .wc-item-meta,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong.wc-item-meta-label{color:var(--variations-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .product-quantity{color:var(--tables-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-order-downloads{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content h2:first-of-type{margin-top:30px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content mark{background-color:transparent;color:var(--general-text-color,#000);font-weight:700}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child th{border-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child th{border-top:0;padding-bottom:var(--tables-titles-spacing,9px);padding-inline-start:0;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>th{background-color:transparent;color:var(--tables-items-color,#69727d);padding-bottom:var(--order-summary-rows-gap-bottom,9px);padding-inline-start:0;padding-top:var(--order-summary-rows-gap-top,9px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table th{border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th span{color:var(--tables-title-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot th{color:var(--tables-title-color,#000);padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-purchase-note td{border-top:none;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);margin-bottom:0;margin-top:0;padding:var(--tables-button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .title h3,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .title h3{float:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address address,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses address{padding:var(--sections-padding,45px 30px 16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .edit,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .edit{float:inline-start;margin-inline-start:var(--edit-link-margin-start,30px);margin-top:var(--edit-link-margin-top,10px);position:absolute}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .u-columns{margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset{border:none;margin-inline-start:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset legend,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset legend{color:var(--general-text-color,#000);font-weight:700;padding:20px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);margin-top:20px;padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination{padding:16px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-OrderUpdates{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:inline-start;width:25%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul{padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li{display:inline-block;list-style-type:none;width:var(--tab-width,100%)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{background-color:var(--tabs-divider-color,#69727d);content:"";display:block;height:var(--tabs-divider-weight,0);position:relative;top:calc(var(--tabs-spacing, 2px) / 2);width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.is-active a{background:#f1f2f3;border-color:var(--tabs-active-border-color,transparent);color:var(--tabs-active-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{background:#f9fafa;border-color:var(--tabs-border-color,transparent);border-radius:var(--tabs-border-radius,0);border-style:var(--tabs-border-type,solid);border-width:0;color:var(--tabs-normal-color,#69727d);display:block;font-size:14px;font-style:normal;font-weight:700;padding:var(--tabs-padding,12px 20px);text-align:var(--tabs-alignment,start)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover{border-color:var(--tabs-hover-border-color,transparent);color:var(--tabs-hover-color,#5bc0de)}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{padding:var(--tabs-padding,10px)}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout:after{display:none}.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .shop_table td{line-height:unset;vertical-align:top}.elementor-widget-woocommerce-my-account .woocommerce-MyAccount-paymentMethods .woocommerce-PaymentMethod--actions{text-align:end}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio{vertical-align:middle}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio+label{color:var(--payment-methods-radio-buttons-color,#69727d)}.e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li{margin:calc(var(--tabs-spacing, 2px) / 2) 0}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--dashboard{margin-top:0}.e-my-account-tabs-vertical .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:none;width:100%}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{float:none;padding:var(--tab-content-spacing,50px) 0 0 0;width:100%}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.e-my-account-tabs-horizontal .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:flex;justify-content:var(--tabs-container-justify-content,space-between);list-style:none;margin:0;padding:0}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:block}}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{border-inline-end-color:var(--tabs-divider-color,#69727d);border-inline-end-style:solid;border-inline-end-width:var(--tabs-divider-weight,0);display:inline-block;margin:0;padding:0 calc(var(--tabs-spacing, 2px) / 2) 0 calc(var(--tabs-spacing, 2px) / 2);width:var(--tab-width,100%)}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:first-of-type{padding-inline-start:0}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:last-of-type{border-inline-end-width:0;padding-inline-end:0}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block;margin:calc(var(--tabs-spacing, 2px) / 2) 0;width:100%}}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-number a,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-number a{pointer-events:none}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button{opacity:.3;pointer-events:none}.elementor-editor-active .elementor-widget-woocommerce-my-account .woocommerce-MyAccount-content:not(:first-of-type){display:none} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-product-add-to-cart-rtl.min.css b/assets/css/templates/widget-woocommerce-product-add-to-cart-rtl.min.css new file mode 100644 index 00000000..5c9d8e0a --- /dev/null +++ b/assets/css/templates/widget-woocommerce-product-add-to-cart-rtl.min.css @@ -0,0 +1 @@ +:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart{margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart:not(.grouped_form):not(.variations_form){display:flex;flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart button:where(:not(:first-child)){margin-block-start:0;margin-inline-start:var(--button-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container{display:flex;flex-wrap:wrap;gap:var(--view-cart-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container>*{display:flex;flex-basis:auto;margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;vertical-align:top}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity input{height:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart:not(.grouped_form):not(.variations_form),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart:not(.grouped_form):not(.variations_form){display:block}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{display:flex}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button:where(:not(:first-child)){margin-block-start:var(--button-spacing,10px);margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder{flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder button{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart button{flex-basis:100%}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart button{flex-basis:100%}}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .quantity{display:none!important}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart button:where(:not(:first-child)){margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart button:where(:not(:first-child)){margin-block-start:0}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart input.qty.disabled{pointer-events:none}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart .button{text-align:center}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) .added_to_cart{align-items:center;display:flex;margin:0;padding:0}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;text-align:center;vertical-align:top;width:3.631em}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-info button.button.alt.elementor-button{background-color:#5bc0de}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-success button.button.alt.elementor-button{background-color:#5cb85c}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-warning button.button.alt.elementor-button{background-color:#f0ad4e}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-danger button.button.alt.elementor-button{background-color:#d9534f}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-product-add-to-cart.min.css b/assets/css/templates/widget-woocommerce-product-add-to-cart.min.css new file mode 100644 index 00000000..c11e31f0 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-product-add-to-cart.min.css @@ -0,0 +1 @@ +:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart{margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart:not(.grouped_form):not(.variations_form){display:flex;flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart button:where(:not(:first-child)){margin-block-start:0;margin-inline-start:var(--button-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container{display:flex;flex-wrap:wrap;gap:var(--view-cart-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container>*{display:flex;flex-basis:auto;margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;vertical-align:top}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity input{height:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart:not(.grouped_form):not(.variations_form),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart:not(.grouped_form):not(.variations_form){display:block}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{display:flex}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button:where(:not(:first-child)){margin-block-start:var(--button-spacing,10px);margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder{flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder button{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart button{flex-basis:100%}@media (min-width:ELEMENTOR_SCREEN_WIDESCREEN_MIN){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_LAPTOP_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_TABLET_EXTRA_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_EXTRA_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart button{flex-basis:100%}}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .quantity{display:none!important}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart button:where(:not(:first-child)){margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart button:where(:not(:first-child)){margin-block-start:0}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart input.qty.disabled{pointer-events:none}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart .button{text-align:center}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) .added_to_cart{align-items:center;display:flex;margin:0;padding:0}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;text-align:center;vertical-align:top;width:3.631em}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-info button.button.alt.elementor-button{background-color:#5bc0de}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-success button.button.alt.elementor-button{background-color:#5cb85c}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-warning button.button.alt.elementor-button{background-color:#f0ad4e}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-danger button.button.alt.elementor-button{background-color:#d9534f}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-products-archive-rtl.min.css b/assets/css/templates/widget-woocommerce-products-archive-rtl.min.css new file mode 100644 index 00000000..655f1353 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-products-archive-rtl.min.css @@ -0,0 +1 @@ +@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-widget-wc-archive-products .woocommerce.columns-2 ul.products{grid-template-columns:repeat(2,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-3 ul.products{grid-template-columns:repeat(3,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-4 ul.products{grid-template-columns:repeat(4,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-5 ul.products{grid-template-columns:repeat(5,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-6 ul.products{grid-template-columns:repeat(6,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-7 ul.products{grid-template-columns:repeat(7,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-8 ul.products{grid-template-columns:repeat(8,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-9 ul.products{grid-template-columns:repeat(9,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-10 ul.products{grid-template-columns:repeat(10,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-11 ul.products{grid-template-columns:repeat(11,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-12 ul.products{grid-template-columns:repeat(12,1fr)}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(3,1fr)}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(2,1fr)}} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-products-archive.min.css b/assets/css/templates/widget-woocommerce-products-archive.min.css new file mode 100644 index 00000000..655f1353 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-products-archive.min.css @@ -0,0 +1 @@ +@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-widget-wc-archive-products .woocommerce.columns-2 ul.products{grid-template-columns:repeat(2,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-3 ul.products{grid-template-columns:repeat(3,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-4 ul.products{grid-template-columns:repeat(4,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-5 ul.products{grid-template-columns:repeat(5,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-6 ul.products{grid-template-columns:repeat(6,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-7 ul.products{grid-template-columns:repeat(7,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-8 ul.products{grid-template-columns:repeat(8,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-9 ul.products{grid-template-columns:repeat(9,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-10 ul.products{grid-template-columns:repeat(10,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-11 ul.products{grid-template-columns:repeat(11,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-12 ul.products{grid-template-columns:repeat(12,1fr)}}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(3,1fr)}}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(2,1fr)}} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-purchase-summary-rtl.min.css b/assets/css/templates/widget-woocommerce-purchase-summary-rtl.min.css new file mode 100644 index 00000000..3eddd1c2 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-purchase-summary-rtl.min.css @@ -0,0 +1 @@ +.elementor-widget-woocommerce-purchase-summary{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>td,.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>th{background-color:initial}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details{display:flex;flex-wrap:wrap;margin:0 0 2em;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-inline-end-color:var(--payment-details-border-color,#d5d8dc);border-inline-end-style:var(--payment-details-border-type,solid);border-inline-end-width:var(--payment-details-border-width,1px);color:var(--payment-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--payment-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--payment-details-space-between,4em);text-transform:capitalize}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-bottom:var(--payment-details-border-width,1px) var(--payment-details-border-type,solid) var(--payment-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--payment-details-space-between, 20px) / 2);padding-top:calc(var(--payment-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{color:var(--payment-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--payment-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details{display:flex;flex-wrap:wrap;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-inline-end-color:var(--bank-details-border-color,#d5d8dc);border-inline-end-style:var(--bank-details-border-type,solid);border-inline-end-width:var(--bank-details-border-width,1px);color:var(--bank-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--bank-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--bank-details-space-between,4em);text-transform:capitalize}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-bottom:var(--bank-details-border-width,1px) var(--bank-details-border-type,solid) var(--bank-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--bank-details-space-between, 20px) / 2);padding-top:calc(var(--bank-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{color:var(--bank-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--bank-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li:last-of-type{border-inline-end:none}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta .wc-item-meta-label,.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta li p{color:var(--order-details-variations-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;font-size:14px;margin-bottom:0;padding:var(--sections-padding,15px 30px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt{background-color:transparent;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);padding:var(--button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table th{border:0;border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc);padding-block:calc(var(--order-details-rows-gap, 18px) / 2);padding-inline:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th{border-top:none;color:var(--order-details-titles-totals-color,#000);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th span{color:var(--order-details-titles-totals-color,#000)}@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td{line-height:unset;vertical-align:top}}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td .woocommerce-Price-amount{color:var(--order-details-items-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot th{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child th{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-quantity,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-expires,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-remaining{color:var(--order-details-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-purchase-note td{border-top:none;color:var(--general-text-color,#69727d);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-table--order-downloads tr td:before{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);margin-bottom:0;margin-top:40px;padding:var(--button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce h2{color:var(--titles-color,#000);font-weight:400;margin-bottom:var(--titles-spacing,45px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-details h2{text-align:var(--order-summary-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-heading{text-align:var(--bank-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-downloads__title{text-align:var(--downloads-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--billing-address h2,.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-customer-details>h2{text-align:var(--billing-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--shipping-address h2{text-align:var(--shipping-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce a{color:var(--order-details-product-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce a:hover{color:var(--order-details-product-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce p{margin-bottom:20px}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-received{color:var(--confirmation-message-color,#69727d);display:var(--confirmation-message-display,none);margin-bottom:var(--sections-spacing,40px);text-align:var(--confirmation-message-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-purchase-summary .woocommerce address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;color:var(--general-text-color,#69727d);padding:var(--sections-padding,15px 30px)}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce-column--2{margin-top:2em}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details+p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-account-name{color:var(--account-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--account-title-spacing,1rem)}.elementor-widget-woocommerce-purchase-summary .woocommerce section{margin-top:var(--sections-spacing,4em)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details:last-child{margin-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details{table-layout:fixed}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details td{word-wrap:break-word} \ No newline at end of file diff --git a/assets/css/templates/widget-woocommerce-purchase-summary.min.css b/assets/css/templates/widget-woocommerce-purchase-summary.min.css new file mode 100644 index 00000000..3eddd1c2 --- /dev/null +++ b/assets/css/templates/widget-woocommerce-purchase-summary.min.css @@ -0,0 +1 @@ +.elementor-widget-woocommerce-purchase-summary{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>td,.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>th{background-color:initial}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details{display:flex;flex-wrap:wrap;margin:0 0 2em;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-inline-end-color:var(--payment-details-border-color,#d5d8dc);border-inline-end-style:var(--payment-details-border-type,solid);border-inline-end-width:var(--payment-details-border-width,1px);color:var(--payment-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--payment-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--payment-details-space-between,4em);text-transform:capitalize}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-bottom:var(--payment-details-border-width,1px) var(--payment-details-border-type,solid) var(--payment-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--payment-details-space-between, 20px) / 2);padding-top:calc(var(--payment-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{color:var(--payment-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--payment-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details{display:flex;flex-wrap:wrap;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-inline-end-color:var(--bank-details-border-color,#d5d8dc);border-inline-end-style:var(--bank-details-border-type,solid);border-inline-end-width:var(--bank-details-border-width,1px);color:var(--bank-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--bank-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--bank-details-space-between,4em);text-transform:capitalize}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-bottom:var(--bank-details-border-width,1px) var(--bank-details-border-type,solid) var(--bank-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--bank-details-space-between, 20px) / 2);padding-top:calc(var(--bank-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{color:var(--bank-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--bank-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:ELEMENTOR_SCREEN_TABLET_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li:last-of-type{border-inline-end:none}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta .wc-item-meta-label,.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta li p{color:var(--order-details-variations-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;font-size:14px;margin-bottom:0;padding:var(--sections-padding,15px 30px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt{background-color:transparent;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);padding:var(--button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table th{border:0;border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc);padding-block:calc(var(--order-details-rows-gap, 18px) / 2);padding-inline:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th{border-top:none;color:var(--order-details-titles-totals-color,#000);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th span{color:var(--order-details-titles-totals-color,#000)}@media (min-width:ELEMENTOR_SCREEN_TABLET_NEXT){.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td{line-height:unset;vertical-align:top}}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td .woocommerce-Price-amount{color:var(--order-details-items-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot th{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child th{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-quantity,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-expires,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-remaining{color:var(--order-details-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-purchase-note td{border-top:none;color:var(--general-text-color,#69727d);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-table--order-downloads tr td:before{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);margin-bottom:0;margin-top:40px;padding:var(--button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce h2{color:var(--titles-color,#000);font-weight:400;margin-bottom:var(--titles-spacing,45px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-details h2{text-align:var(--order-summary-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-heading{text-align:var(--bank-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-downloads__title{text-align:var(--downloads-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--billing-address h2,.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-customer-details>h2{text-align:var(--billing-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--shipping-address h2{text-align:var(--shipping-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce a{color:var(--order-details-product-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce a:hover{color:var(--order-details-product-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce p{margin-bottom:20px}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-received{color:var(--confirmation-message-color,#69727d);display:var(--confirmation-message-display,none);margin-bottom:var(--sections-spacing,40px);text-align:var(--confirmation-message-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-purchase-summary .woocommerce address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;color:var(--general-text-color,#69727d);padding:var(--sections-padding,15px 30px)}@media (max-width:ELEMENTOR_SCREEN_MOBILE_MAX){.elementor-widget-woocommerce-purchase-summary .woocommerce-column--2{margin-top:2em}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details+p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-account-name{color:var(--account-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--account-title-spacing,1rem)}.elementor-widget-woocommerce-purchase-summary .woocommerce section{margin-top:var(--sections-spacing,4em)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details:last-child{margin-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details{table-layout:fixed}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details td{word-wrap:break-word} \ No newline at end of file diff --git a/assets/css/widget-_compatibility-rtl.min.css b/assets/css/widget-_compatibility-rtl.min.css new file mode 100644 index 00000000..c188a7e0 --- /dev/null +++ b/assets/css/widget-_compatibility-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/widget-_compatibility.min.css b/assets/css/widget-_compatibility.min.css new file mode 100644 index 00000000..c188a7e0 --- /dev/null +++ b/assets/css/widget-_compatibility.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/widget-_overlay-animation-rtl.min.css b/assets/css/widget-_overlay-animation-rtl.min.css new file mode 100644 index 00000000..b183f950 --- /dev/null +++ b/assets/css/widget-_overlay-animation-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-overlay-animation-fade{opacity:0}.e-overlay-animation-slide-up{transform:translateY(100%)}.e-overlay-animation-slide-down{transform:translateY(-100%)}.e-overlay-animation-slide-right{transform:translateX(-100%)}.e-overlay-animation-slide-left{transform:translateX(100%)}.e-overlay-animation-zoom-in{opacity:0;transform:scale(.5)} \ No newline at end of file diff --git a/assets/css/widget-_overlay-animation.min.css b/assets/css/widget-_overlay-animation.min.css new file mode 100644 index 00000000..b183f950 --- /dev/null +++ b/assets/css/widget-_overlay-animation.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-overlay-animation-fade{opacity:0}.e-overlay-animation-slide-up{transform:translateY(100%)}.e-overlay-animation-slide-down{transform:translateY(-100%)}.e-overlay-animation-slide-right{transform:translateX(-100%)}.e-overlay-animation-slide-left{transform:translateX(100%)}.e-overlay-animation-zoom-in{opacity:0;transform:scale(.5)} \ No newline at end of file diff --git a/assets/css/widget-_sticky-rtl.min.css b/assets/css/widget-_sticky-rtl.min.css new file mode 100644 index 00000000..708b5a0e --- /dev/null +++ b/assets/css/widget-_sticky-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-_sticky.min.css b/assets/css/widget-_sticky.min.css new file mode 100644 index 00000000..708b5a0e --- /dev/null +++ b/assets/css/widget-_sticky.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-animated-headline-rtl.min.css b/assets/css/widget-animated-headline-rtl.min.css new file mode 100644 index 00000000..4eb47271 --- /dev/null +++ b/assets/css/widget-animated-headline-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-headline{display:block;font-size:43px;line-height:1.2}.elementor-headline-dynamic-text{color:var(--dynamic-text-color,#aebcb9)}.elementor-headline--style-rotate .elementor-headline-dynamic-wrapper{text-align:start}.elementor-headline--style-highlight .elementor-headline-dynamic-wrapper{overflow:visible;text-align:inherit}.elementor-headline--style-highlight .elementor-headline-dynamic-text{z-index:1}.elementor-headline--style-highlight .elementor-headline-plain-text{position:relative;z-index:1}.elementor-headline--style-highlight svg{height:calc(100% + 20px);left:50%;overflow:visible;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% + 20px)}.elementor-headline--style-highlight svg path{stroke:red;stroke-width:9;fill:none;opacity:0;stroke-dasharray:0 1500;transition:.3s}.elementor-headline.e-animated svg path{animation:elementor-headline-dash forwards;animation-duration:var(--animation-duration,1.2s);animation-iteration-count:1}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path{animation-duration:0s}}.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:calc(var(--animation-duration, 1.2s) / 2)}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:0s}}.elementor-headline.e-hide-highlight svg path{opacity:1;stroke-dasharray:1500 1500;animation:hide-highlight .4s forwards;animation-iteration-count:1}@keyframes elementor-headline-dash{0%{stroke-dasharray:0 1500;opacity:1}to{stroke-dasharray:1500 1500;opacity:1}}@keyframes hide-highlight{0%{opacity:1;stroke-dasharray:1500 1500}to{filter:blur(10px);opacity:0}}.elementor-headline-text-wrapper{vertical-align:bottom}.elementor-headline-dynamic-wrapper{display:inline-block;position:relative}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text{display:inline-block;inset-block-start:0;inset-inline-start:0;position:absolute}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text.elementor-headline-text-active{position:relative}.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text{opacity:0;transform:rotateX(180deg);transform-origin:50% 100%}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-flip-in 1.2s;opacity:1;transform:rotateX(0deg)}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-flip-out 1.2s;transform:rotateX(180deg)}@keyframes elementor-headline-flip-in{0%{opacity:0;transform:rotateX(180deg)}35%{opacity:0;transform:rotateX(120deg)}65%{opacity:0}to{opacity:1;transform:rotateX(1turn)}}@keyframes elementor-headline-flip-out{0%{opacity:1;transform:rotateX(0deg)}35%{opacity:1;transform:rotateX(-40deg)}65%{opacity:0}to{opacity:0;transform:rotateX(180deg)}}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:90%;inset-block-start:50%;inset-inline:auto 0;position:absolute;transform:translateY(-50%);width:1px}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:not(.elementor-headline-typing-selected):after{animation:elementor-headline-pulse 1s infinite}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected{background-color:var(--typing-selected-bg-color,#0d0d0d)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected:after{visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected .elementor-headline-dynamic-text{color:var(--typing-selected-color,var(--dynamic-text-color),#aebcb9)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-text:not(.elementor-headline-text-active){visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){position:absolute;visibility:hidden}@keyframes elementor-headline-pulse{0%{opacity:1;transform:translateY(-50%) scale(1)}40%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:0;transform:translateY(-50%) scale(0)}}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text{opacity:0;transform:scaleX(1.0005)}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:0;transform:translateZ(-20px) rotateX(90deg);transform-style:preserve-3d}.elementor-headline-text-active .elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-swirl-in .4s forwards}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-swirl-out .4s forwards}@keyframes elementor-headline-swirl-in{0%{opacity:0;transform:translateZ(-20px) rotateX(90deg)}60%{opacity:1;transform:translateZ(-20px) rotateX(-10deg)}to{opacity:1;transform:translateZ(-20px) rotateX(0deg)}}@keyframes elementor-headline-swirl-out{0%{opacity:1;transform:translateZ(-20px) rotateX(0)}60%{opacity:0;transform:translateZ(-20px) rotateX(-100deg)}to{opacity:0;transform:translateZ(-20px) rotateX(-90deg)}}.elementor-headline-animation-type-slide-down .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text{opacity:0;top:.2em}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-down-in .6s;opacity:1;top:0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-down-out .6s}@keyframes elementor-headline-slide-down-in{0%{opacity:0;transform:translateY(-100%)}60%{opacity:1;transform:translateY(20%)}to{opacity:1;transform:translateY(0)}}@keyframes elementor-headline-slide-down-out{0%{opacity:1;transform:translateY(0)}60%{opacity:0;transform:translateY(120%)}to{opacity:0;transform:translateY(100%)}}.elementor-headline-animation-type-clip .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:100%;inset-block-start:0;inset-inline:auto 0;position:absolute;width:2px}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text.elementor-headline-text-active{opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-drop-in-in .8s;opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-drop-in-out .8s}@keyframes elementor-headline-drop-in-in{0%{opacity:0;transform:translateZ(100px)}to{opacity:1;transform:translateZ(0)}}@keyframes elementor-headline-drop-in-out{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translateZ(-100px)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block;transform:rotateY(180deg)}.elementor-headline-text-active .elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{transform:rotateY(0deg)}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-blinds-in .6s forwards}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-blinds-out .6s forwards}@keyframes elementor-headline-blinds-in{0%{transform:rotateY(180deg)}to{transform:rotateY(0deg)}}@keyframes elementor-headline-blinds-out{0%{transform:rotateY(0)}to{transform:rotateY(-180deg)}}.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{display:inline-block;opacity:0;transform:scale(0)}.elementor-headline-text-active .elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-wave-up .6s forwards}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-wave-down .6s forwards}@keyframes elementor-headline-wave-up{0%{opacity:0;transform:scale(0)}60%{opacity:1;transform:scale(1.2)}to{opacity:1;transform:scale(1)}}@keyframes elementor-headline-wave-down{0%{opacity:1;transform:scale(1)}60%{opacity:0;transform:scale(0)}}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-in .6s;opacity:1}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-out .6s}@keyframes elementor-headline-slide-in{0%{opacity:0;transform:translateX(-100%)}60%{opacity:1;transform:translateX(10%)}to{opacity:1;transform:translateX(0)}}@keyframes elementor-headline-slide-out{0%{opacity:1;transform:translateX(0)}60%{opacity:0;transform:translateX(110%)}to{opacity:0;transform:translateX(100%)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{transition:width .5s}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{overflow:hidden}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text,.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{white-space:nowrap} \ No newline at end of file diff --git a/assets/css/widget-animated-headline.min.css b/assets/css/widget-animated-headline.min.css new file mode 100644 index 00000000..4eb47271 --- /dev/null +++ b/assets/css/widget-animated-headline.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-headline{display:block;font-size:43px;line-height:1.2}.elementor-headline-dynamic-text{color:var(--dynamic-text-color,#aebcb9)}.elementor-headline--style-rotate .elementor-headline-dynamic-wrapper{text-align:start}.elementor-headline--style-highlight .elementor-headline-dynamic-wrapper{overflow:visible;text-align:inherit}.elementor-headline--style-highlight .elementor-headline-dynamic-text{z-index:1}.elementor-headline--style-highlight .elementor-headline-plain-text{position:relative;z-index:1}.elementor-headline--style-highlight svg{height:calc(100% + 20px);left:50%;overflow:visible;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% + 20px)}.elementor-headline--style-highlight svg path{stroke:red;stroke-width:9;fill:none;opacity:0;stroke-dasharray:0 1500;transition:.3s}.elementor-headline.e-animated svg path{animation:elementor-headline-dash forwards;animation-duration:var(--animation-duration,1.2s);animation-iteration-count:1}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path{animation-duration:0s}}.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:calc(var(--animation-duration, 1.2s) / 2)}@media (prefers-reduced-motion:reduce){.elementor-headline.e-animated svg path:nth-of-type(2){animation-delay:0s}}.elementor-headline.e-hide-highlight svg path{opacity:1;stroke-dasharray:1500 1500;animation:hide-highlight .4s forwards;animation-iteration-count:1}@keyframes elementor-headline-dash{0%{stroke-dasharray:0 1500;opacity:1}to{stroke-dasharray:1500 1500;opacity:1}}@keyframes hide-highlight{0%{opacity:1;stroke-dasharray:1500 1500}to{filter:blur(10px);opacity:0}}.elementor-headline-text-wrapper{vertical-align:bottom}.elementor-headline-dynamic-wrapper{display:inline-block;position:relative}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text{display:inline-block;inset-block-start:0;inset-inline-start:0;position:absolute}.elementor-headline-dynamic-wrapper .elementor-headline-dynamic-text.elementor-headline-text-active{position:relative}.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text{opacity:0;transform:rotateX(180deg);transform-origin:50% 100%}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-flip-in 1.2s;opacity:1;transform:rotateX(0deg)}.elementor-headline-animation-type-flip .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-flip-out 1.2s;transform:rotateX(180deg)}@keyframes elementor-headline-flip-in{0%{opacity:0;transform:rotateX(180deg)}35%{opacity:0;transform:rotateX(120deg)}65%{opacity:0}to{opacity:1;transform:rotateX(1turn)}}@keyframes elementor-headline-flip-out{0%{opacity:1;transform:rotateX(0deg)}35%{opacity:1;transform:rotateX(-40deg)}65%{opacity:0}to{opacity:0;transform:rotateX(180deg)}}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:90%;inset-block-start:50%;inset-inline:auto 0;position:absolute;transform:translateY(-50%);width:1px}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper:not(.elementor-headline-typing-selected):after{animation:elementor-headline-pulse 1s infinite}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected{background-color:var(--typing-selected-bg-color,#0d0d0d)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected:after{visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper.elementor-headline-typing-selected .elementor-headline-dynamic-text{color:var(--typing-selected-color,var(--dynamic-text-color),#aebcb9)}.elementor-headline-animation-type-typing .elementor-headline-dynamic-text:not(.elementor-headline-text-active){visibility:hidden}.elementor-headline-animation-type-typing .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){position:absolute;visibility:hidden}@keyframes elementor-headline-pulse{0%{opacity:1;transform:translateY(-50%) scale(1)}40%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:0;transform:translateY(-50%) scale(0)}}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text{opacity:0;transform:scaleX(1.0005)}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:0;transform:translateZ(-20px) rotateX(90deg);transform-style:preserve-3d}.elementor-headline-text-active .elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-swirl-in .4s forwards}.elementor-headline-animation-type-swirl .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-swirl-out .4s forwards}@keyframes elementor-headline-swirl-in{0%{opacity:0;transform:translateZ(-20px) rotateX(90deg)}60%{opacity:1;transform:translateZ(-20px) rotateX(-10deg)}to{opacity:1;transform:translateZ(-20px) rotateX(0deg)}}@keyframes elementor-headline-swirl-out{0%{opacity:1;transform:translateZ(-20px) rotateX(0)}60%{opacity:0;transform:translateZ(-20px) rotateX(-100deg)}to{opacity:0;transform:translateZ(-20px) rotateX(-90deg)}}.elementor-headline-animation-type-slide-down .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text{opacity:0;top:.2em}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-down-in .6s;opacity:1;top:0}.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-down-out .6s}@keyframes elementor-headline-slide-down-in{0%{opacity:0;transform:translateY(-100%)}60%{opacity:1;transform:translateY(20%)}to{opacity:1;transform:translateY(0)}}@keyframes elementor-headline-slide-down-out{0%{opacity:1;transform:translateY(0)}60%{opacity:0;transform:translateY(120%)}to{opacity:0;transform:translateY(100%)}}.elementor-headline-animation-type-clip .elementor-headline-text-wrapper{display:inline-block;padding:.2em 0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper{overflow:hidden;vertical-align:top}.elementor-headline-animation-type-clip .elementor-headline-dynamic-wrapper:after{background-color:#0d0d0d;content:"";height:100%;inset-block-start:0;inset-inline:auto 0;position:absolute;width:2px}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-clip .elementor-headline-dynamic-text.elementor-headline-text-active{opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-drop-in-in .8s;opacity:1}.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-drop-in-out .8s}@keyframes elementor-headline-drop-in-in{0%{opacity:0;transform:translateZ(100px)}to{opacity:1;transform:translateZ(0)}}@keyframes elementor-headline-drop-in-out{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translateZ(-100px)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper{perspective:300px}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{backface-visibility:hidden;display:inline-block;transform:rotateY(180deg)}.elementor-headline-text-active .elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter{transform:rotateY(0deg)}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-blinds-in .6s forwards}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-blinds-out .6s forwards}@keyframes elementor-headline-blinds-in{0%{transform:rotateY(180deg)}to{transform:rotateY(0deg)}}@keyframes elementor-headline-blinds-out{0%{transform:rotateY(0)}to{transform:rotateY(-180deg)}}.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{display:inline-block;opacity:0;transform:scale(0)}.elementor-headline-text-active .elementor-headline-animation-type-wave .elementor-headline-dynamic-letter{opacity:1}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter.elementor-headline-animation-in{animation:elementor-headline-wave-up .6s forwards}.elementor-headline-animation-type-wave .elementor-headline-dynamic-letter:not(.elementor-headline-animation-in){animation:elementor-headline-wave-down .6s forwards}@keyframes elementor-headline-wave-up{0%{opacity:0;transform:scale(0)}60%{opacity:1;transform:scale(1.2)}to{opacity:1;transform:scale(1)}}@keyframes elementor-headline-wave-down{0%{opacity:1;transform:scale(1)}60%{opacity:0;transform:scale(0)}}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text{opacity:0}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-active{animation:elementor-headline-slide-in .6s;opacity:1}.elementor-headline-animation-type-slide .elementor-headline-dynamic-text.elementor-headline-text-inactive{animation:elementor-headline-slide-out .6s}@keyframes elementor-headline-slide-in{0%{opacity:0;transform:translateX(-100%)}60%{opacity:1;transform:translateX(10%)}to{opacity:1;transform:translateX(0)}}@keyframes elementor-headline-slide-out{0%{opacity:1;transform:translateX(0)}60%{opacity:0;transform:translateX(110%)}to{opacity:0;transform:translateX(100%)}}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-drop-in .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-flip .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-slide-down .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{transition:width .5s}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-wrapper,.elementor-headline-animation-type-wave .elementor-headline-dynamic-wrapper{overflow:hidden}.elementor-headline-animation-type-blinds .elementor-headline-dynamic-text,.elementor-headline-animation-type-swirl .elementor-headline-dynamic-text,.elementor-headline-animation-type-wave .elementor-headline-dynamic-text{white-space:nowrap} \ No newline at end of file diff --git a/assets/css/widget-author-box-rtl.min.css b/assets/css/widget-author-box-rtl.min.css new file mode 100644 index 00000000..f320faeb --- /dev/null +++ b/assets/css/widget-author-box-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-author-box{align-items:center;display:flex}.elementor-author-box__avatar{flex-shrink:0;margin-inline-end:25px}.elementor-author-box__avatar img{border-radius:500px;-o-object-fit:cover;object-fit:cover;width:100px}.elementor-author-box__text{flex-grow:1;font-size:17px}.elementor-author-box__name{font-size:24px;margin-bottom:5px}.elementor-author-box__bio,.elementor-author-box__bio p{margin-bottom:.8em}.elementor-author-box__bio p:last-of-type{margin-bottom:0}.elementor-author-box--layout-image-left .elementor-author-box{flex-direction:row-reverse}.elementor-author-box--layout-image-left .elementor-author-box__avatar{margin-left:0;margin-right:25px}.elementor-author-box--layout-image-right .elementor-author-box{flex-direction:row}.elementor-author-box--layout-image-right .elementor-author-box__avatar{margin-left:25px;margin-right:0}.elementor-author-box--layout-image-above .elementor-author-box{display:block}.elementor-author-box--layout-image-above .elementor-author-box__avatar{display:inline-block;margin:0 auto 15px}.elementor-author-box--layout-image-above.elementor-author-box--align-left .elementor-author-box__avatar{margin-left:0}.elementor-author-box--layout-image-above.elementor-author-box--align-right .elementor-author-box__avatar{margin-right:0}.elementor-author-box--align-left .elementor-author-box{text-align:left}.elementor-author-box--align-right .elementor-author-box{text-align:right}.elementor-author-box--align-center .elementor-author-box{text-align:center}.elementor-button.elementor-author-box__button{border:2px solid #3f444b;font-size:15px;font-weight:100;padding:10px 18px}.elementor-button.elementor-author-box__button,.elementor-button.elementor-author-box__button:hover{background:transparent;color:#3f444b}.elementor-widget-author-box:not(.elementor-author-box--layout-image-above) .elementor-author-box__avatar,.elementor-widget-author-box:not(.elementor-author-box--layout-image-above).elementor-author-box--image-valign-top .elementor-author-box__avatar{align-self:flex-start}.elementor-widget-author-box:not(.elementor-author-box--layout-image-above).elementor-author-box--image-valign-middle .elementor-author-box__avatar{align-self:center} \ No newline at end of file diff --git a/assets/css/widget-author-box.min.css b/assets/css/widget-author-box.min.css new file mode 100644 index 00000000..88fb0209 --- /dev/null +++ b/assets/css/widget-author-box.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-author-box{align-items:center;display:flex}.elementor-author-box__avatar{flex-shrink:0;margin-inline-end:25px}.elementor-author-box__avatar img{border-radius:500px;-o-object-fit:cover;object-fit:cover;width:100px}.elementor-author-box__text{flex-grow:1;font-size:17px}.elementor-author-box__name{font-size:24px;margin-bottom:5px}.elementor-author-box__bio,.elementor-author-box__bio p{margin-bottom:.8em}.elementor-author-box__bio p:last-of-type{margin-bottom:0}.elementor-author-box--layout-image-left .elementor-author-box{flex-direction:row}.elementor-author-box--layout-image-left .elementor-author-box__avatar{margin-left:0;margin-right:25px}.elementor-author-box--layout-image-right .elementor-author-box{flex-direction:row-reverse}.elementor-author-box--layout-image-right .elementor-author-box__avatar{margin-left:25px;margin-right:0}.elementor-author-box--layout-image-above .elementor-author-box{display:block}.elementor-author-box--layout-image-above .elementor-author-box__avatar{display:inline-block;margin:0 auto 15px}.elementor-author-box--layout-image-above.elementor-author-box--align-left .elementor-author-box__avatar{margin-left:0}.elementor-author-box--layout-image-above.elementor-author-box--align-right .elementor-author-box__avatar{margin-right:0}.elementor-author-box--align-left .elementor-author-box{text-align:left}.elementor-author-box--align-right .elementor-author-box{text-align:right}.elementor-author-box--align-center .elementor-author-box{text-align:center}.elementor-button.elementor-author-box__button{border:2px solid #3f444b;font-size:15px;font-weight:100;padding:10px 18px}.elementor-button.elementor-author-box__button,.elementor-button.elementor-author-box__button:hover{background:transparent;color:#3f444b}.elementor-widget-author-box:not(.elementor-author-box--layout-image-above) .elementor-author-box__avatar,.elementor-widget-author-box:not(.elementor-author-box--layout-image-above).elementor-author-box--image-valign-top .elementor-author-box__avatar{align-self:flex-start}.elementor-widget-author-box:not(.elementor-author-box--layout-image-above).elementor-author-box--image-valign-middle .elementor-author-box__avatar{align-self:center} \ No newline at end of file diff --git a/assets/css/widget-blockquote-rtl.min.css b/assets/css/widget-blockquote-rtl.min.css new file mode 100644 index 00000000..a3afc371 --- /dev/null +++ b/assets/css/widget-blockquote-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.entry-content blockquote.elementor-blockquote:not(.alignright):not(.alignleft),.entry-summary blockquote.elementor-blockquote{margin-left:0;margin-right:0}.elementor-widget-blockquote blockquote{background:transparent;border:0;color:#3f444b;font-size:100%;font-style:normal;margin:0;outline:0;padding:0;quotes:none;vertical-align:baseline}.elementor-widget-blockquote blockquote .e-q-footer:after,.elementor-widget-blockquote blockquote .e-q-footer:before,.elementor-widget-blockquote blockquote cite:after,.elementor-widget-blockquote blockquote cite:before,.elementor-widget-blockquote blockquote:after,.elementor-widget-blockquote blockquote:before{content:none}.elementor-blockquote{transition:.3s}.elementor-blockquote__author,.elementor-blockquote__content{font-style:normal;margin-bottom:0}.elementor-blockquote__author{font-weight:700}.elementor-blockquote .e-q-footer{display:flex;justify-content:space-between;margin-top:12px}.elementor-blockquote__tweet-button{align-self:flex-end;color:#1da1f2;display:flex;line-height:1;position:relative;transition:.3s;width:-moz-max-content;width:max-content}.elementor-blockquote__tweet-button:hover{color:#0967a0}.elementor-blockquote__tweet-button span{font-weight:600}.elementor-blockquote__tweet-button i,.elementor-blockquote__tweet-button span{vertical-align:middle}.elementor-blockquote__tweet-button i+span,.elementor-blockquote__tweet-button svg+span{margin-inline-start:.5em}.elementor-blockquote__tweet-button svg{fill:#1da1f2;height:1em;width:1em}.elementor-blockquote__tweet-label{white-space:pre-wrap}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button{background-color:#1da1f2;border-radius:100em;color:#fff;font-size:15px;padding:.7em 1.2em}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:hover,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button:hover{background-color:#0967a0;color:#fff}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:hover:before,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button:hover:before{border-inline-end-color:#0967a0}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button svg,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button svg{fill:#fff;height:1em;width:1em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button,.elementor-blockquote--button-skin-classic.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button{height:2em;padding:0;width:2em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button i,.elementor-blockquote--button-skin-classic.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button i{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:before{border:.5em solid transparent;border-inline-end-color:#1da1f2;content:"";inset-block-start:50%;inset-inline-start:-.8em;position:absolute;transform:translateY(-50%) scaleY(.65);transition:.3s}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-left .elementor-blockquote__tweet-button:before{border-left-color:transparent;border-right-color:#1da1f2;left:-.8em;right:auto}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-left .elementor-blockquote__tweet-button:hover:before{border-right-color:#0967a0}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-right .elementor-blockquote__tweet-button:before{border-left-color:#1da1f2;border-right-color:transparent;left:auto;right:-.8em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-right .elementor-blockquote__tweet-button:hover:before{border-left-color:#0967a0}.elementor-blockquote--skin-boxed .elementor-blockquote{background-color:#f9fafa;padding:30px}.elementor-blockquote--skin-border .elementor-blockquote{border-color:#f9fafa;border-inline-start-width:7px;border-style:solid;padding-inline-start:20px}.elementor-blockquote--skin-quotation .elementor-blockquote:before{color:#f9fafa;content:"“";display:block;font-family:Times New Roman,Times,serif;font-size:100px;font-weight:900;height:.6em;line-height:1}.elementor-blockquote--skin-quotation .elementor-blockquote__content{margin-top:15px}.elementor-blockquote--align-left .elementor-blockquote__content{text-align:left}.elementor-blockquote--align-left .elementor-blockquote .e-q-footer{flex-direction:row-reverse}.elementor-blockquote--align-right .elementor-blockquote__content{text-align:right}.elementor-blockquote--align-right .elementor-blockquote .e-q-footer{flex-direction:row}.elementor-blockquote--align-center .elementor-blockquote{text-align:center}.elementor-blockquote--align-center .elementor-blockquote .e-q-footer,.elementor-blockquote--align-center .elementor-blockquote__author{display:block}.elementor-blockquote--align-center .elementor-blockquote__tweet-button{margin-left:auto;margin-right:auto} \ No newline at end of file diff --git a/assets/css/widget-blockquote.min.css b/assets/css/widget-blockquote.min.css new file mode 100644 index 00000000..3737880d --- /dev/null +++ b/assets/css/widget-blockquote.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.entry-content blockquote.elementor-blockquote:not(.alignright):not(.alignleft),.entry-summary blockquote.elementor-blockquote{margin-left:0;margin-right:0}.elementor-widget-blockquote blockquote{background:transparent;border:0;color:#3f444b;font-size:100%;font-style:normal;margin:0;outline:0;padding:0;quotes:none;vertical-align:baseline}.elementor-widget-blockquote blockquote .e-q-footer:after,.elementor-widget-blockquote blockquote .e-q-footer:before,.elementor-widget-blockquote blockquote cite:after,.elementor-widget-blockquote blockquote cite:before,.elementor-widget-blockquote blockquote:after,.elementor-widget-blockquote blockquote:before{content:none}.elementor-blockquote{transition:.3s}.elementor-blockquote__author,.elementor-blockquote__content{font-style:normal;margin-bottom:0}.elementor-blockquote__author{font-weight:700}.elementor-blockquote .e-q-footer{display:flex;justify-content:space-between;margin-top:12px}.elementor-blockquote__tweet-button{align-self:flex-end;color:#1da1f2;display:flex;line-height:1;position:relative;transition:.3s;width:-moz-max-content;width:max-content}.elementor-blockquote__tweet-button:hover{color:#0967a0}.elementor-blockquote__tweet-button span{font-weight:600}.elementor-blockquote__tweet-button i,.elementor-blockquote__tweet-button span{vertical-align:middle}.elementor-blockquote__tweet-button i+span,.elementor-blockquote__tweet-button svg+span{margin-inline-start:.5em}.elementor-blockquote__tweet-button svg{fill:#1da1f2;height:1em;width:1em}.elementor-blockquote__tweet-label{white-space:pre-wrap}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button{background-color:#1da1f2;border-radius:100em;color:#fff;font-size:15px;padding:.7em 1.2em}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:hover,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button:hover{background-color:#0967a0;color:#fff}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:hover:before,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button:hover:before{border-inline-end-color:#0967a0}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button svg,.elementor-blockquote--button-skin-classic .elementor-blockquote__tweet-button svg{fill:#fff;height:1em;width:1em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button,.elementor-blockquote--button-skin-classic.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button{height:2em;padding:0;width:2em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button i,.elementor-blockquote--button-skin-classic.elementor-blockquote--button-view-icon .elementor-blockquote__tweet-button i{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.elementor-blockquote--button-skin-bubble .elementor-blockquote__tweet-button:before{border:.5em solid transparent;border-inline-end-color:#1da1f2;content:"";inset-block-start:50%;inset-inline-start:-.8em;position:absolute;transform:translateY(-50%) scaleY(.65);transition:.3s}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-left .elementor-blockquote__tweet-button:before{border-left-color:transparent;border-right-color:#1da1f2;left:-.8em;right:auto}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-left .elementor-blockquote__tweet-button:hover:before{border-right-color:#0967a0}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-right .elementor-blockquote__tweet-button:before{border-left-color:#1da1f2;border-right-color:transparent;left:auto;right:-.8em}.elementor-blockquote--button-skin-bubble.elementor-blockquote--align-right .elementor-blockquote__tweet-button:hover:before{border-left-color:#0967a0}.elementor-blockquote--skin-boxed .elementor-blockquote{background-color:#f9fafa;padding:30px}.elementor-blockquote--skin-border .elementor-blockquote{border-color:#f9fafa;border-inline-start-width:7px;border-style:solid;padding-inline-start:20px}.elementor-blockquote--skin-quotation .elementor-blockquote:before{color:#f9fafa;content:"“";display:block;font-family:Times New Roman,Times,serif;font-size:100px;font-weight:900;height:.6em;line-height:1}.elementor-blockquote--skin-quotation .elementor-blockquote__content{margin-top:15px}.elementor-blockquote--align-left .elementor-blockquote__content{text-align:left}.elementor-blockquote--align-left .elementor-blockquote .e-q-footer{flex-direction:row}.elementor-blockquote--align-right .elementor-blockquote__content{text-align:right}.elementor-blockquote--align-right .elementor-blockquote .e-q-footer{flex-direction:row-reverse}.elementor-blockquote--align-center .elementor-blockquote{text-align:center}.elementor-blockquote--align-center .elementor-blockquote .e-q-footer,.elementor-blockquote--align-center .elementor-blockquote__author{display:block}.elementor-blockquote--align-center .elementor-blockquote__tweet-button{margin-left:auto;margin-right:auto} \ No newline at end of file diff --git a/assets/css/widget-breadcrumbs-rtl.min.css b/assets/css/widget-breadcrumbs-rtl.min.css new file mode 100644 index 00000000..548dbaba --- /dev/null +++ b/assets/css/widget-breadcrumbs-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-breadcrumbs{font-size:.85em}.elementor-widget-breadcrumbs p{margin-bottom:0} \ No newline at end of file diff --git a/assets/css/widget-breadcrumbs.min.css b/assets/css/widget-breadcrumbs.min.css new file mode 100644 index 00000000..548dbaba --- /dev/null +++ b/assets/css/widget-breadcrumbs.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-breadcrumbs{font-size:.85em}.elementor-widget-breadcrumbs p{margin-bottom:0} \ No newline at end of file diff --git a/assets/css/widget-call-to-action-rtl.min.css b/assets/css/widget-call-to-action-rtl.min.css new file mode 100644 index 00000000..b10ffbba --- /dev/null +++ b/assets/css/widget-call-to-action-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-call-to-action .elementor-widget-container,.elementor-widget-call-to-action:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-cta{display:flex;overflow:hidden;position:relative;transition:.5s}.elementor-cta--skin-classic .elementor-cta{flex-wrap:wrap}.elementor-cta--skin-classic .elementor-cta__bg-wrapper{min-height:200px;position:relative;width:100%}.elementor-cta--skin-classic .elementor-cta__content{background-color:#f9fafa;transition:all .4s;width:100%}.elementor-cta--skin-classic .elementor-cta__content-item,.elementor-cta--skin-classic .elementor-cta__content-item .elementor-icon{border-color:#3f444b;color:#3f444b;fill:#3f444b}.elementor-cta--skin-classic .elementor-cta__button.elementor-button{border-color:#3f444b;color:#3f444b}.elementor-cta--skin-cover .elementor-cta{display:block}.elementor-cta--skin-cover .elementor-cta__bg-wrapper{inset:0;position:absolute;transition:all .4s;width:100%}.elementor-cta--skin-cover .elementor-cta__content{min-height:280px}.elementor-cta--skin-cover .elementor-cta__button.elementor-button,.elementor-cta--skin-cover .elementor-cta__content-item,.elementor-cta--skin-cover .elementor-cta__content-item .elementor-icon{border-color:#fff;color:#fff}.elementor-cta--layout-image-above .elementor-cta,.elementor-cta--layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--layout-image-left .elementor-cta,.elementor-cta--layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--layout-image-left .elementor-cta__content,.elementor-cta--layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--layout-image-right .elementor-cta{flex-direction:row}.elementor-cta__bg,.elementor-cta__bg-overlay{inset:0;position:absolute;transition:all .4s}.elementor-cta__bg-wrapper{overflow:hidden;z-index:1}.elementor-cta__bg{background-position:50%;background-size:cover;z-index:1}.elementor-cta__bg-overlay{z-index:2}.elementor-cta__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-cta__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-cta__title{font-size:23px}.elementor-cta__content{align-content:center;align-items:center;display:flex;flex-wrap:wrap;overflow:hidden;padding:35px;width:100%;z-index:1}.elementor-cta__content,.elementor-cta__content-item{color:#fff;position:relative;transition:.5s}.elementor-cta__content-item{margin:0;width:100%}.elementor-cta__content-item:not(:last-child){margin-bottom:15px}.elementor-cta__content-item .elementor-icon{color:#fff}.elementor-cta--valign-top .elementor-cta__content{align-content:flex-start;align-items:flex-start}.elementor-cta--valign-middle .elementor-cta__content{align-content:center;align-items:center}.elementor-cta--valign-bottom .elementor-cta__content{align-content:flex-end;align-items:flex-end}.elementor-cta:hover .elementor-cta__bg-overlay{background-color:rgba(0,0,0,.3)}@media (max-width:1024px){.elementor-cta{cursor:pointer}}@media (min-width:-1){.elementor-cta--widescreen-layout-image-above .elementor-cta,.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--widescreen-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--widescreen-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--widescreen-layout-image-left .elementor-cta,.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--widescreen-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--widescreen-layout-image-left .elementor-cta__content,.elementor-cta--widescreen-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--widescreen-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:-1){.elementor-cta--laptop-layout-image-above .elementor-cta,.elementor-cta--laptop-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--laptop-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--laptop-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--laptop-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--laptop-layout-image-left .elementor-cta,.elementor-cta--laptop-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--laptop-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--laptop-layout-image-left .elementor-cta__content,.elementor-cta--laptop-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--laptop-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--laptop-layout-image-right .elementor-cta{flex-direction:row}.elementor-cta--tablet_extra-layout-image-above .elementor-cta,.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet_extra-layout-image-left .elementor-cta,.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__content,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet_extra-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:1024px){.elementor-cta--tablet-layout-image-above .elementor-cta,.elementor-cta--tablet-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet-layout-image-left .elementor-cta,.elementor-cta--tablet-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet-layout-image-left .elementor-cta__content,.elementor-cta--tablet-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--tablet-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:-1){.elementor-cta--mobile_extra-layout-image-above .elementor-cta,.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile_extra-layout-image-left .elementor-cta,.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__content,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile_extra-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-direction:row}}@media (max-width:767px){.elementor-cta--mobile-layout-image-above .elementor-cta,.elementor-cta--mobile-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile-layout-image-left .elementor-cta,.elementor-cta--mobile-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile-layout-image-left .elementor-cta__content,.elementor-cta--mobile-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile-layout-image-left .elementor-cta{flex-direction:row-reverse}.elementor-cta--mobile-layout-image-right .elementor-cta{flex-direction:row}}.elementor-bg-transform .elementor-bg{will-change:transform}.elementor-bg-transform-zoom-in:hover .elementor-bg,.elementor-bg-transform-zoom-out .elementor-bg{transform:scale(1.2)}.elementor-bg-transform-zoom-out:hover .elementor-bg{transform:scale(1)}.elementor-bg-transform-move-left .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-left:hover .elementor-bg,.elementor-bg-transform-move-right .elementor-bg{transform:scale(1.2) translateX(-8%)}.elementor-bg-transform-move-right:hover .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-up .elementor-bg{transform:scale(1.2) translateY(8%)}.elementor-bg-transform-move-down .elementor-bg,.elementor-bg-transform-move-up:hover .elementor-bg{transform:scale(1.2) translateY(-8%)}.elementor-bg-transform-move-down:hover .elementor-bg{transform:scale(1.2) translateY(8%)} \ No newline at end of file diff --git a/assets/css/widget-call-to-action.min.css b/assets/css/widget-call-to-action.min.css new file mode 100644 index 00000000..d47c09c8 --- /dev/null +++ b/assets/css/widget-call-to-action.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-call-to-action .elementor-widget-container,.elementor-widget-call-to-action:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-cta{display:flex;overflow:hidden;position:relative;transition:.5s}.elementor-cta--skin-classic .elementor-cta{flex-wrap:wrap}.elementor-cta--skin-classic .elementor-cta__bg-wrapper{min-height:200px;position:relative;width:100%}.elementor-cta--skin-classic .elementor-cta__content{background-color:#f9fafa;transition:all .4s;width:100%}.elementor-cta--skin-classic .elementor-cta__content-item,.elementor-cta--skin-classic .elementor-cta__content-item .elementor-icon{border-color:#3f444b;color:#3f444b;fill:#3f444b}.elementor-cta--skin-classic .elementor-cta__button.elementor-button{border-color:#3f444b;color:#3f444b}.elementor-cta--skin-cover .elementor-cta{display:block}.elementor-cta--skin-cover .elementor-cta__bg-wrapper{inset:0;position:absolute;transition:all .4s;width:100%}.elementor-cta--skin-cover .elementor-cta__content{min-height:280px}.elementor-cta--skin-cover .elementor-cta__button.elementor-button,.elementor-cta--skin-cover .elementor-cta__content-item,.elementor-cta--skin-cover .elementor-cta__content-item .elementor-icon{border-color:#fff;color:#fff}.elementor-cta--layout-image-above .elementor-cta,.elementor-cta--layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--layout-image-left .elementor-cta,.elementor-cta--layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--layout-image-left .elementor-cta__content,.elementor-cta--layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--layout-image-right .elementor-cta{flex-direction:row-reverse}.elementor-cta__bg,.elementor-cta__bg-overlay{inset:0;position:absolute;transition:all .4s}.elementor-cta__bg-wrapper{overflow:hidden;z-index:1}.elementor-cta__bg{background-position:50%;background-size:cover;z-index:1}.elementor-cta__bg-overlay{z-index:2}.elementor-cta__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-cta__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-cta__title{font-size:23px}.elementor-cta__content{align-content:center;align-items:center;display:flex;flex-wrap:wrap;overflow:hidden;padding:35px;width:100%;z-index:1}.elementor-cta__content,.elementor-cta__content-item{color:#fff;position:relative;transition:.5s}.elementor-cta__content-item{margin:0;width:100%}.elementor-cta__content-item:not(:last-child){margin-bottom:15px}.elementor-cta__content-item .elementor-icon{color:#fff}.elementor-cta--valign-top .elementor-cta__content{align-content:flex-start;align-items:flex-start}.elementor-cta--valign-middle .elementor-cta__content{align-content:center;align-items:center}.elementor-cta--valign-bottom .elementor-cta__content{align-content:flex-end;align-items:flex-end}.elementor-cta:hover .elementor-cta__bg-overlay{background-color:rgba(0,0,0,.3)}@media (max-width:1024px){.elementor-cta{cursor:pointer}}@media (min-width:-1){.elementor-cta--widescreen-layout-image-above .elementor-cta,.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--widescreen-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--widescreen-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--widescreen-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--widescreen-layout-image-left .elementor-cta,.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--widescreen-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--widescreen-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--widescreen-layout-image-left .elementor-cta__content,.elementor-cta--widescreen-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--widescreen-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--widescreen-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:-1){.elementor-cta--laptop-layout-image-above .elementor-cta,.elementor-cta--laptop-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--laptop-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--laptop-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--laptop-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--laptop-layout-image-left .elementor-cta,.elementor-cta--laptop-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--laptop-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--laptop-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--laptop-layout-image-left .elementor-cta__content,.elementor-cta--laptop-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--laptop-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--laptop-layout-image-right .elementor-cta{flex-direction:row-reverse}.elementor-cta--tablet_extra-layout-image-above .elementor-cta,.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet_extra-layout-image-left .elementor-cta,.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet_extra-layout-image-left .elementor-cta__content,.elementor-cta--tablet_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet_extra-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--tablet_extra-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:1024px){.elementor-cta--tablet-layout-image-above .elementor-cta,.elementor-cta--tablet-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--tablet-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--tablet-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--tablet-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--tablet-layout-image-left .elementor-cta,.elementor-cta--tablet-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--tablet-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--tablet-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--tablet-layout-image-left .elementor-cta__content,.elementor-cta--tablet-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--tablet-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--tablet-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:-1){.elementor-cta--mobile_extra-layout-image-above .elementor-cta,.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile_extra-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile_extra-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile_extra-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile_extra-layout-image-left .elementor-cta,.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile_extra-layout-image-left .elementor-cta__content,.elementor-cta--mobile_extra-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile_extra-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--mobile_extra-layout-image-right .elementor-cta{flex-direction:row-reverse}}@media (max-width:767px){.elementor-cta--mobile-layout-image-above .elementor-cta,.elementor-cta--mobile-layout-image-below .elementor-cta{flex-wrap:wrap}.elementor-cta--mobile-layout-image-above .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-below .elementor-cta__bg-wrapper{width:100%}.elementor-cta--mobile-layout-image-above .elementor-cta{flex-direction:column}.elementor-cta--mobile-layout-image-below .elementor-cta{flex-direction:column-reverse}.elementor-cta--mobile-layout-image-left .elementor-cta,.elementor-cta--mobile-layout-image-right .elementor-cta{flex-wrap:nowrap}.elementor-cta--mobile-layout-image-left .elementor-cta__bg-wrapper,.elementor-cta--mobile-layout-image-right .elementor-cta__bg-wrapper{min-width:50%;width:auto}.elementor-cta--mobile-layout-image-left .elementor-cta__content,.elementor-cta--mobile-layout-image-right .elementor-cta__content{flex-grow:1}.elementor-cta--mobile-layout-image-left .elementor-cta{flex-direction:row}.elementor-cta--mobile-layout-image-right .elementor-cta{flex-direction:row-reverse}}.elementor-bg-transform .elementor-bg{will-change:transform}.elementor-bg-transform-zoom-in:hover .elementor-bg,.elementor-bg-transform-zoom-out .elementor-bg{transform:scale(1.2)}.elementor-bg-transform-zoom-out:hover .elementor-bg{transform:scale(1)}.elementor-bg-transform-move-left .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-left:hover .elementor-bg,.elementor-bg-transform-move-right .elementor-bg{transform:scale(1.2) translateX(-8%)}.elementor-bg-transform-move-right:hover .elementor-bg{transform:scale(1.2) translateX(8%)}.elementor-bg-transform-move-up .elementor-bg{transform:scale(1.2) translateY(8%)}.elementor-bg-transform-move-down .elementor-bg,.elementor-bg-transform-move-up:hover .elementor-bg{transform:scale(1.2) translateY(-8%)}.elementor-bg-transform-move-down:hover .elementor-bg{transform:scale(1.2) translateY(8%)} \ No newline at end of file diff --git a/assets/css/widget-carousel-module-base-rtl.min.css b/assets/css/widget-carousel-module-base-rtl.min.css new file mode 100644 index 00000000..1c2e0d8a --- /dev/null +++ b/assets/css/widget-carousel-module-base-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.swiper-pagination-bullets{color:#fff;cursor:default}.swiper-slide{border-style:solid;border-width:0;overflow:hidden;transition-duration:.5s;transition-property:border,background,transform;will-change:transform}.swiper-slide:not(:hover) .e-overlay-animation-fade{opacity:0}.swiper-slide:not(:hover) .e-overlay-animation-slide-up{transform:translateY(100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-down{transform:translateY(-100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-right{transform:translateX(-100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-left{transform:translateX(100%)}.swiper-slide:not(:hover) .e-overlay-animation-zoom-in{opacity:0;transform:scale(.5)}.swiper-slide a{display:inline}.swiper-slide a.elementor-button{display:inline-block}.elementor-widget-reviews .elementor-arrows-yes .elementor-main-swiper,.elementor-widget-testimonial-carousel .elementor-arrows-yes .elementor-main-swiper{width:calc(95% - 40px)}.elementor-widget-reviews .elementor-main-swiper,.elementor-widget-testimonial-carousel .elementor-main-swiper{width:95%}.elementor-widget-reviews .swiper-wrapper,.elementor-widget-testimonial-carousel .swiper-wrapper{align-items:stretch;display:flex}.elementor-widget-reviews .swiper-slide,.elementor-widget-testimonial-carousel .swiper-slide{height:auto}.elementor-widget-reviews.elementor-pagination-type-bullets .swiper,.elementor-widget-reviews.elementor-pagination-type-bullets .swiper-container,.elementor-widget-reviews.elementor-pagination-type-fraction .swiper,.elementor-widget-reviews.elementor-pagination-type-fraction .swiper-container,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .swiper,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .swiper-container,.elementor-widget-testimonial-carousel.elementor-pagination-type-fraction .swiper,.elementor-widget-testimonial-carousel.elementor-pagination-type-fraction .swiper-container{padding-bottom:40px}.elementor-widget-reviews .elementor-swiper-button-prev,.elementor-widget-reviews .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-reviews .swiper-rtl .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .swiper-rtl .elementor-swiper-button-next{left:0;right:unset}.elementor-widget-reviews .elementor-swiper-button-next,.elementor-widget-reviews .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-reviews .swiper-rtl .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .swiper-rtl .elementor-swiper-button-prev{left:unset;right:0}.elementor-widget-reviews.elementor-pagination-type-bullets .elementor-swiper-button-next,.elementor-widget-reviews.elementor-pagination-type-bullets .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .elementor-swiper-button-next,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .elementor-swiper-button-prev{top:calc(50% - 40px / 2)}.elementor-widget-media-carousel .elementor-swiper-button-prev,.elementor-widget-media-carousel .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-media-carousel .swiper-rtl .elementor-swiper-button-next{left:10px;right:unset}.elementor-widget-media-carousel .elementor-swiper-button-next,.elementor-widget-media-carousel .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-media-carousel .swiper-rtl .elementor-swiper-button-prev{left:unset;right:10px} \ No newline at end of file diff --git a/assets/css/widget-carousel-module-base.min.css b/assets/css/widget-carousel-module-base.min.css new file mode 100644 index 00000000..1c2e0d8a --- /dev/null +++ b/assets/css/widget-carousel-module-base.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.swiper-pagination-bullets{color:#fff;cursor:default}.swiper-slide{border-style:solid;border-width:0;overflow:hidden;transition-duration:.5s;transition-property:border,background,transform;will-change:transform}.swiper-slide:not(:hover) .e-overlay-animation-fade{opacity:0}.swiper-slide:not(:hover) .e-overlay-animation-slide-up{transform:translateY(100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-down{transform:translateY(-100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-right{transform:translateX(-100%)}.swiper-slide:not(:hover) .e-overlay-animation-slide-left{transform:translateX(100%)}.swiper-slide:not(:hover) .e-overlay-animation-zoom-in{opacity:0;transform:scale(.5)}.swiper-slide a{display:inline}.swiper-slide a.elementor-button{display:inline-block}.elementor-widget-reviews .elementor-arrows-yes .elementor-main-swiper,.elementor-widget-testimonial-carousel .elementor-arrows-yes .elementor-main-swiper{width:calc(95% - 40px)}.elementor-widget-reviews .elementor-main-swiper,.elementor-widget-testimonial-carousel .elementor-main-swiper{width:95%}.elementor-widget-reviews .swiper-wrapper,.elementor-widget-testimonial-carousel .swiper-wrapper{align-items:stretch;display:flex}.elementor-widget-reviews .swiper-slide,.elementor-widget-testimonial-carousel .swiper-slide{height:auto}.elementor-widget-reviews.elementor-pagination-type-bullets .swiper,.elementor-widget-reviews.elementor-pagination-type-bullets .swiper-container,.elementor-widget-reviews.elementor-pagination-type-fraction .swiper,.elementor-widget-reviews.elementor-pagination-type-fraction .swiper-container,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .swiper,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .swiper-container,.elementor-widget-testimonial-carousel.elementor-pagination-type-fraction .swiper,.elementor-widget-testimonial-carousel.elementor-pagination-type-fraction .swiper-container{padding-bottom:40px}.elementor-widget-reviews .elementor-swiper-button-prev,.elementor-widget-reviews .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-reviews .swiper-rtl .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .swiper-rtl .elementor-swiper-button-next{left:0;right:unset}.elementor-widget-reviews .elementor-swiper-button-next,.elementor-widget-reviews .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-reviews .swiper-rtl .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .elementor-swiper-button-next,.elementor-widget-testimonial-carousel .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel .swiper-rtl .elementor-swiper-button-prev{left:unset;right:0}.elementor-widget-reviews.elementor-pagination-type-bullets .elementor-swiper-button-next,.elementor-widget-reviews.elementor-pagination-type-bullets .elementor-swiper-button-prev,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .elementor-swiper-button-next,.elementor-widget-testimonial-carousel.elementor-pagination-type-bullets .elementor-swiper-button-prev{top:calc(50% - 40px / 2)}.elementor-widget-media-carousel .elementor-swiper-button-prev,.elementor-widget-media-carousel .swiper-container-rtl .elementor-swiper-button-next,.elementor-widget-media-carousel .swiper-rtl .elementor-swiper-button-next{left:10px;right:unset}.elementor-widget-media-carousel .elementor-swiper-button-next,.elementor-widget-media-carousel .swiper-container-rtl .elementor-swiper-button-prev,.elementor-widget-media-carousel .swiper-rtl .elementor-swiper-button-prev{left:unset;right:10px} \ No newline at end of file diff --git a/assets/css/widget-code-highlight-rtl.min.css b/assets/css/widget-code-highlight-rtl.min.css new file mode 100644 index 00000000..3fc9879a --- /dev/null +++ b/assets/css/widget-code-highlight-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.prismjs-dark code[class*=language-],.prismjs-dark pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-dark pre[class*=language-]{background:#4c3f33;border:.3em solid #7a6651;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-dark :not(pre)>code[class*=language-]{border:.13em solid #7a6651;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-dark .token.cdata,.prismjs-dark .token.doctype,.prismjs-dark .token.prolog,.token.comment{color:#997f66}.prismjs-dark .token.namespace,.prismjs-dark .token.punctuation{opacity:.7}.prismjs-dark .token.boolean,.prismjs-dark .token.constant,.prismjs-dark .token.number,.prismjs-dark .token.property,.prismjs-dark .token.symbol,.prismjs-dark .token.tag{color:#d1939e}.prismjs-dark .token.attr-name,.prismjs-dark .token.builtin,.prismjs-dark .token.char,.prismjs-dark .token.inserted,.prismjs-dark .token.selector,.prismjs-dark .token.string{color:#bce051}.prismjs-dark .language-css .token.string,.prismjs-dark .style .token.string,.prismjs-dark .token.entity,.prismjs-dark .token.operator,.prismjs-dark .token.url,.token.variable{color:#f4b73d}.prismjs-dark .token.atrule,.prismjs-dark .token.attr-value,.prismjs-dark .token.keyword{color:#d1939e}.prismjs-dark .token.important,.prismjs-dark .token.regex{color:#e90}.prismjs-dark .token.bold,.prismjs-dark .token.important{font-weight:700}.prismjs-dark .token.italic{font-style:italic}.prismjs-dark .token.entity{cursor:help}.prismjs-dark .token.deleted{color:red}.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{background:0 0;color:#000;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px #fff;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-default code[class*=language-] ::-moz-selection,.prismjs-default code[class*=language-]::-moz-selection,.prismjs-default pre[class*=language-] ::-moz-selection,.prismjs-default pre[class*=language-]::-moz-selection{background:#b3d4fc;text-shadow:none}.prismjs-default code[class*=language-] ::selection,.prismjs-default code[class*=language-]::selection,.prismjs-default pre[class*=language-] ::selection,.prismjs-default pre[class*=language-]::selection{background:#b3d4fc;text-shadow:none}@media print{.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{text-shadow:none}}.prismjs-default pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-default :not(pre)>code[class*=language-],.prismjs-default pre[class*=language-]{background:#f5f2f0}.prismjs-default :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-default .token.cdata,.prismjs-default .token.comment,.prismjs-default .token.doctype,.prismjs-default .token.prolog{color:#708090}.prismjs-default .token.punctuation{color:#999}.prismjs-default .token.namespace{opacity:.7}.prismjs-default .token.boolean,.prismjs-default .token.constant,.prismjs-default .token.deleted,.prismjs-default .token.number,.prismjs-default .token.property,.prismjs-default .token.symbol,.prismjs-default .token.tag{color:#905}.prismjs-default .token.attr-name,.prismjs-default .token.builtin,.prismjs-default .token.char,.prismjs-default .token.inserted,.prismjs-default .token.selector,.prismjs-default .token.string{color:#690}.prismjs-default .language-css .token.string,.prismjs-default .style .token.string,.prismjs-default .token.entity,.prismjs-default .token.operator,.prismjs-default .token.url{background:hsla(0,0%,100%,.5);color:#9a6e3a}.prismjs-default .token.atrule,.prismjs-default .token.attr-value,.prismjs-default .token.keyword{color:#07a}.prismjs-default .token.class-name,.prismjs-default .token.function{color:#dd4a68}.prismjs-default .token.important,.prismjs-default .token.regex,.prismjs-default .token.variable{color:#e90}.prismjs-default .token.bold,.prismjs-default .token.important{font-weight:700}.prismjs-default .token.italic{font-style:italic}.prismjs-default .token.entity{cursor:help}.prismjs-okaidia code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:0 0;color:#f8f8f2;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px rgba(0,0,0,.3);white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-okaidia pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-okaidia :not(pre)>code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:#272822}.prismjs-okaidia :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-okaidia .token.cdata,.prismjs-okaidia .token.comment,.prismjs-okaidia .token.doctype,.prismjs-okaidia .token.prolog{color:#8292a2}.prismjs-okaidia .token.punctuation{color:#f8f8f2}.prismjs-okaidia .token.namespace{opacity:.7}.prismjs-okaidia .token.constant,.prismjs-okaidia .token.deleted,.prismjs-okaidia .token.property,.prismjs-okaidia .token.symbol,.prismjs-okaidia .token.tag{color:#f92672}.prismjs-okaidia .token.boolean,.prismjs-okaidia .token.number{color:#ae81ff}.prismjs-okaidia .token.attr-name,.prismjs-okaidia .token.builtin,.prismjs-okaidia .token.char,.prismjs-okaidia .token.inserted,.prismjs-okaidia .token.selector,.prismjs-okaidia .token.string{color:#a6e22e}.prismjs-okaidia .language-css .token.string,.prismjs-okaidia .style .token.string,.prismjs-okaidia .token.entity,.prismjs-okaidia .token.operator,.prismjs-okaidia .token.url,.prismjs-okaidia .token.variable{color:#f8f8f2}.prismjs-okaidia .token.atrule,.prismjs-okaidia .token.attr-value,.prismjs-okaidia .token.class-name,.prismjs-okaidia .token.function{color:#e6db74}.prismjs-okaidia .token.keyword{color:#66d9ef}.prismjs-okaidia .token.important,.prismjs-okaidia .token.regex{color:#fd971f}.prismjs-okaidia .token.bold,.prismjs-okaidia .token.important{font-weight:700}.prismjs-okaidia .token.italic{font-style:italic}.prismjs-okaidia .token.entity{cursor:help}.prismjs-solarizedlight code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{color:#657b83;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-solarizedlight code[class*=language-] ::-moz-selection,.prismjs-solarizedlight code[class*=language-]::-moz-selection,.prismjs-solarizedlight pre[class*=language-] ::-moz-selection,.prismjs-solarizedlight pre[class*=language-]::-moz-selection{background:#073642}.prismjs-solarizedlight code[class*=language-] ::selection,.prismjs-solarizedlight code[class*=language-]::selection,.prismjs-solarizedlight pre[class*=language-] ::selection,.prismjs-solarizedlight pre[class*=language-]::selection{background:#073642}.prismjs-solarizedlight pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-solarizedlight :not(pre)>code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{background-color:#fdf6e3}.prismjs-solarizedlight :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em}.prismjs-solarizedlight .token.cdata,.prismjs-solarizedlight .token.comment,.prismjs-solarizedlight .token.doctype,.prismjs-solarizedlight .token.prolog{color:#93a1a1}.prismjs-solarizedlight .token.punctuation{color:#586e75}.prismjs-solarizedlight .token.namespace{opacity:.7}.prismjs-solarizedlight .token.boolean,.prismjs-solarizedlight .token.constant,.prismjs-solarizedlight .token.deleted,.prismjs-solarizedlight .token.number,.prismjs-solarizedlight .token.property,.prismjs-solarizedlight .token.symbol,.token.tag{color:#268bd2}.prismjs-solarizedlight .token.attr-name,.prismjs-solarizedlight .token.builtin,.prismjs-solarizedlight .token.char,.prismjs-solarizedlight .token.inserted,.prismjs-solarizedlight .token.selector,.prismjs-solarizedlight .token.string,.prismjs-solarizedlight .token.url{color:#2aa198}.prismjs-solarizedlight .token.entity{background:#eee8d5;color:#657b83}.prismjs-solarizedlight .token.atrule,.prismjs-solarizedlight .token.attr-value,.prismjs-solarizedlight .token.keyword{color:#859900}.prismjs-solarizedlight .token.class-name,.prismjs-solarizedlight .token.function{color:#b58900}.prismjs-solarizedlight .token.important,.prismjs-solarizedlight .token.regex,.prismjs-solarizedlight .token.variable{color:#cb4b16}.prismjs-solarizedlight .token.bold,.prismjs-solarizedlight .token.important{font-weight:700}.prismjs-solarizedlight .token.italic{font-style:italic}.prismjs-solarizedlight .token.entity{cursor:help}.prismjs-tomorrow code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:0 0;color:#ccc;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-tomorrow pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-tomorrow :not(pre)>code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:#2d2d2d}.prismjs-tomorrow :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-tomorrow .token.block-comment,.prismjs-tomorrow .token.cdata,.prismjs-tomorrow .token.comment,.prismjs-tomorrow .token.doctype,.prismjs-tomorrow .token.prolog{color:#999}.prismjs-tomorrow .token.punctuation{color:#ccc}.prismjs-tomorrow .token.attr-name,.prismjs-tomorrow .token.deleted,.prismjs-tomorrow .token.namespace,.prismjs-tomorrow .token.tag{color:#e2777a}.prismjs-tomorrow .token.function-name{color:#6196cc}.prismjs-tomorrow .token.boolean,.prismjs-tomorrow .token.function,.prismjs-tomorrow .token.number{color:#f08d49}.prismjs-tomorrow .token.class-name,.prismjs-tomorrow .token.constant,.prismjs-tomorrow .token.property,.prismjs-tomorrow .token.symbol{color:#f8c555}.prismjs-tomorrow .token.atrule,.prismjs-tomorrow .token.builtin,.prismjs-tomorrow .token.important,.prismjs-tomorrow .token.keyword,.prismjs-tomorrow .token.selector{color:#cc99cd}.prismjs-tomorrow .token.attr-value,.prismjs-tomorrow .token.char,.prismjs-tomorrow .token.regex,.prismjs-tomorrow .token.string,.prismjs-tomorrow .token.variable{color:#7ec699}.prismjs-tomorrow .token.entity,.prismjs-tomorrow .token.operator,.prismjs-tomorrow .token.url{color:#67cdcc}.prismjs-tomorrow .token.bold,.prismjs-tomorrow .token.important{font-weight:700}.prismjs-tomorrow .token.italic{font-style:italic}.prismjs-tomorrow .token.entity{cursor:help}.prismjs-tomorrow .token.inserted{color:green}.prismjs-twilight code[class*=language-],.prismjs-twilight pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-twilight :not(pre)>code[class*=language-],.prismjs-twilight pre[class*=language-]{background:#141414}.prismjs-twilight pre[class*=language-]{border:.3em solid #545454;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-twilight pre[class*=language-]::-moz-selection{background:#27292a}.prismjs-twilight pre[class*=language-]::selection{background:#27292a}.prismjs-twilight code[class*=language-] ::-moz-selection,.prismjs-twilight code[class*=language-]::-moz-selection,.prismjs-twilight pre[class*=language-] ::-moz-selection,.prismjs-twilight pre[class*=language-]::-moz-selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight code[class*=language-] ::selection,.prismjs-twilight code[class*=language-]::selection,.prismjs-twilight pre[class*=language-] ::selection,.prismjs-twilight pre[class*=language-]::selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight :not(pre)>code[class*=language-]{border:.13em solid #545454;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-twilight .token.cdata,.prismjs-twilight .token.comment,.prismjs-twilight .token.doctype,.prismjs-twilight .token.prolog{color:#777}.prismjs-twilight .token.namespace,.prismjs-twilight .token.punctuation{opacity:.7}.prismjs-twilight .token.boolean,.prismjs-twilight .token.deleted,.prismjs-twilight .token.number,.prismjs-twilight .token.tag{color:#ce6849}.prismjs-twilight .token.builtin,.prismjs-twilight .token.constant,.prismjs-twilight .token.keyword,.prismjs-twilight .token.property,.prismjs-twilight .token.selector,.prismjs-twilight .token.symbol{color:#f9ed99}.prismjs-twilight .language-css .token.string,.prismjs-twilight .style .token.string,.prismjs-twilight .token.attr-name,.prismjs-twilight .token.attr-value,.prismjs-twilight .token.char,.prismjs-twilight .token.entity,.prismjs-twilight .token.inserted,.prismjs-twilight .token.operator,.prismjs-twilight .token.string,.prismjs-twilight .token.url,.prismjs-twilight .token.variable{color:#909e6a}.prismjs-twilight .token.atrule{color:#7385a5}.prismjs-twilight .token.important,.prismjs-twilight .token.regex{color:#e8c062}.prismjs-twilight .token.bold,.prismjs-twilight .token.important{font-weight:700}.prismjs-twilight .token.italic{font-style:italic}.prismjs-twilight .token.entity{cursor:help}.prismjs-twilight pre[data-line]{padding:1em;position:relative}.prismjs-twilight .language-markup .token.attr-name,.prismjs-twilight .language-markup .token.punctuation,.prismjs-twilight .language-markup .token.tag{color:#ac885c}.prismjs-twilight .token{position:relative;z-index:1}.prismjs-twilight .line-highlight{background:rgba(84,84,84,.25);background:linear-gradient(90deg,rgba(84,84,84,.1) 70%,rgba(84,84,84,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;left:0;line-height:inherit;margin-top:.75em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre;z-index:0}.prismjs-twilight .line-highlight:before,.prismjs-twilight .line-highlight[data-end]:after{background-color:#8693a6;border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.prismjs-twilight .line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.copy-to-clipboard div.code-toolbar{position:relative}.copy-to-clipboard div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out}.copy-to-clipboard div.code-toolbar:hover>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar:focus-within>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar>.toolbar .toolbar-item{display:inline-block}.copy-to-clipboard div.code-toolbar>.toolbar a{cursor:pointer}.copy-to-clipboard div.code-toolbar>.toolbar button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.copy-to-clipboard div.code-toolbar>.toolbar a,.copy-to-clipboard div.code-toolbar>.toolbar button,.copy-to-clipboard div.code-toolbar>.toolbar span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}.copy-to-clipboard div.code-toolbar>.toolbar a:focus,div.code-toolbar>.toolbar a:hover,div.code-toolbar>.toolbar button:focus,div.code-toolbar>.toolbar button:hover,div.code-toolbar>.toolbar span:focus,div.code-toolbar>.toolbar span:hover{color:inherit;text-decoration:none}:not(.copy-to-clipboard)>div.code-toolbar>.toolbar{display:none}.word-wrap code[class*=language-],.word-wrap pre[class*=language-]{white-space:pre-wrap!important}.elementor-widget-code-highlight .elementor-widget-container,.elementor-widget-code-highlight:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-widget-code-highlight pre{direction:ltr}.prismjs-twilight pre:not([data-line=""]):not(.line-numbers){padding:.8em 0 1em 2em}.prismjs-dark pre:not([data-line=""]):not(.line-numbers),.prismjs-default pre:not([data-line=""]):not(.line-numbers),.prismjs-okaidia pre:not([data-line=""]):not(.line-numbers),.prismjs-solarizedlight pre:not([data-line=""]):not(.line-numbers),.prismjs-tomorrow pre:not([data-line=""]):not(.line-numbers){padding:1em 0 1em 2em}pre[data-line]{padding:1em 0 1em 3em;position:relative}.line-highlight{background:hsla(24,20%,50%,.08);background:linear-gradient(90deg,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));left:0;line-height:inherit;margin-top:1em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{background-color:hsla(24,20%,50%,.4);border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:hsla(0,0%,50%,.2)}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right} \ No newline at end of file diff --git a/assets/css/widget-code-highlight.min.css b/assets/css/widget-code-highlight.min.css new file mode 100644 index 00000000..3fc9879a --- /dev/null +++ b/assets/css/widget-code-highlight.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.prismjs-dark code[class*=language-],.prismjs-dark pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-dark pre[class*=language-]{background:#4c3f33;border:.3em solid #7a6651;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-dark :not(pre)>code[class*=language-]{border:.13em solid #7a6651;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-dark .token.cdata,.prismjs-dark .token.doctype,.prismjs-dark .token.prolog,.token.comment{color:#997f66}.prismjs-dark .token.namespace,.prismjs-dark .token.punctuation{opacity:.7}.prismjs-dark .token.boolean,.prismjs-dark .token.constant,.prismjs-dark .token.number,.prismjs-dark .token.property,.prismjs-dark .token.symbol,.prismjs-dark .token.tag{color:#d1939e}.prismjs-dark .token.attr-name,.prismjs-dark .token.builtin,.prismjs-dark .token.char,.prismjs-dark .token.inserted,.prismjs-dark .token.selector,.prismjs-dark .token.string{color:#bce051}.prismjs-dark .language-css .token.string,.prismjs-dark .style .token.string,.prismjs-dark .token.entity,.prismjs-dark .token.operator,.prismjs-dark .token.url,.token.variable{color:#f4b73d}.prismjs-dark .token.atrule,.prismjs-dark .token.attr-value,.prismjs-dark .token.keyword{color:#d1939e}.prismjs-dark .token.important,.prismjs-dark .token.regex{color:#e90}.prismjs-dark .token.bold,.prismjs-dark .token.important{font-weight:700}.prismjs-dark .token.italic{font-style:italic}.prismjs-dark .token.entity{cursor:help}.prismjs-dark .token.deleted{color:red}.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{background:0 0;color:#000;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px #fff;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-default code[class*=language-] ::-moz-selection,.prismjs-default code[class*=language-]::-moz-selection,.prismjs-default pre[class*=language-] ::-moz-selection,.prismjs-default pre[class*=language-]::-moz-selection{background:#b3d4fc;text-shadow:none}.prismjs-default code[class*=language-] ::selection,.prismjs-default code[class*=language-]::selection,.prismjs-default pre[class*=language-] ::selection,.prismjs-default pre[class*=language-]::selection{background:#b3d4fc;text-shadow:none}@media print{.prismjs-default code[class*=language-],.prismjs-default pre[class*=language-]{text-shadow:none}}.prismjs-default pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-default :not(pre)>code[class*=language-],.prismjs-default pre[class*=language-]{background:#f5f2f0}.prismjs-default :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-default .token.cdata,.prismjs-default .token.comment,.prismjs-default .token.doctype,.prismjs-default .token.prolog{color:#708090}.prismjs-default .token.punctuation{color:#999}.prismjs-default .token.namespace{opacity:.7}.prismjs-default .token.boolean,.prismjs-default .token.constant,.prismjs-default .token.deleted,.prismjs-default .token.number,.prismjs-default .token.property,.prismjs-default .token.symbol,.prismjs-default .token.tag{color:#905}.prismjs-default .token.attr-name,.prismjs-default .token.builtin,.prismjs-default .token.char,.prismjs-default .token.inserted,.prismjs-default .token.selector,.prismjs-default .token.string{color:#690}.prismjs-default .language-css .token.string,.prismjs-default .style .token.string,.prismjs-default .token.entity,.prismjs-default .token.operator,.prismjs-default .token.url{background:hsla(0,0%,100%,.5);color:#9a6e3a}.prismjs-default .token.atrule,.prismjs-default .token.attr-value,.prismjs-default .token.keyword{color:#07a}.prismjs-default .token.class-name,.prismjs-default .token.function{color:#dd4a68}.prismjs-default .token.important,.prismjs-default .token.regex,.prismjs-default .token.variable{color:#e90}.prismjs-default .token.bold,.prismjs-default .token.important{font-weight:700}.prismjs-default .token.italic{font-style:italic}.prismjs-default .token.entity{cursor:help}.prismjs-okaidia code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:0 0;color:#f8f8f2;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 1px rgba(0,0,0,.3);white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-okaidia pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-okaidia :not(pre)>code[class*=language-],.prismjs-okaidia pre[class*=language-]{background:#272822}.prismjs-okaidia :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-okaidia .token.cdata,.prismjs-okaidia .token.comment,.prismjs-okaidia .token.doctype,.prismjs-okaidia .token.prolog{color:#8292a2}.prismjs-okaidia .token.punctuation{color:#f8f8f2}.prismjs-okaidia .token.namespace{opacity:.7}.prismjs-okaidia .token.constant,.prismjs-okaidia .token.deleted,.prismjs-okaidia .token.property,.prismjs-okaidia .token.symbol,.prismjs-okaidia .token.tag{color:#f92672}.prismjs-okaidia .token.boolean,.prismjs-okaidia .token.number{color:#ae81ff}.prismjs-okaidia .token.attr-name,.prismjs-okaidia .token.builtin,.prismjs-okaidia .token.char,.prismjs-okaidia .token.inserted,.prismjs-okaidia .token.selector,.prismjs-okaidia .token.string{color:#a6e22e}.prismjs-okaidia .language-css .token.string,.prismjs-okaidia .style .token.string,.prismjs-okaidia .token.entity,.prismjs-okaidia .token.operator,.prismjs-okaidia .token.url,.prismjs-okaidia .token.variable{color:#f8f8f2}.prismjs-okaidia .token.atrule,.prismjs-okaidia .token.attr-value,.prismjs-okaidia .token.class-name,.prismjs-okaidia .token.function{color:#e6db74}.prismjs-okaidia .token.keyword{color:#66d9ef}.prismjs-okaidia .token.important,.prismjs-okaidia .token.regex{color:#fd971f}.prismjs-okaidia .token.bold,.prismjs-okaidia .token.important{font-weight:700}.prismjs-okaidia .token.italic{font-style:italic}.prismjs-okaidia .token.entity{cursor:help}.prismjs-solarizedlight code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{color:#657b83;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-solarizedlight code[class*=language-] ::-moz-selection,.prismjs-solarizedlight code[class*=language-]::-moz-selection,.prismjs-solarizedlight pre[class*=language-] ::-moz-selection,.prismjs-solarizedlight pre[class*=language-]::-moz-selection{background:#073642}.prismjs-solarizedlight code[class*=language-] ::selection,.prismjs-solarizedlight code[class*=language-]::selection,.prismjs-solarizedlight pre[class*=language-] ::selection,.prismjs-solarizedlight pre[class*=language-]::selection{background:#073642}.prismjs-solarizedlight pre[class*=language-]{border-radius:.3em;margin:0;overflow:auto;padding:1em}.prismjs-solarizedlight :not(pre)>code[class*=language-],.prismjs-solarizedlight pre[class*=language-]{background-color:#fdf6e3}.prismjs-solarizedlight :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em}.prismjs-solarizedlight .token.cdata,.prismjs-solarizedlight .token.comment,.prismjs-solarizedlight .token.doctype,.prismjs-solarizedlight .token.prolog{color:#93a1a1}.prismjs-solarizedlight .token.punctuation{color:#586e75}.prismjs-solarizedlight .token.namespace{opacity:.7}.prismjs-solarizedlight .token.boolean,.prismjs-solarizedlight .token.constant,.prismjs-solarizedlight .token.deleted,.prismjs-solarizedlight .token.number,.prismjs-solarizedlight .token.property,.prismjs-solarizedlight .token.symbol,.token.tag{color:#268bd2}.prismjs-solarizedlight .token.attr-name,.prismjs-solarizedlight .token.builtin,.prismjs-solarizedlight .token.char,.prismjs-solarizedlight .token.inserted,.prismjs-solarizedlight .token.selector,.prismjs-solarizedlight .token.string,.prismjs-solarizedlight .token.url{color:#2aa198}.prismjs-solarizedlight .token.entity{background:#eee8d5;color:#657b83}.prismjs-solarizedlight .token.atrule,.prismjs-solarizedlight .token.attr-value,.prismjs-solarizedlight .token.keyword{color:#859900}.prismjs-solarizedlight .token.class-name,.prismjs-solarizedlight .token.function{color:#b58900}.prismjs-solarizedlight .token.important,.prismjs-solarizedlight .token.regex,.prismjs-solarizedlight .token.variable{color:#cb4b16}.prismjs-solarizedlight .token.bold,.prismjs-solarizedlight .token.important{font-weight:700}.prismjs-solarizedlight .token.italic{font-style:italic}.prismjs-solarizedlight .token.entity{cursor:help}.prismjs-tomorrow code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:0 0;color:#ccc;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-tomorrow pre[class*=language-]{margin:0;overflow:auto;padding:1em}.prismjs-tomorrow :not(pre)>code[class*=language-],.prismjs-tomorrow pre[class*=language-]{background:#2d2d2d}.prismjs-tomorrow :not(pre)>code[class*=language-]{border-radius:.3em;padding:.1em;white-space:normal}.prismjs-tomorrow .token.block-comment,.prismjs-tomorrow .token.cdata,.prismjs-tomorrow .token.comment,.prismjs-tomorrow .token.doctype,.prismjs-tomorrow .token.prolog{color:#999}.prismjs-tomorrow .token.punctuation{color:#ccc}.prismjs-tomorrow .token.attr-name,.prismjs-tomorrow .token.deleted,.prismjs-tomorrow .token.namespace,.prismjs-tomorrow .token.tag{color:#e2777a}.prismjs-tomorrow .token.function-name{color:#6196cc}.prismjs-tomorrow .token.boolean,.prismjs-tomorrow .token.function,.prismjs-tomorrow .token.number{color:#f08d49}.prismjs-tomorrow .token.class-name,.prismjs-tomorrow .token.constant,.prismjs-tomorrow .token.property,.prismjs-tomorrow .token.symbol{color:#f8c555}.prismjs-tomorrow .token.atrule,.prismjs-tomorrow .token.builtin,.prismjs-tomorrow .token.important,.prismjs-tomorrow .token.keyword,.prismjs-tomorrow .token.selector{color:#cc99cd}.prismjs-tomorrow .token.attr-value,.prismjs-tomorrow .token.char,.prismjs-tomorrow .token.regex,.prismjs-tomorrow .token.string,.prismjs-tomorrow .token.variable{color:#7ec699}.prismjs-tomorrow .token.entity,.prismjs-tomorrow .token.operator,.prismjs-tomorrow .token.url{color:#67cdcc}.prismjs-tomorrow .token.bold,.prismjs-tomorrow .token.important{font-weight:700}.prismjs-tomorrow .token.italic{font-style:italic}.prismjs-tomorrow .token.entity{cursor:help}.prismjs-tomorrow .token.inserted{color:green}.prismjs-twilight code[class*=language-],.prismjs-twilight pre[class*=language-]{background:0 0;color:#fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal;-webkit-hyphens:none;hyphens:none;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.prismjs-twilight :not(pre)>code[class*=language-],.prismjs-twilight pre[class*=language-]{background:#141414}.prismjs-twilight pre[class*=language-]{border:.3em solid #545454;border-radius:.5em;box-shadow:inset 1px 1px .5em #000;margin:0;overflow:auto;padding:1em}.prismjs-twilight pre[class*=language-]::-moz-selection{background:#27292a}.prismjs-twilight pre[class*=language-]::selection{background:#27292a}.prismjs-twilight code[class*=language-] ::-moz-selection,.prismjs-twilight code[class*=language-]::-moz-selection,.prismjs-twilight pre[class*=language-] ::-moz-selection,.prismjs-twilight pre[class*=language-]::-moz-selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight code[class*=language-] ::selection,.prismjs-twilight code[class*=language-]::selection,.prismjs-twilight pre[class*=language-] ::selection,.prismjs-twilight pre[class*=language-]::selection{background:hsla(0,0%,93%,.15);text-shadow:none}.prismjs-twilight :not(pre)>code[class*=language-]{border:.13em solid #545454;border-radius:.3em;box-shadow:inset 1px 1px .3em -.1em #000;padding:.15em .2em .05em;white-space:normal}.prismjs-twilight .token.cdata,.prismjs-twilight .token.comment,.prismjs-twilight .token.doctype,.prismjs-twilight .token.prolog{color:#777}.prismjs-twilight .token.namespace,.prismjs-twilight .token.punctuation{opacity:.7}.prismjs-twilight .token.boolean,.prismjs-twilight .token.deleted,.prismjs-twilight .token.number,.prismjs-twilight .token.tag{color:#ce6849}.prismjs-twilight .token.builtin,.prismjs-twilight .token.constant,.prismjs-twilight .token.keyword,.prismjs-twilight .token.property,.prismjs-twilight .token.selector,.prismjs-twilight .token.symbol{color:#f9ed99}.prismjs-twilight .language-css .token.string,.prismjs-twilight .style .token.string,.prismjs-twilight .token.attr-name,.prismjs-twilight .token.attr-value,.prismjs-twilight .token.char,.prismjs-twilight .token.entity,.prismjs-twilight .token.inserted,.prismjs-twilight .token.operator,.prismjs-twilight .token.string,.prismjs-twilight .token.url,.prismjs-twilight .token.variable{color:#909e6a}.prismjs-twilight .token.atrule{color:#7385a5}.prismjs-twilight .token.important,.prismjs-twilight .token.regex{color:#e8c062}.prismjs-twilight .token.bold,.prismjs-twilight .token.important{font-weight:700}.prismjs-twilight .token.italic{font-style:italic}.prismjs-twilight .token.entity{cursor:help}.prismjs-twilight pre[data-line]{padding:1em;position:relative}.prismjs-twilight .language-markup .token.attr-name,.prismjs-twilight .language-markup .token.punctuation,.prismjs-twilight .language-markup .token.tag{color:#ac885c}.prismjs-twilight .token{position:relative;z-index:1}.prismjs-twilight .line-highlight{background:rgba(84,84,84,.25);background:linear-gradient(90deg,rgba(84,84,84,.1) 70%,rgba(84,84,84,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;left:0;line-height:inherit;margin-top:.75em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre;z-index:0}.prismjs-twilight .line-highlight:before,.prismjs-twilight .line-highlight[data-end]:after{background-color:#8693a6;border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.prismjs-twilight .line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.copy-to-clipboard div.code-toolbar{position:relative}.copy-to-clipboard div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out}.copy-to-clipboard div.code-toolbar:hover>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar:focus-within>.toolbar{opacity:1}.copy-to-clipboard div.code-toolbar>.toolbar .toolbar-item{display:inline-block}.copy-to-clipboard div.code-toolbar>.toolbar a{cursor:pointer}.copy-to-clipboard div.code-toolbar>.toolbar button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.copy-to-clipboard div.code-toolbar>.toolbar a,.copy-to-clipboard div.code-toolbar>.toolbar button,.copy-to-clipboard div.code-toolbar>.toolbar span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}.copy-to-clipboard div.code-toolbar>.toolbar a:focus,div.code-toolbar>.toolbar a:hover,div.code-toolbar>.toolbar button:focus,div.code-toolbar>.toolbar button:hover,div.code-toolbar>.toolbar span:focus,div.code-toolbar>.toolbar span:hover{color:inherit;text-decoration:none}:not(.copy-to-clipboard)>div.code-toolbar>.toolbar{display:none}.word-wrap code[class*=language-],.word-wrap pre[class*=language-]{white-space:pre-wrap!important}.elementor-widget-code-highlight .elementor-widget-container,.elementor-widget-code-highlight:not(:has(.elementor-widget-container)){overflow:hidden}.elementor-widget-code-highlight pre{direction:ltr}.prismjs-twilight pre:not([data-line=""]):not(.line-numbers){padding:.8em 0 1em 2em}.prismjs-dark pre:not([data-line=""]):not(.line-numbers),.prismjs-default pre:not([data-line=""]):not(.line-numbers),.prismjs-okaidia pre:not([data-line=""]):not(.line-numbers),.prismjs-solarizedlight pre:not([data-line=""]):not(.line-numbers),.prismjs-tomorrow pre:not([data-line=""]):not(.line-numbers){padding:1em 0 1em 2em}pre[data-line]{padding:1em 0 1em 3em;position:relative}.line-highlight{background:hsla(24,20%,50%,.08);background:linear-gradient(90deg,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));left:0;line-height:inherit;margin-top:1em;padding-bottom:inherit;padding-left:0;padding-right:0;padding-top:inherit;pointer-events:none;position:absolute;right:0;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{background-color:hsla(24,20%,50%,.4);border-radius:999px;box-shadow:0 1px #fff;color:#f4f1ef;content:attr(data-start);font:700 65%/1.5 sans-serif;left:.6em;min-width:1em;padding:0 .5em;position:absolute;text-align:center;text-shadow:none;top:.4em;vertical-align:.3em}.line-highlight[data-end]:after{bottom:.4em;content:attr(data-end);top:auto}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:hsla(0,0%,50%,.2)}pre[class*=language-].line-numbers{counter-reset:linenumber;padding-left:3.8em;position:relative}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{border-right:1px solid #999;font-size:100%;left:-3.8em;letter-spacing:-1px;pointer-events:none;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:3em}.line-numbers-rows>span{counter-increment:linenumber;display:block}.line-numbers-rows>span:before{color:#999;content:counter(linenumber);display:block;padding-right:.8em;text-align:right} \ No newline at end of file diff --git a/assets/css/widget-countdown-rtl.min.css b/assets/css/widget-countdown-rtl.min.css new file mode 100644 index 00000000..4af511a5 --- /dev/null +++ b/assets/css/widget-countdown-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-countdown .elementor-countdown-expire--message{display:none;padding:20px;text-align:center}.elementor-widget-countdown .elementor-countdown-wrapper{flex-direction:row-reverse}.elementor-widget-countdown .elementor-countdown-item{color:#fff;padding:20px 0;text-align:center}.elementor-widget-countdown .elementor-countdown-digits,.elementor-widget-countdown .elementor-countdown-label{line-height:1}.elementor-widget-countdown .elementor-countdown-digits{font-size:69px}.elementor-widget-countdown .elementor-countdown-label{font-size:19px}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-wrapper{display:flex;justify-content:center;margin-left:auto;margin-right:auto}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-digits,.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-label{display:block}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-item{flex-basis:0;flex-grow:1}.elementor-widget-countdown.elementor-countdown--label-inline{text-align:center}.elementor-widget-countdown.elementor-countdown--label-inline .elementor-countdown-item{display:inline-block;padding-left:5px;padding-right:5px} \ No newline at end of file diff --git a/assets/css/widget-countdown.min.css b/assets/css/widget-countdown.min.css new file mode 100644 index 00000000..6547da6c --- /dev/null +++ b/assets/css/widget-countdown.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-countdown .elementor-countdown-expire--message{display:none;padding:20px;text-align:center}.elementor-widget-countdown .elementor-countdown-wrapper{flex-direction:row}.elementor-widget-countdown .elementor-countdown-item{color:#fff;padding:20px 0;text-align:center}.elementor-widget-countdown .elementor-countdown-digits,.elementor-widget-countdown .elementor-countdown-label{line-height:1}.elementor-widget-countdown .elementor-countdown-digits{font-size:69px}.elementor-widget-countdown .elementor-countdown-label{font-size:19px}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-wrapper{display:flex;justify-content:center;margin-left:auto;margin-right:auto}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-digits,.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-label{display:block}.elementor-widget-countdown.elementor-countdown--label-block .elementor-countdown-item{flex-basis:0;flex-grow:1}.elementor-widget-countdown.elementor-countdown--label-inline{text-align:center}.elementor-widget-countdown.elementor-countdown--label-inline .elementor-countdown-item{display:inline-block;padding-left:5px;padding-right:5px} \ No newline at end of file diff --git a/assets/css/widget-flip-box-rtl.min.css b/assets/css/widget-flip-box-rtl.min.css new file mode 100644 index 00000000..5d2cbe47 --- /dev/null +++ b/assets/css/widget-flip-box-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-flip-box{height:280px;perspective:1000px;position:relative;transform-style:preserve-3d}@media (max-width:1024px){.elementor-flip-box{cursor:pointer}}.elementor-flip-box__front{background-color:#1abc9c}.elementor-flip-box__back{background-color:#4054b2;display:block}.elementor-flip-box__layer{height:100%;position:absolute;transition:all .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.elementor-flip-box__layer{transition-duration:0s}}.elementor-flip-box__layer__overlay{align-items:stretch;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:center;padding:35px;text-align:center;width:100%}.elementor-flip-box__layer__title{font-size:21px}.elementor-flip-box__layer__description{font-size:14px}.elementor-flip-box__layer__description:not(:last-child),.elementor-flip-box__layer__title:not(:last-child){margin:0 0 20px;padding:0}.elementor-flip-box__layer__title{font-weight:600;line-height:1}.elementor-flip-box,.elementor-flip-box .elementor-view-framed,.elementor-flip-box .elementor-view-stacked{--e-flip-box-view-framed-stacked-icon-color:#fff}.elementor-flip-box .elementor-icon,.elementor-flip-box .elementor-view-framed .elementor-icon,.elementor-flip-box .elementor-view-stacked .elementor-icon{color:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-icon svg,.elementor-flip-box .elementor-view-framed .elementor-icon svg,.elementor-flip-box .elementor-view-stacked .elementor-icon svg{fill:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-view-framed .elementor-icon{border-color:#fff}.elementor-flip-box .elementor-view-stacked .elementor-icon{background-color:rgba(0,0,0,.5)}.elementor-flip-box__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-flip-box__button.elementor-button:focus-visible,.elementor-flip-box__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-flip-box__image{display:inline-block;margin:0 0 20px;width:100%}.elementor-flip-box__image img{width:50%}.elementor-flip-box .elementor-icon-wrapper{margin-bottom:20px}.elementor-flip-box--3d .elementor-flip-box__layer__inner{transform:translateZ(90px) scale(.91)}.elementor-flip-box--3d .elementor-flip-box__layer__overlay{transform:translateZ(.1px);transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box{perspective:1000px;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__layer{backface-visibility:hidden;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__front{transform:none;z-index:1}.elementor-flip-box--effect-flip .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-flip .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box__back{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box__back{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box__back{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box__back{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-push .elementor-flip-box__front{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push .elementor-flip-box,.elementor-flip-box--effect-slide .elementor-flip-box{overflow:hidden}.elementor-flip-box--effect-push .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-push .elementor-flip-box:hover .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-right .elementor-flip-box__back{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-left .elementor-flip-box__back{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-up .elementor-flip-box__back{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-down .elementor-flip-box__back{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{opacity:1;transform:scale(1);transition:transform .7s,opacity .35s,width .1ms;width:100%;z-index:1}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{transition-duration:0s}}.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{opacity:0;transform:scale(.7);transition:transform .8s,opacity .7s .1s,width .1ms .7s;width:0}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{opacity:0;transform:scale(.7);transition:transform .7s,opacity .5s .2s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{opacity:1;transform:scale(1);transition:transform .7s,opacity .5s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{transition-duration:0s}}.elementor-flip-box--effect-fade .elementor-flip-box .elementor-flip-box__back{opacity:0}.elementor-flip-box--effect-fade .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-fade .elementor-flip-box:hover .elementor-flip-box__back{opacity:1}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__front,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__front{display:none}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__back,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__back{opacity:1;transform:none}.e-con-inner>.elementor-widget-flip-box,.e-con>.elementor-widget-flip-box{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-flip-box.min.css b/assets/css/widget-flip-box.min.css new file mode 100644 index 00000000..5d2cbe47 --- /dev/null +++ b/assets/css/widget-flip-box.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-flip-box{height:280px;perspective:1000px;position:relative;transform-style:preserve-3d}@media (max-width:1024px){.elementor-flip-box{cursor:pointer}}.elementor-flip-box__front{background-color:#1abc9c}.elementor-flip-box__back{background-color:#4054b2;display:block}.elementor-flip-box__layer{height:100%;position:absolute;transition:all .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.elementor-flip-box__layer{transition-duration:0s}}.elementor-flip-box__layer__overlay{align-items:stretch;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:center;padding:35px;text-align:center;width:100%}.elementor-flip-box__layer__title{font-size:21px}.elementor-flip-box__layer__description{font-size:14px}.elementor-flip-box__layer__description:not(:last-child),.elementor-flip-box__layer__title:not(:last-child){margin:0 0 20px;padding:0}.elementor-flip-box__layer__title{font-weight:600;line-height:1}.elementor-flip-box,.elementor-flip-box .elementor-view-framed,.elementor-flip-box .elementor-view-stacked{--e-flip-box-view-framed-stacked-icon-color:#fff}.elementor-flip-box .elementor-icon,.elementor-flip-box .elementor-view-framed .elementor-icon,.elementor-flip-box .elementor-view-stacked .elementor-icon{color:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-icon svg,.elementor-flip-box .elementor-view-framed .elementor-icon svg,.elementor-flip-box .elementor-view-stacked .elementor-icon svg{fill:var(--e-flip-box-view-framed-stacked-icon-color)}.elementor-flip-box .elementor-view-framed .elementor-icon{border-color:#fff}.elementor-flip-box .elementor-view-stacked .elementor-icon{background-color:rgba(0,0,0,.5)}.elementor-flip-box__button.elementor-button{align-self:center;background:transparent;border:2px solid #fff;cursor:pointer;margin-left:auto;margin-right:auto}.elementor-flip-box__button.elementor-button:focus-visible,.elementor-flip-box__button.elementor-button:hover{background:transparent;text-decoration:none}.elementor-flip-box__image{display:inline-block;margin:0 0 20px;width:100%}.elementor-flip-box__image img{width:50%}.elementor-flip-box .elementor-icon-wrapper{margin-bottom:20px}.elementor-flip-box--3d .elementor-flip-box__layer__inner{transform:translateZ(90px) scale(.91)}.elementor-flip-box--3d .elementor-flip-box__layer__overlay{transform:translateZ(.1px);transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box{perspective:1000px;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__layer{backface-visibility:hidden;transform-style:preserve-3d}.elementor-flip-box--effect-flip .elementor-flip-box__front{transform:none;z-index:1}.elementor-flip-box--effect-flip .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-flip .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box__back{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box__back{transform:rotateX(0) rotateY(180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(0) rotateY(-180deg)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box__back{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box__back{transform:rotateX(180deg) rotateY(0)}.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-flip.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:rotateX(-180deg) rotateY(0)}.elementor-flip-box--effect-push .elementor-flip-box__front{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box:hover .elementor-flip-box__front{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push .elementor-flip-box,.elementor-flip-box--effect-slide .elementor-flip-box{overflow:hidden}.elementor-flip-box--effect-push .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-push .elementor-flip-box:hover .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-slide .elementor-flip-box:hover .elementor-flip-box__back{transform:none}.elementor-flip-box--effect-push.elementor-flip-box--direction-right .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-right .elementor-flip-box__back{transform:translateX(-100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-left .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-left .elementor-flip-box__back{transform:translateX(100%) translateY(0)}.elementor-flip-box--effect-push.elementor-flip-box--direction-up .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-up .elementor-flip-box__back{transform:translateX(0) translateY(100%)}.elementor-flip-box--effect-push.elementor-flip-box--direction-down .elementor-flip-box__back,.elementor-flip-box--effect-slide.elementor-flip-box--direction-down .elementor-flip-box__back{transform:translateX(0) translateY(-100%)}.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{opacity:1;transform:scale(1);transition:transform .7s,opacity .35s,width .1ms;width:100%;z-index:1}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box .elementor-flip-box__front{transition-duration:0s}}.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{opacity:0;transform:scale(.7);transition:transform .8s,opacity .7s .1s,width .1ms .7s;width:0}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-out .elementor-flip-box:focus-visible .elementor-flip-box__front,.elementor-flip-box--effect-zoom-out .elementor-flip-box:hover .elementor-flip-box__front{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{opacity:0;transform:scale(.7);transition:transform .7s,opacity .5s .2s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box .elementor-flip-box__back{transition-delay:0s;transition-duration:0s}}.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{opacity:1;transform:scale(1);transition:transform .7s,opacity .5s}@media (prefers-reduced-motion:reduce){.elementor-flip-box--effect-zoom-in .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-zoom-in .elementor-flip-box:hover .elementor-flip-box__back{transition-duration:0s}}.elementor-flip-box--effect-fade .elementor-flip-box .elementor-flip-box__back{opacity:0}.elementor-flip-box--effect-fade .elementor-flip-box:focus-visible .elementor-flip-box__back,.elementor-flip-box--effect-fade .elementor-flip-box:hover .elementor-flip-box__back{opacity:1}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__front,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__front{display:none}.elementor-widget-flip-box.elementor-flip-box--flipped .elementor-widget-container .elementor-flip-box__back,.elementor-widget-flip-box.elementor-flip-box--flipped:not(:has(.elementor-widget-container)) .elementor-flip-box__back{opacity:1;transform:none}.e-con-inner>.elementor-widget-flip-box,.e-con>.elementor-widget-flip-box{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-form-rtl.min.css b/assets/css/widget-form-rtl.min.css new file mode 100644 index 00000000..7e61d85a --- /dev/null +++ b/assets/css/widget-form-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-button.elementor-hidden,.elementor-hidden{display:none}.e-form__step{width:100%}.e-form__step:not(.elementor-hidden){display:flex;flex-wrap:wrap}.e-form__buttons{flex-wrap:wrap}.e-form__buttons,.e-form__buttons__wrapper{display:flex}.e-form__indicators{align-items:center;display:flex;flex-wrap:nowrap;font-size:13px;justify-content:space-between;margin-bottom:var(--e-form-steps-indicators-spacing)}.e-form__indicators__indicator{align-items:center;display:flex;flex-basis:0;flex-direction:column;justify-content:center;padding:0 var(--e-form-steps-divider-gap)}.e-form__indicators__indicator__progress{background-color:var(--e-form-steps-indicator-progress-background-color);border-radius:var(--e-form-steps-indicator-progress-border-radius);overflow:hidden;position:relative;width:100%}.e-form__indicators__indicator__progress__meter{background-color:var(--e-form-steps-indicator-progress-color);border-radius:var(--e-form-steps-indicator-progress-border-radius);color:var(--e-form-steps-indicator-progress-meter-color);height:var(--e-form-steps-indicator-progress-height);line-height:var(--e-form-steps-indicator-progress-height);padding-right:15px;text-align:right;transition:width .1s linear;width:var(--e-form-steps-indicator-progress-meter-width,0)}.e-form__indicators__indicator:first-child{padding-left:0}.e-form__indicators__indicator:last-child{padding-right:0}.e-form__indicators__indicator--state-inactive{color:var(--e-form-steps-indicator-inactive-primary-color,#c2cbd2)}.e-form__indicators__indicator--state-inactive [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-inactive-secondary-color,#fff)}.e-form__indicators__indicator--state-inactive object,.e-form__indicators__indicator--state-inactive svg{fill:var(--e-form-steps-indicator-inactive-primary-color,#c2cbd2)}.e-form__indicators__indicator--state-active{border-color:var(--e-form-steps-indicator-active-secondary-color,#fff);color:var(--e-form-steps-indicator-active-primary-color,#39b54a)}.e-form__indicators__indicator--state-active [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-active-secondary-color,#fff)}.e-form__indicators__indicator--state-active object,.e-form__indicators__indicator--state-active svg{fill:var(--e-form-steps-indicator-active-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed{color:var(--e-form-steps-indicator-completed-secondary-color,#fff)}.e-form__indicators__indicator--state-completed [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed .e-form__indicators__indicator__label{color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed .e-form__indicators__indicator--shape-none{background-color:initial;color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed object,.e-form__indicators__indicator--state-completed svg{fill:var(--e-form-steps-indicator-completed-secondary-color,#fff)}.e-form__indicators__indicator__icon{align-items:center;border-style:solid;border-width:1px;display:flex;font-size:var(--e-form-steps-indicator-icon-size);height:var(--e-form-steps-indicator-padding,30px);justify-content:center;margin-bottom:10px;overflow:hidden;width:var(--e-form-steps-indicator-padding,30px)}.e-form__indicators__indicator__icon img,.e-form__indicators__indicator__icon object,.e-form__indicators__indicator__icon svg{height:auto;width:var(--e-form-steps-indicator-icon-size)}.e-form__indicators__indicator__icon .e-font-icon-svg{height:1em}.e-form__indicators__indicator__number{align-items:center;border-style:solid;border-width:1px;display:flex;height:var(--e-form-steps-indicator-padding,30px);justify-content:center;margin-bottom:10px;width:var(--e-form-steps-indicator-padding,30px)}.e-form__indicators__indicator--shape-circle{border-radius:50%}.e-form__indicators__indicator--shape-square{border-radius:0}.e-form__indicators__indicator--shape-rounded{border-radius:5px}.e-form__indicators__indicator--shape-none{border:0}.e-form__indicators__indicator__label{text-align:center}.e-form__indicators__indicator__separator{background-color:#babfc5;height:var(--e-form-steps-divider-width);width:100%}.e-form__indicators--type-icon,.e-form__indicators--type-icon_text,.e-form__indicators--type-number,.e-form__indicators--type-number_text{align-items:flex-start}.e-form__indicators--type-icon .e-form__indicators__indicator__separator,.e-form__indicators--type-icon_text .e-form__indicators__indicator__separator,.e-form__indicators--type-number .e-form__indicators__indicator__separator,.e-form__indicators--type-number_text .e-form__indicators__indicator__separator{margin-top:calc(var(--e-form-steps-indicator-padding, 30px) / 2 - var(--e-form-steps-divider-width, 1px) / 2)}.elementor-field-type-hidden{display:none}.elementor-field-type-html{display:inline-block}.elementor-field-type-tel input{direction:inherit}.elementor-field-type-recaptcha_v3 .elementor-field-label{display:none}.elementor-field-type-recaptcha_v3 .grecaptcha-badge{z-index:1}.elementor-button .elementor-form-spinner{order:3}.elementor-form .elementor-button .elementor-button-content-wrapper{align-items:center}.elementor-form .elementor-button .elementor-button-text{white-space:normal}.elementor-form .elementor-button svg{height:auto}.elementor-form .elementor-button .e-font-icon-svg{height:1em}.elementor-form .elementor-button .elementor-button-content-wrapper{gap:5px}.elementor-form .elementor-button .elementor-button-icon,.elementor-form .elementor-button .elementor-button-text{flex-grow:unset;order:unset}.elementor-select-wrapper .select-caret-down-wrapper{font-size:11px;inset-inline-end:10px;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%)}.elementor-select-wrapper .select-caret-down-wrapper svg{aspect-ratio:unset;display:unset;width:1em;fill:currentColor;overflow:visible}.elementor-select-wrapper .select-caret-down-wrapper i{font-size:19px;line-height:2}.elementor-select-wrapper.remove-before:before{content:""!important}.elementor-message-svg:before{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMSIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDE0IDExIj48cGF0aCBmaWxsPSIjMDA4QTIwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ljc1IDguMTUgMS42IDUgLjU1IDYuMDVsNC4yIDQuMiA5LTlMMTIuNy4yeiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+");background-position:50%;background-repeat:no-repeat;content:"";height:1em;width:1em} \ No newline at end of file diff --git a/assets/css/widget-form.min.css b/assets/css/widget-form.min.css new file mode 100644 index 00000000..7e61d85a --- /dev/null +++ b/assets/css/widget-form.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-button.elementor-hidden,.elementor-hidden{display:none}.e-form__step{width:100%}.e-form__step:not(.elementor-hidden){display:flex;flex-wrap:wrap}.e-form__buttons{flex-wrap:wrap}.e-form__buttons,.e-form__buttons__wrapper{display:flex}.e-form__indicators{align-items:center;display:flex;flex-wrap:nowrap;font-size:13px;justify-content:space-between;margin-bottom:var(--e-form-steps-indicators-spacing)}.e-form__indicators__indicator{align-items:center;display:flex;flex-basis:0;flex-direction:column;justify-content:center;padding:0 var(--e-form-steps-divider-gap)}.e-form__indicators__indicator__progress{background-color:var(--e-form-steps-indicator-progress-background-color);border-radius:var(--e-form-steps-indicator-progress-border-radius);overflow:hidden;position:relative;width:100%}.e-form__indicators__indicator__progress__meter{background-color:var(--e-form-steps-indicator-progress-color);border-radius:var(--e-form-steps-indicator-progress-border-radius);color:var(--e-form-steps-indicator-progress-meter-color);height:var(--e-form-steps-indicator-progress-height);line-height:var(--e-form-steps-indicator-progress-height);padding-right:15px;text-align:right;transition:width .1s linear;width:var(--e-form-steps-indicator-progress-meter-width,0)}.e-form__indicators__indicator:first-child{padding-left:0}.e-form__indicators__indicator:last-child{padding-right:0}.e-form__indicators__indicator--state-inactive{color:var(--e-form-steps-indicator-inactive-primary-color,#c2cbd2)}.e-form__indicators__indicator--state-inactive [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-inactive-secondary-color,#fff)}.e-form__indicators__indicator--state-inactive object,.e-form__indicators__indicator--state-inactive svg{fill:var(--e-form-steps-indicator-inactive-primary-color,#c2cbd2)}.e-form__indicators__indicator--state-active{border-color:var(--e-form-steps-indicator-active-secondary-color,#fff);color:var(--e-form-steps-indicator-active-primary-color,#39b54a)}.e-form__indicators__indicator--state-active [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-active-secondary-color,#fff)}.e-form__indicators__indicator--state-active object,.e-form__indicators__indicator--state-active svg{fill:var(--e-form-steps-indicator-active-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed{color:var(--e-form-steps-indicator-completed-secondary-color,#fff)}.e-form__indicators__indicator--state-completed [class*=indicator--shape-]:not(.e-form__indicators__indicator--shape-none){background-color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed .e-form__indicators__indicator__label{color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed .e-form__indicators__indicator--shape-none{background-color:initial;color:var(--e-form-steps-indicator-completed-primary-color,#39b54a)}.e-form__indicators__indicator--state-completed object,.e-form__indicators__indicator--state-completed svg{fill:var(--e-form-steps-indicator-completed-secondary-color,#fff)}.e-form__indicators__indicator__icon{align-items:center;border-style:solid;border-width:1px;display:flex;font-size:var(--e-form-steps-indicator-icon-size);height:var(--e-form-steps-indicator-padding,30px);justify-content:center;margin-bottom:10px;overflow:hidden;width:var(--e-form-steps-indicator-padding,30px)}.e-form__indicators__indicator__icon img,.e-form__indicators__indicator__icon object,.e-form__indicators__indicator__icon svg{height:auto;width:var(--e-form-steps-indicator-icon-size)}.e-form__indicators__indicator__icon .e-font-icon-svg{height:1em}.e-form__indicators__indicator__number{align-items:center;border-style:solid;border-width:1px;display:flex;height:var(--e-form-steps-indicator-padding,30px);justify-content:center;margin-bottom:10px;width:var(--e-form-steps-indicator-padding,30px)}.e-form__indicators__indicator--shape-circle{border-radius:50%}.e-form__indicators__indicator--shape-square{border-radius:0}.e-form__indicators__indicator--shape-rounded{border-radius:5px}.e-form__indicators__indicator--shape-none{border:0}.e-form__indicators__indicator__label{text-align:center}.e-form__indicators__indicator__separator{background-color:#babfc5;height:var(--e-form-steps-divider-width);width:100%}.e-form__indicators--type-icon,.e-form__indicators--type-icon_text,.e-form__indicators--type-number,.e-form__indicators--type-number_text{align-items:flex-start}.e-form__indicators--type-icon .e-form__indicators__indicator__separator,.e-form__indicators--type-icon_text .e-form__indicators__indicator__separator,.e-form__indicators--type-number .e-form__indicators__indicator__separator,.e-form__indicators--type-number_text .e-form__indicators__indicator__separator{margin-top:calc(var(--e-form-steps-indicator-padding, 30px) / 2 - var(--e-form-steps-divider-width, 1px) / 2)}.elementor-field-type-hidden{display:none}.elementor-field-type-html{display:inline-block}.elementor-field-type-tel input{direction:inherit}.elementor-field-type-recaptcha_v3 .elementor-field-label{display:none}.elementor-field-type-recaptcha_v3 .grecaptcha-badge{z-index:1}.elementor-button .elementor-form-spinner{order:3}.elementor-form .elementor-button .elementor-button-content-wrapper{align-items:center}.elementor-form .elementor-button .elementor-button-text{white-space:normal}.elementor-form .elementor-button svg{height:auto}.elementor-form .elementor-button .e-font-icon-svg{height:1em}.elementor-form .elementor-button .elementor-button-content-wrapper{gap:5px}.elementor-form .elementor-button .elementor-button-icon,.elementor-form .elementor-button .elementor-button-text{flex-grow:unset;order:unset}.elementor-select-wrapper .select-caret-down-wrapper{font-size:11px;inset-inline-end:10px;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%)}.elementor-select-wrapper .select-caret-down-wrapper svg{aspect-ratio:unset;display:unset;width:1em;fill:currentColor;overflow:visible}.elementor-select-wrapper .select-caret-down-wrapper i{font-size:19px;line-height:2}.elementor-select-wrapper.remove-before:before{content:""!important}.elementor-message-svg:before{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMSIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDE0IDExIj48cGF0aCBmaWxsPSIjMDA4QTIwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ljc1IDguMTUgMS42IDUgLjU1IDYuMDVsNC4yIDQuMiA5LTlMMTIuNy4yeiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+");background-position:50%;background-repeat:no-repeat;content:"";height:1em;width:1em} \ No newline at end of file diff --git a/assets/css/widget-gallery-rtl.min.css b/assets/css/widget-gallery-rtl.min.css new file mode 100644 index 00000000..efde9dca --- /dev/null +++ b/assets/css/widget-gallery-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-gallery__container{min-height:1px}.elementor-gallery-item{border:solid var(--image-border-width) var(--image-border-color);border-radius:var(--image-border-radius);display:block;overflow:hidden;position:relative;text-decoration:none}.elementor-gallery-item__content,.elementor-gallery-item__overlay{height:100%;left:0;position:absolute;top:0;width:100%}.elementor-gallery-item__overlay{mix-blend-mode:var(--overlay-mix-blend-mode);transition-duration:var(--overlay-transition-duration);transition-property:mix-blend-mode,transform,opacity,background-color}.elementor-gallery-item__image.e-gallery-image{transition-duration:var(--image-transition-duration);transition-property:filter,transform}.elementor-gallery-item__content{align-items:center;display:flex;flex-direction:column;justify-content:var(--content-justify-content,center);padding:var(--content-padding);text-align:var(--content-text-align)}.elementor-gallery-item__content>div{transition-duration:var(--content-transition-duration)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(2){transition-delay:calc(var(--content-transition-delay) / 3)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(3){transition-delay:calc(var(--content-transition-delay) / 3 * 2)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(4){transition-delay:calc(var(--content-transition-delay) / 3 * 3)}.elementor-gallery-item__description{color:var(--description-text-color,#fff);width:100%}.elementor-gallery-item__title{color:var(--title-text-color,#fff);font-weight:700;width:100%}.elementor-gallery__titles-container{display:flex;flex-wrap:wrap;justify-content:var(--titles-container-justify-content,center);margin-bottom:20px}.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item:after,.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item:before{background-color:var(--galleries-pointer-bg-color-hover)}.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item.elementor-item-active:after,.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item.elementor-item-active:before{background-color:var(--galleries-pointer-bg-color-active)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item:before{border-color:var(--galleries-pointer-bg-color-hover);border-width:var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item:after{border-color:var(--galleries-pointer-bg-color-hover)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item.elementor-item-active:after,.elementor-gallery__titles-container.e--pointer-framed .elementor-item.elementor-item-active:before{border-color:var(--galleries-pointer-bg-color-active)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-draw .elementor-item:before{border-width:0 0 var(--galleries-pointer-border-width) var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-draw .elementor-item:after{border-width:var(--galleries-pointer-border-width) var(--galleries-pointer-border-width) 0 0}.elementor-gallery__titles-container.e--pointer-framed.e--animation-corners .elementor-item:before{border-width:var(--galleries-pointer-border-width) 0 0 var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-corners .elementor-item:after{border-width:0 var(--galleries-pointer-border-width) var(--galleries-pointer-border-width) 0}.elementor-gallery__titles-container .e--pointer-double-line .elementor-item:after,.elementor-gallery__titles-container .e--pointer-double-line .elementor-item:before,.elementor-gallery__titles-container .e--pointer-overline .elementor-item:before,.elementor-gallery__titles-container .e--pointer-underline .elementor-item:after{height:var(--galleries-pointer-border-width)}.elementor-gallery-title{--space-between:10px;color:#6d7882;cursor:pointer;font-weight:500;padding:7px 14px;position:relative;transition:all .3s}.elementor-gallery-title--active{color:#495157}.elementor-gallery-title:not(:last-child){margin-inline-end:var(--space-between)}.elementor-gallery-item__title+.elementor-gallery-item__description{margin-top:var(--description-margin-top)}.e-gallery-item.elementor-gallery-item{transition-property:all}.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-bottom,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-left,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-right,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-top,.e-gallery-item:focus .elementor-gallery__item-overlay-bg,.e-gallery-item:focus .elementor-gallery__item-overlay-content,.e-gallery-item:focus .elementor-gallery__item-overlay-content__description,.e-gallery-item:focus .elementor-gallery__item-overlay-content__title,.e-gallery-item:hover .elementor-gallery__item-overlay-bg,.e-gallery-item:hover .elementor-gallery__item-overlay-content,.e-gallery-item:hover .elementor-gallery__item-overlay-content__description,.e-gallery-item:hover .elementor-gallery__item-overlay-content__title{opacity:1}a.elementor-item.elementor-gallery-title{color:var(--galleries-title-color-normal)}a.elementor-item.elementor-gallery-title.elementor-item-active,a.elementor-item.elementor-gallery-title.highlighted,a.elementor-item.elementor-gallery-title:focus,a.elementor-item.elementor-gallery-title:hover{color:var(--galleries-title-color-hover)}a.elementor-item.elementor-gallery-title.elementor-item-active{color:var(--gallery-title-color-active)}.e-con-inner>.elementor-widget-gallery,.e-con>.elementor-widget-gallery{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-gallery.min.css b/assets/css/widget-gallery.min.css new file mode 100644 index 00000000..efde9dca --- /dev/null +++ b/assets/css/widget-gallery.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-gallery__container{min-height:1px}.elementor-gallery-item{border:solid var(--image-border-width) var(--image-border-color);border-radius:var(--image-border-radius);display:block;overflow:hidden;position:relative;text-decoration:none}.elementor-gallery-item__content,.elementor-gallery-item__overlay{height:100%;left:0;position:absolute;top:0;width:100%}.elementor-gallery-item__overlay{mix-blend-mode:var(--overlay-mix-blend-mode);transition-duration:var(--overlay-transition-duration);transition-property:mix-blend-mode,transform,opacity,background-color}.elementor-gallery-item__image.e-gallery-image{transition-duration:var(--image-transition-duration);transition-property:filter,transform}.elementor-gallery-item__content{align-items:center;display:flex;flex-direction:column;justify-content:var(--content-justify-content,center);padding:var(--content-padding);text-align:var(--content-text-align)}.elementor-gallery-item__content>div{transition-duration:var(--content-transition-duration)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(2){transition-delay:calc(var(--content-transition-delay) / 3)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(3){transition-delay:calc(var(--content-transition-delay) / 3 * 2)}.elementor-gallery-item__content.elementor-gallery--sequenced-animation>div:nth-child(4){transition-delay:calc(var(--content-transition-delay) / 3 * 3)}.elementor-gallery-item__description{color:var(--description-text-color,#fff);width:100%}.elementor-gallery-item__title{color:var(--title-text-color,#fff);font-weight:700;width:100%}.elementor-gallery__titles-container{display:flex;flex-wrap:wrap;justify-content:var(--titles-container-justify-content,center);margin-bottom:20px}.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item:after,.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item:before{background-color:var(--galleries-pointer-bg-color-hover)}.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item.elementor-item-active:after,.elementor-gallery__titles-container:not(.e--pointer-framed) .elementor-item.elementor-item-active:before{background-color:var(--galleries-pointer-bg-color-active)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item:before{border-color:var(--galleries-pointer-bg-color-hover);border-width:var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item:after{border-color:var(--galleries-pointer-bg-color-hover)}.elementor-gallery__titles-container.e--pointer-framed .elementor-item.elementor-item-active:after,.elementor-gallery__titles-container.e--pointer-framed .elementor-item.elementor-item-active:before{border-color:var(--galleries-pointer-bg-color-active)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-draw .elementor-item:before{border-width:0 0 var(--galleries-pointer-border-width) var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-draw .elementor-item:after{border-width:var(--galleries-pointer-border-width) var(--galleries-pointer-border-width) 0 0}.elementor-gallery__titles-container.e--pointer-framed.e--animation-corners .elementor-item:before{border-width:var(--galleries-pointer-border-width) 0 0 var(--galleries-pointer-border-width)}.elementor-gallery__titles-container.e--pointer-framed.e--animation-corners .elementor-item:after{border-width:0 var(--galleries-pointer-border-width) var(--galleries-pointer-border-width) 0}.elementor-gallery__titles-container .e--pointer-double-line .elementor-item:after,.elementor-gallery__titles-container .e--pointer-double-line .elementor-item:before,.elementor-gallery__titles-container .e--pointer-overline .elementor-item:before,.elementor-gallery__titles-container .e--pointer-underline .elementor-item:after{height:var(--galleries-pointer-border-width)}.elementor-gallery-title{--space-between:10px;color:#6d7882;cursor:pointer;font-weight:500;padding:7px 14px;position:relative;transition:all .3s}.elementor-gallery-title--active{color:#495157}.elementor-gallery-title:not(:last-child){margin-inline-end:var(--space-between)}.elementor-gallery-item__title+.elementor-gallery-item__description{margin-top:var(--description-margin-top)}.e-gallery-item.elementor-gallery-item{transition-property:all}.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-bottom,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-left,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-right,.e-gallery-item.elementor-animated-content .elementor-animated-item--enter-from-top,.e-gallery-item:focus .elementor-gallery__item-overlay-bg,.e-gallery-item:focus .elementor-gallery__item-overlay-content,.e-gallery-item:focus .elementor-gallery__item-overlay-content__description,.e-gallery-item:focus .elementor-gallery__item-overlay-content__title,.e-gallery-item:hover .elementor-gallery__item-overlay-bg,.e-gallery-item:hover .elementor-gallery__item-overlay-content,.e-gallery-item:hover .elementor-gallery__item-overlay-content__description,.e-gallery-item:hover .elementor-gallery__item-overlay-content__title{opacity:1}a.elementor-item.elementor-gallery-title{color:var(--galleries-title-color-normal)}a.elementor-item.elementor-gallery-title.elementor-item-active,a.elementor-item.elementor-gallery-title.highlighted,a.elementor-item.elementor-gallery-title:focus,a.elementor-item.elementor-gallery-title:hover{color:var(--galleries-title-color-hover)}a.elementor-item.elementor-gallery-title.elementor-item-active{color:var(--gallery-title-color-active)}.e-con-inner>.elementor-widget-gallery,.e-con>.elementor-widget-gallery{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-hotspot-rtl.min.css b/assets/css/widget-hotspot-rtl.min.css new file mode 100644 index 00000000..1bac16af --- /dev/null +++ b/assets/css/widget-hotspot-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@keyframes e-hotspot-soft-beat{0%{transform:scale(1)}to{transform:scale(1.1)}}@keyframes e-hotspot-expand{0%{opacity:1;transform:scale(.5)}to{opacity:0;transform:scale(1.5)}}.elementor-widget-hotspot{display:flex;justify-content:var(--background-align)}.elementor-widget-hotspot .elementor-widget-container,.elementor-widget-hotspot:not(:has(.elementor-widget-container)){height:var(--container-height);max-width:var(--container-max-width);position:relative;width:var(--container-width)}.elementor-widget-hotspot .elementor-widget-container>img,.elementor-widget-hotspot:not(:has(.elementor-widget-container))>img{display:block;height:var(--container-height);opacity:var(--opacity,1);width:var(--image-width,auto)}.elementor-widget-hotspot .elementor-widget-container{display:inline-block}.e-hotspot{align-items:center;display:flex;justify-content:center;position:absolute;z-index:1}.e-hotspot--position-left.e-hotspot--position-top{transform:translate(calc(-1 * var(--hotspot-translate-x)),calc(-1 * var(--hotspot-translate-y)))}.e-hotspot--position-left.e-hotspot--position-bottom{transform:translate(calc(-1 * var(--hotspot-translate-x)),var(--hotspot-translate-y))}.e-hotspot--position-right.e-hotspot--position-top{transform:translate(var(--hotspot-translate-x),calc(-1 * var(--hotspot-translate-y)))}.e-hotspot--position-right.e-hotspot--position-bottom{transform:translate(var(--hotspot-translate-x),var(--hotspot-translate-y))}.e-hotspot--active{z-index:2}.e-hotspot__inner-circle,.e-hotspot__outer-circle{border-radius:50%;box-sizing:content-box;content:"";display:inline-block}.e-hotspot__inner-circle{background-color:var(--hotspot-color);left:50%;padding:calc(var(--hotspot-size, 18px) / 2);position:absolute;top:50%;transform:translate(-50%,-50%)}.e-hotspot__outer-circle{background-color:var(--hotspot-color);padding:var(--hotspot-padding,4px)}.e-hotspot--icon .e-hotspot__button,.e-hotspot__outer-circle{height:var(--hotspot-size,18px);width:var(--hotspot-size,18px)}.e-hotspot--icon .e-hotspot__button{box-sizing:content-box;font-size:var(--hotspot-size,18px);line-height:0}.e-hotspot__icon,.e-hotspot__label{align-items:center;display:flex;justify-content:center}.e-hotspot__icon svg,.e-hotspot__label svg{height:var(--hotspot-size,18px);width:auto}.e-hotspot__button{color:var(--hotspot-color);cursor:pointer;display:grid;font-size:var(--hotspot-size,18px);grid-auto-flow:column;justify-content:center;min-height:var(--hotspot-button-height);min-width:var(--hotspot-button-width);position:relative}.e-hotspot__button:before{box-sizing:content-box;content:"";height:100%;left:-5px;padding:5px;position:absolute;top:-5px;width:100%;z-index:-2}.e-hotspot__button svg{fill:var(--hotspot-color)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot__button{background-color:var(--hotspot-box-color);border-radius:var(--hotspot-border-radius,3px);min-height:var(--hotspot-min-height);min-width:var(--hotspot-min-width);padding:var(--hotspot-padding,4px)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot__button:before{border-radius:var(--hotspot-border-radius,3px)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot--expand:before{background-color:var(--hotspot-box-color)}.e-hotspot--overlay{opacity:.7;transition:opacity .2s}.e-hotspot--active .e-hotspot--overlay,.e-hotspot--overlay:hover{opacity:1}.e-hotspot--soft-beat{animation:e-hotspot-soft-beat .7s infinite alternate;animation-timing-function:ease}.e-hotspot--expand .e-hotspot__outer-circle{animation:e-hotspot-expand 2s infinite}.e-hotspot:not(.e-hotspot--circle) .e-hotspot--expand:before{animation:e-hotspot-expand 2s infinite;content:"";height:100%;opacity:0;position:absolute;width:100%;z-index:-1}.e-hotspot--sequenced{animation:fadeIn .3s;animation-fill-mode:both;animation-iteration-count:1}.e-hotspot__direction-mask{overflow:hidden;pointer-events:none;position:absolute}.e-hotspot__tooltip{background-color:var(--tooltip-color);border-radius:var(--tooltip-border-radius);color:var(--tooltip-text-color,#fff);max-width:var(--tooltip-max-width);min-width:var(--tooltip-min-width);padding:var(--tooltip-padding,8px);pointer-events:none;position:absolute;text-align:var(--tooltip-align);transform-origin:center center;transition-duration:var(--tooltip-transition-duration,.5s);transition-property:transform,opacity;white-space:var(--white-space,nowrap)}.e-hotspot__tooltip p:last-of-type{margin-bottom:0}.e-hotspot__direction-mask .e-hotspot__tooltip{box-shadow:none!important;position:static}.e-hotspot--active .e-hotspot__tooltip{pointer-events:visible}.e-hotspot--fade-in-out{opacity:0}.e-hotspot--active .e-hotspot--fade-in-out{opacity:1}.e-hotspot--fade-grow{opacity:0;transform:scale(0)}.e-hotspot--active .e-hotspot--fade-grow{opacity:1;transform:scale(1)}.e-hotspot--override-tooltip-animation-from-top,.e-hotspot--tooltip-animation-from-top{transform:translateY(calc(-100% - 1px))}.e-hotspot--override-tooltip-animation-from-left,.e-hotspot--tooltip-animation-from-left{transform:translate(calc(-100% - 1px))}.e-hotspot--override-tooltip-animation-from-right,.e-hotspot--tooltip-animation-from-right{transform:translate(calc(100% + 1px))}.e-hotspot--override-tooltip-animation-from-bottom,.e-hotspot--tooltip-animation-from-bottom{transform:translateY(calc(100% + 1px))}.e-hotspot--fade-direction{opacity:0}.e-hotspot--active .e-hotspot--fade-direction,.e-hotspot--active .e-hotspot--slide-direction{opacity:1;transform:translate(0) scale(1)}.e-hotspot--show-tooltip{opacity:1;pointer-events:visible;transform:translate(0);transition:none} \ No newline at end of file diff --git a/assets/css/widget-hotspot.min.css b/assets/css/widget-hotspot.min.css new file mode 100644 index 00000000..1bac16af --- /dev/null +++ b/assets/css/widget-hotspot.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@keyframes e-hotspot-soft-beat{0%{transform:scale(1)}to{transform:scale(1.1)}}@keyframes e-hotspot-expand{0%{opacity:1;transform:scale(.5)}to{opacity:0;transform:scale(1.5)}}.elementor-widget-hotspot{display:flex;justify-content:var(--background-align)}.elementor-widget-hotspot .elementor-widget-container,.elementor-widget-hotspot:not(:has(.elementor-widget-container)){height:var(--container-height);max-width:var(--container-max-width);position:relative;width:var(--container-width)}.elementor-widget-hotspot .elementor-widget-container>img,.elementor-widget-hotspot:not(:has(.elementor-widget-container))>img{display:block;height:var(--container-height);opacity:var(--opacity,1);width:var(--image-width,auto)}.elementor-widget-hotspot .elementor-widget-container{display:inline-block}.e-hotspot{align-items:center;display:flex;justify-content:center;position:absolute;z-index:1}.e-hotspot--position-left.e-hotspot--position-top{transform:translate(calc(-1 * var(--hotspot-translate-x)),calc(-1 * var(--hotspot-translate-y)))}.e-hotspot--position-left.e-hotspot--position-bottom{transform:translate(calc(-1 * var(--hotspot-translate-x)),var(--hotspot-translate-y))}.e-hotspot--position-right.e-hotspot--position-top{transform:translate(var(--hotspot-translate-x),calc(-1 * var(--hotspot-translate-y)))}.e-hotspot--position-right.e-hotspot--position-bottom{transform:translate(var(--hotspot-translate-x),var(--hotspot-translate-y))}.e-hotspot--active{z-index:2}.e-hotspot__inner-circle,.e-hotspot__outer-circle{border-radius:50%;box-sizing:content-box;content:"";display:inline-block}.e-hotspot__inner-circle{background-color:var(--hotspot-color);left:50%;padding:calc(var(--hotspot-size, 18px) / 2);position:absolute;top:50%;transform:translate(-50%,-50%)}.e-hotspot__outer-circle{background-color:var(--hotspot-color);padding:var(--hotspot-padding,4px)}.e-hotspot--icon .e-hotspot__button,.e-hotspot__outer-circle{height:var(--hotspot-size,18px);width:var(--hotspot-size,18px)}.e-hotspot--icon .e-hotspot__button{box-sizing:content-box;font-size:var(--hotspot-size,18px);line-height:0}.e-hotspot__icon,.e-hotspot__label{align-items:center;display:flex;justify-content:center}.e-hotspot__icon svg,.e-hotspot__label svg{height:var(--hotspot-size,18px);width:auto}.e-hotspot__button{color:var(--hotspot-color);cursor:pointer;display:grid;font-size:var(--hotspot-size,18px);grid-auto-flow:column;justify-content:center;min-height:var(--hotspot-button-height);min-width:var(--hotspot-button-width);position:relative}.e-hotspot__button:before{box-sizing:content-box;content:"";height:100%;left:-5px;padding:5px;position:absolute;top:-5px;width:100%;z-index:-2}.e-hotspot__button svg{fill:var(--hotspot-color)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot__button{background-color:var(--hotspot-box-color);border-radius:var(--hotspot-border-radius,3px);min-height:var(--hotspot-min-height);min-width:var(--hotspot-min-width);padding:var(--hotspot-padding,4px)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot__button:before{border-radius:var(--hotspot-border-radius,3px)}.e-hotspot:not(.e-hotspot--circle) .e-hotspot--expand:before{background-color:var(--hotspot-box-color)}.e-hotspot--overlay{opacity:.7;transition:opacity .2s}.e-hotspot--active .e-hotspot--overlay,.e-hotspot--overlay:hover{opacity:1}.e-hotspot--soft-beat{animation:e-hotspot-soft-beat .7s infinite alternate;animation-timing-function:ease}.e-hotspot--expand .e-hotspot__outer-circle{animation:e-hotspot-expand 2s infinite}.e-hotspot:not(.e-hotspot--circle) .e-hotspot--expand:before{animation:e-hotspot-expand 2s infinite;content:"";height:100%;opacity:0;position:absolute;width:100%;z-index:-1}.e-hotspot--sequenced{animation:fadeIn .3s;animation-fill-mode:both;animation-iteration-count:1}.e-hotspot__direction-mask{overflow:hidden;pointer-events:none;position:absolute}.e-hotspot__tooltip{background-color:var(--tooltip-color);border-radius:var(--tooltip-border-radius);color:var(--tooltip-text-color,#fff);max-width:var(--tooltip-max-width);min-width:var(--tooltip-min-width);padding:var(--tooltip-padding,8px);pointer-events:none;position:absolute;text-align:var(--tooltip-align);transform-origin:center center;transition-duration:var(--tooltip-transition-duration,.5s);transition-property:transform,opacity;white-space:var(--white-space,nowrap)}.e-hotspot__tooltip p:last-of-type{margin-bottom:0}.e-hotspot__direction-mask .e-hotspot__tooltip{box-shadow:none!important;position:static}.e-hotspot--active .e-hotspot__tooltip{pointer-events:visible}.e-hotspot--fade-in-out{opacity:0}.e-hotspot--active .e-hotspot--fade-in-out{opacity:1}.e-hotspot--fade-grow{opacity:0;transform:scale(0)}.e-hotspot--active .e-hotspot--fade-grow{opacity:1;transform:scale(1)}.e-hotspot--override-tooltip-animation-from-top,.e-hotspot--tooltip-animation-from-top{transform:translateY(calc(-100% - 1px))}.e-hotspot--override-tooltip-animation-from-left,.e-hotspot--tooltip-animation-from-left{transform:translate(calc(-100% - 1px))}.e-hotspot--override-tooltip-animation-from-right,.e-hotspot--tooltip-animation-from-right{transform:translate(calc(100% + 1px))}.e-hotspot--override-tooltip-animation-from-bottom,.e-hotspot--tooltip-animation-from-bottom{transform:translateY(calc(100% + 1px))}.e-hotspot--fade-direction{opacity:0}.e-hotspot--active .e-hotspot--fade-direction,.e-hotspot--active .e-hotspot--slide-direction{opacity:1;transform:translate(0) scale(1)}.e-hotspot--show-tooltip{opacity:1;pointer-events:visible;transform:translate(0);transition:none} \ No newline at end of file diff --git a/assets/css/widget-login-rtl.min.css b/assets/css/widget-login-rtl.min.css new file mode 100644 index 00000000..0c1d0994 --- /dev/null +++ b/assets/css/widget-login-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-login .elementor-lost-password,.elementor-login .elementor-remember-me{font-size:.85em} \ No newline at end of file diff --git a/assets/css/widget-login.min.css b/assets/css/widget-login.min.css new file mode 100644 index 00000000..0c1d0994 --- /dev/null +++ b/assets/css/widget-login.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-login .elementor-lost-password,.elementor-login .elementor-remember-me{font-size:.85em} \ No newline at end of file diff --git a/assets/css/widget-loop-canvas-rtl.min.css b/assets/css/widget-loop-canvas-rtl.min.css new file mode 100644 index 00000000..4c0c3927 --- /dev/null +++ b/assets/css/widget-loop-canvas-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-loop-template-canvas{align-items:center;display:flex;justify-content:center;min-height:100vh}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item{max-width:var(--preview-width,410px);width:var(--preview-width,410px)}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item #elementor-add-new-section{width:var(--preview-width,410px)} \ No newline at end of file diff --git a/assets/css/widget-loop-canvas.min.css b/assets/css/widget-loop-canvas.min.css new file mode 100644 index 00000000..4c0c3927 --- /dev/null +++ b/assets/css/widget-loop-canvas.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-loop-template-canvas{align-items:center;display:flex;justify-content:center;min-height:100vh}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item{max-width:var(--preview-width,410px);width:var(--preview-width,410px)}.e-loop-template-canvas [data-elementor-type=loop-item].e-loop-item #elementor-add-new-section{width:var(--preview-width,410px)} \ No newline at end of file diff --git a/assets/css/widget-loop-carousel-rtl.min.css b/assets/css/widget-loop-carousel-rtl.min.css new file mode 100644 index 00000000..70c83672 --- /dev/null +++ b/assets/css/widget-loop-carousel-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-loop-carousel{--swiper-pagination-size:0;--swiper-pagination-spacing:10px;--swiper-slides-gap:10px;--swiper-offset-size:0;height:-moz-fit-content;height:fit-content;--swiper-padding-bottom:calc(var(--swiper-pagination-size) + var(--swiper-pagination-spacing));--arrow-prev-top-align:50%;--arrow-prev-top-position:0px;--arrow-prev-caption-spacing:15px;--arrow-next-top-align:50%;--arrow-next-top-position:0px;--arrow-next-caption-spacing:15px;--arrow-prev-left-align:0px;--arrow-prev-left-position:0px;--arrow-next-right-align:0px;--arrow-next-right-position:0px;--arrow-next-translate-x:0px;--arrow-next-translate-y:0px;--arrow-prev-translate-x:0px;--arrow-prev-translate-y:0px;--dots-vertical-position:100%;--dots-vertical-offset:0px;--dots-horizontal-position:50%;--dots-horizontal-offset:0px;--dots-horizontal-transform:-50%;--dots-vertical-transform:-100%;--fraction-vertical-position:100%;--fraction-vertical-offset:0px;--fraction-horizontal-position:50%;--fraction-horizontal-offset:0px;--fraction-horizontal-transform:-50%;--fraction-vertical-transform:-100%}.elementor-widget-loop-carousel.elementor-pagination-type-bullets{--swiper-pagination-size:6px}.elementor-widget-loop-carousel.elementor-pagination-type-fraction{--swiper-pagination-size:16px}.elementor-widget-loop-carousel.elementor-pagination-type-progressbar{--swiper-pagination-size:4px}.elementor-widget-loop-carousel .elementor-loop-container>.swiper-wrapper>.swiper-slide-active.elementor-edit-area-active{overflow:initial}.elementor-widget-loop-carousel .elementor-loop-container.offset-left{padding-inline-start:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .elementor-loop-container.offset-right{padding-inline-end:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .elementor-loop-container.offset-both{padding-inline-end:var(--swiper-offset-size,0);padding-inline-start:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .swiper-container:not(.swiper-container-initialized)>.swiper-wrapper,.elementor-widget-loop-carousel .swiper:not(.swiper-initialized)>.swiper-wrapper{gap:var(--swiper-slides-gap);overflow:hidden}.elementor-widget-loop-carousel .swiper-container:not(.swiper-container-initialized)>.swiper-wrapper>.swiper--slide,.elementor-widget-loop-carousel .swiper:not(.swiper-initialized)>.swiper-wrapper>.swiper--slide{--number-of-gaps:max(calc(var(--swiper-slides-to-display) - 1),0);--gaps-width-total:calc(var(--number-of-gaps) * var(--swiper-slides-gap));max-width:calc((100% - var(--gaps-width-total)) / var(--swiper-slides-to-display, 1))}.elementor-widget-loop-carousel .e-loop-first-edit{margin-block-start:23px;min-width:33%}.elementor-widget-loop-carousel .swiper-wrapper .swiper-slide a.e-con{display:var(--display)}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev{border-style:var(--arrow-normal-border-type);color:var(--arrow-normal-color,hsla(0,0%,93%,.9));font-size:var(--arrow-size,25px);transition-duration:.25s;z-index:2}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next svg,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev svg{fill:var(--arrow-normal-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next:hover,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover{border-style:var(--arrow-hover-border-type);color:var(--arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next:hover svg,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover svg{fill:var(--arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-next{right:calc(var(--arrow-next-right-align) + var(--arrow-next-right-position));top:calc(var(--arrow-next-top-align) + var(--arrow-next-top-position) - var(--arrow-next-caption-spacing));transform:translate(var(--arrow-next-translate-x),var(--arrow-next-translate-y))}.elementor-widget-loop-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-prev{left:calc(var(--arrow-prev-left-align) + var(--arrow-prev-left-position));top:calc(var(--arrow-prev-top-align) + var(--arrow-prev-top-position) - var(--arrow-prev-caption-spacing));transform:translate(var(--arrow-prev-translate-x),var(--arrow-prev-translate-y))}.elementor-widget-loop-carousel .swiper-container-horizontal~.swiper-pagination-progressbar,.elementor-widget-loop-carousel .swiper-horizontal~.swiper-pagination-progressbar{height:var(--swiper-pagination-size)}.elementor-widget-loop-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--progressbar-normal-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill:hover{background:var(--progressbar-hover-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-fraction{color:var(--fraction-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-bullet{background:var(--dots-normal-color,#000);height:var(--swiper-pagination-size);width:var(--swiper-pagination-size)}.elementor-widget-loop-carousel .swiper-pagination-bullet:hover{background:var(--dots-hover-color,#000);opacity:1}.elementor-widget-loop-carousel.elementor-in-place-template-editable .elementor-loop-container{overflow:visible;overflow-x:clip}.elementor-widget-loop-carousel .swiper-horizontal>.swiper-pagination-bullets,.elementor-widget-loop-carousel .swiper-pagination,.elementor-widget-loop-carousel .swiper-pagination-bullets.swiper-pagination-horizontal,.elementor-widget-loop-carousel .swiper-pagination-custom,.elementor-widget-loop-carousel .swiper-pagination-fraction{font-size:var(--swiper-pagination-size);line-height:var(--swiper-pagination-size)}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper,.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container{padding-bottom:var(--swiper-padding-bottom)}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container .elementor-background-slideshow{padding-bottom:0}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container)) .swiper-pagination-bullet,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container .swiper-pagination-bullet{vertical-align:top}.elementor-widget-loop-carousel .swiper-pagination-bullets{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--dots-horizontal-position) + var(--dots-horizontal-offset));top:calc(var(--dots-vertical-position) + var(--dots-vertical-offset));transform:translate(calc(var(--dots-horizontal-transform) * var(--direction-multiplier, 1)),var(--dots-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.elementor-widget-loop-carousel .swiper-pagination-fraction{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--fraction-horizontal-position) + var(--fraction-horizontal-offset));top:calc(var(--fraction-vertical-position) + var(--fraction-vertical-offset));transform:translate(calc(var(--fraction-horizontal-transform) * var(--direction-multiplier, 1)),var(--fraction-vertical-transform));width:-moz-max-content;width:max-content;z-index:3} \ No newline at end of file diff --git a/assets/css/widget-loop-carousel.min.css b/assets/css/widget-loop-carousel.min.css new file mode 100644 index 00000000..70c83672 --- /dev/null +++ b/assets/css/widget-loop-carousel.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-loop-carousel{--swiper-pagination-size:0;--swiper-pagination-spacing:10px;--swiper-slides-gap:10px;--swiper-offset-size:0;height:-moz-fit-content;height:fit-content;--swiper-padding-bottom:calc(var(--swiper-pagination-size) + var(--swiper-pagination-spacing));--arrow-prev-top-align:50%;--arrow-prev-top-position:0px;--arrow-prev-caption-spacing:15px;--arrow-next-top-align:50%;--arrow-next-top-position:0px;--arrow-next-caption-spacing:15px;--arrow-prev-left-align:0px;--arrow-prev-left-position:0px;--arrow-next-right-align:0px;--arrow-next-right-position:0px;--arrow-next-translate-x:0px;--arrow-next-translate-y:0px;--arrow-prev-translate-x:0px;--arrow-prev-translate-y:0px;--dots-vertical-position:100%;--dots-vertical-offset:0px;--dots-horizontal-position:50%;--dots-horizontal-offset:0px;--dots-horizontal-transform:-50%;--dots-vertical-transform:-100%;--fraction-vertical-position:100%;--fraction-vertical-offset:0px;--fraction-horizontal-position:50%;--fraction-horizontal-offset:0px;--fraction-horizontal-transform:-50%;--fraction-vertical-transform:-100%}.elementor-widget-loop-carousel.elementor-pagination-type-bullets{--swiper-pagination-size:6px}.elementor-widget-loop-carousel.elementor-pagination-type-fraction{--swiper-pagination-size:16px}.elementor-widget-loop-carousel.elementor-pagination-type-progressbar{--swiper-pagination-size:4px}.elementor-widget-loop-carousel .elementor-loop-container>.swiper-wrapper>.swiper-slide-active.elementor-edit-area-active{overflow:initial}.elementor-widget-loop-carousel .elementor-loop-container.offset-left{padding-inline-start:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .elementor-loop-container.offset-right{padding-inline-end:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .elementor-loop-container.offset-both{padding-inline-end:var(--swiper-offset-size,0);padding-inline-start:var(--swiper-offset-size,0)}.elementor-widget-loop-carousel .swiper-container:not(.swiper-container-initialized)>.swiper-wrapper,.elementor-widget-loop-carousel .swiper:not(.swiper-initialized)>.swiper-wrapper{gap:var(--swiper-slides-gap);overflow:hidden}.elementor-widget-loop-carousel .swiper-container:not(.swiper-container-initialized)>.swiper-wrapper>.swiper--slide,.elementor-widget-loop-carousel .swiper:not(.swiper-initialized)>.swiper-wrapper>.swiper--slide{--number-of-gaps:max(calc(var(--swiper-slides-to-display) - 1),0);--gaps-width-total:calc(var(--number-of-gaps) * var(--swiper-slides-gap));max-width:calc((100% - var(--gaps-width-total)) / var(--swiper-slides-to-display, 1))}.elementor-widget-loop-carousel .e-loop-first-edit{margin-block-start:23px;min-width:33%}.elementor-widget-loop-carousel .swiper-wrapper .swiper-slide a.e-con{display:var(--display)}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev{border-style:var(--arrow-normal-border-type);color:var(--arrow-normal-color,hsla(0,0%,93%,.9));font-size:var(--arrow-size,25px);transition-duration:.25s;z-index:2}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next svg,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev svg{fill:var(--arrow-normal-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next:hover,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover{border-style:var(--arrow-hover-border-type);color:var(--arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-next:hover svg,.elementor-widget-loop-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover svg{fill:var(--arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-loop-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-next{right:calc(var(--arrow-next-right-align) + var(--arrow-next-right-position));top:calc(var(--arrow-next-top-align) + var(--arrow-next-top-position) - var(--arrow-next-caption-spacing));transform:translate(var(--arrow-next-translate-x),var(--arrow-next-translate-y))}.elementor-widget-loop-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-prev{left:calc(var(--arrow-prev-left-align) + var(--arrow-prev-left-position));top:calc(var(--arrow-prev-top-align) + var(--arrow-prev-top-position) - var(--arrow-prev-caption-spacing));transform:translate(var(--arrow-prev-translate-x),var(--arrow-prev-translate-y))}.elementor-widget-loop-carousel .swiper-container-horizontal~.swiper-pagination-progressbar,.elementor-widget-loop-carousel .swiper-horizontal~.swiper-pagination-progressbar{height:var(--swiper-pagination-size)}.elementor-widget-loop-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--progressbar-normal-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill:hover{background:var(--progressbar-hover-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-fraction{color:var(--fraction-color,#000)}.elementor-widget-loop-carousel .swiper-pagination-bullet{background:var(--dots-normal-color,#000);height:var(--swiper-pagination-size);width:var(--swiper-pagination-size)}.elementor-widget-loop-carousel .swiper-pagination-bullet:hover{background:var(--dots-hover-color,#000);opacity:1}.elementor-widget-loop-carousel.elementor-in-place-template-editable .elementor-loop-container{overflow:visible;overflow-x:clip}.elementor-widget-loop-carousel .swiper-horizontal>.swiper-pagination-bullets,.elementor-widget-loop-carousel .swiper-pagination,.elementor-widget-loop-carousel .swiper-pagination-bullets.swiper-pagination-horizontal,.elementor-widget-loop-carousel .swiper-pagination-custom,.elementor-widget-loop-carousel .swiper-pagination-fraction{font-size:var(--swiper-pagination-size);line-height:var(--swiper-pagination-size)}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper,.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container{padding-bottom:var(--swiper-padding-bottom)}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper .elementor-background-slideshow,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container .elementor-background-slideshow{padding-bottom:0}.elementor-widget-loop-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container)) .swiper-pagination-bullet,.elementor-widget-loop-carousel.elementor-pagination-position-outside>.elementor-widget-container .swiper-pagination-bullet{vertical-align:top}.elementor-widget-loop-carousel .swiper-pagination-bullets{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--dots-horizontal-position) + var(--dots-horizontal-offset));top:calc(var(--dots-vertical-position) + var(--dots-vertical-offset));transform:translate(calc(var(--dots-horizontal-transform) * var(--direction-multiplier, 1)),var(--dots-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.elementor-widget-loop-carousel .swiper-pagination-fraction{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--fraction-horizontal-position) + var(--fraction-horizontal-offset));top:calc(var(--fraction-vertical-position) + var(--fraction-vertical-offset));transform:translate(calc(var(--fraction-horizontal-transform) * var(--direction-multiplier, 1)),var(--fraction-vertical-transform));width:-moz-max-content;width:max-content;z-index:3} \ No newline at end of file diff --git a/assets/css/widget-loop-common-rtl.min.css b/assets/css/widget-loop-common-rtl.min.css new file mode 100644 index 00000000..f773843d --- /dev/null +++ b/assets/css/widget-loop-common-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-loop-item *{word-break:break-word}[class*=elementor-widget-loop] .elementor-page-title,[class*=elementor-widget-loop] .product_title.entry-title{display:initial} \ No newline at end of file diff --git a/assets/css/widget-loop-common.min.css b/assets/css/widget-loop-common.min.css new file mode 100644 index 00000000..f773843d --- /dev/null +++ b/assets/css/widget-loop-common.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-loop-item *{word-break:break-word}[class*=elementor-widget-loop] .elementor-page-title,[class*=elementor-widget-loop] .product_title.entry-title{display:initial} \ No newline at end of file diff --git a/assets/css/widget-loop-filter-rtl.min.css b/assets/css/widget-loop-filter-rtl.min.css new file mode 100644 index 00000000..33d1e702 --- /dev/null +++ b/assets/css/widget-loop-filter-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-taxonomy-filter{--e-filter-display:flex;--e-filter-direction:row;--e-filter-justify-content:center;--e-filter-wrap:wrap;--e-filter-align-items:center;--e-filter-item-width:initial;--e-filter-item-max-width:calc(100% - calc(var( --e-filter-item-padding )*3));--e-filter-item-justify-content:center;--e-filter-item-flex-grow:0;--e-filter-item-align-items:center;--e-filter-item-border-radius:initial;--e-filter-space-between:20px;--e-filter-normal-text-color:#69727d;--e-filter-active-text-color:#0c0d0e;--e-filter-hover-text-color:#0c0d0e;--e-filter-overflow-x:initial;--e-filter-white-space:nowrap;--e-filter-item-align-text:center;--e-filter-item-padding:8px;--e-filter-item-box-sizing:initial}.elementor-widget-taxonomy-filter .e-filter{align-items:var(--e-filter-align-items);display:var(--e-filter-display);flex-direction:var(--e-filter-direction);flex-shrink:0;flex-wrap:var(--e-filter-wrap);gap:var(--e-filter-space-between);justify-content:var(--e-filter-justify-content);overflow-x:var(--e-filter-overflow-x);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-taxonomy-filter .e-filter::-webkit-scrollbar{display:none}.elementor-widget-taxonomy-filter .e-filter.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-taxonomy-filter .e-filter.e-scroll-active{position:relative}.elementor-widget-taxonomy-filter .e-filter.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-taxonomy-filter .e-filter-item{align-items:var(--e-filter-item-align-items);background-color:initial;border:1px #69727d;border-radius:var(--e-filter-item-border-radius);box-sizing:var(--e-filter-item-box-sizing);color:var(--e-filter-normal-text-color);display:var(--e-filter-display);flex-basis:content;flex-grow:var(--e-filter-item-flex-grow);flex-shrink:0;justify-content:var(--e-filter-item-justify-content);line-height:normal;max-width:var(--e-filter-item-max-width);overflow:hidden;overflow-wrap:break-word;padding:var(--e-filter-item-padding);text-align:var(--e-filter-item-align-text);white-space:var(--e-filter-white-space);width:var(--e-filter-item-width)}.elementor-widget-taxonomy-filter .e-filter-item[aria-pressed=true]{border-color:#0c0d0e;color:var(--e-filter-active-text-color)}.elementor-widget-taxonomy-filter .e-filter-item:hover:not([aria-pressed=true]){border-color:#0c0d0e;color:var(--e-filter-hover-text-color)}.elementor-widget-taxonomy-filter .e-filter-item:hover,.elementor-widget-taxonomy-filter .e-filter-item[aria-pressed=true]{background-color:initial}.elementor-widget-taxonomy-filter .e-filter-item[data-filter=__all]{order:-1}.elementor-widget-taxonomy-filter .e-filter-item:focus:not(:focus-visible){outline:none}.elementor-widget-taxonomy-filter .e-filter-empty{background-color:hsla(214,9%,85%,.8);color:#0c0d0e;font-size:1rem;padding:1rem 0;text-align:center}.elementor-widget-loop-grid .e-loop-item.e-inactive{display:none} \ No newline at end of file diff --git a/assets/css/widget-loop-filter.min.css b/assets/css/widget-loop-filter.min.css new file mode 100644 index 00000000..33d1e702 --- /dev/null +++ b/assets/css/widget-loop-filter.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-taxonomy-filter{--e-filter-display:flex;--e-filter-direction:row;--e-filter-justify-content:center;--e-filter-wrap:wrap;--e-filter-align-items:center;--e-filter-item-width:initial;--e-filter-item-max-width:calc(100% - calc(var( --e-filter-item-padding )*3));--e-filter-item-justify-content:center;--e-filter-item-flex-grow:0;--e-filter-item-align-items:center;--e-filter-item-border-radius:initial;--e-filter-space-between:20px;--e-filter-normal-text-color:#69727d;--e-filter-active-text-color:#0c0d0e;--e-filter-hover-text-color:#0c0d0e;--e-filter-overflow-x:initial;--e-filter-white-space:nowrap;--e-filter-item-align-text:center;--e-filter-item-padding:8px;--e-filter-item-box-sizing:initial}.elementor-widget-taxonomy-filter .e-filter{align-items:var(--e-filter-align-items);display:var(--e-filter-display);flex-direction:var(--e-filter-direction);flex-shrink:0;flex-wrap:var(--e-filter-wrap);gap:var(--e-filter-space-between);justify-content:var(--e-filter-justify-content);overflow-x:var(--e-filter-overflow-x);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-taxonomy-filter .e-filter::-webkit-scrollbar{display:none}.elementor-widget-taxonomy-filter .e-filter.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-taxonomy-filter .e-filter.e-scroll-active{position:relative}.elementor-widget-taxonomy-filter .e-filter.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-taxonomy-filter .e-filter-item{align-items:var(--e-filter-item-align-items);background-color:initial;border:1px #69727d;border-radius:var(--e-filter-item-border-radius);box-sizing:var(--e-filter-item-box-sizing);color:var(--e-filter-normal-text-color);display:var(--e-filter-display);flex-basis:content;flex-grow:var(--e-filter-item-flex-grow);flex-shrink:0;justify-content:var(--e-filter-item-justify-content);line-height:normal;max-width:var(--e-filter-item-max-width);overflow:hidden;overflow-wrap:break-word;padding:var(--e-filter-item-padding);text-align:var(--e-filter-item-align-text);white-space:var(--e-filter-white-space);width:var(--e-filter-item-width)}.elementor-widget-taxonomy-filter .e-filter-item[aria-pressed=true]{border-color:#0c0d0e;color:var(--e-filter-active-text-color)}.elementor-widget-taxonomy-filter .e-filter-item:hover:not([aria-pressed=true]){border-color:#0c0d0e;color:var(--e-filter-hover-text-color)}.elementor-widget-taxonomy-filter .e-filter-item:hover,.elementor-widget-taxonomy-filter .e-filter-item[aria-pressed=true]{background-color:initial}.elementor-widget-taxonomy-filter .e-filter-item[data-filter=__all]{order:-1}.elementor-widget-taxonomy-filter .e-filter-item:focus:not(:focus-visible){outline:none}.elementor-widget-taxonomy-filter .e-filter-empty{background-color:hsla(214,9%,85%,.8);color:#0c0d0e;font-size:1rem;padding:1rem 0;text-align:center}.elementor-widget-loop-grid .e-loop-item.e-inactive{display:none} \ No newline at end of file diff --git a/assets/css/widget-loop-grid-rtl.min.css b/assets/css/widget-loop-grid-rtl.min.css new file mode 100644 index 00000000..60d2afad --- /dev/null +++ b/assets/css/widget-loop-grid-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.elementor-widget-loop-grid{scroll-margin-top:var(--auto-scroll-offset,initial)}.elementor-widget-loop-grid-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}@media (min-width:-1){.elementor-widget-loop-grid-widescreen-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:-1){.elementor-widget-loop-grid-laptop-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:1024px){.elementor-widget-loop-grid-tablet-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:-1){.elementor-widget-loop-grid-mobile_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:767px){.elementor-widget-loop-grid-mobile-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}.elementor-widget-loop-grid .elementor-grid{grid-column-gap:var(--grid-column-gap,30px);grid-row-gap:var(--grid-row-gap,30px)}.elementor-widget-loop-grid.e-loading-overlay{animation:loadingOpacityAnimation 1s infinite alternate}.elementor-widget-loop-grid .e-loop__load-more{text-align:var(--load-more-button-align)}.elementor-widget-loop-grid .e-loop__load-more .elementor-button{width:var(--load-more-button-width)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-loop-grid.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-loop-grid.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative}.elementor-widget-loop-grid .e-loop-nothing-found-message{color:var(--e-loop-nothing-found-message-color,#1f2124);padding-block-end:var(--e-loop-nothing-found-message-space-from-bottom,30px);padding-block-start:var(--e-loop-nothing-found-message-space-from-top,30px);text-align:var(--e-loop-nothing-found-message-align,center)}.elementor-loop-container.elementor-posts-masonry{align-items:flex-start}.elementor-loop-container:not(.elementor-posts-masonry){align-items:stretch}@keyframes loadingOpacityAnimation{0%,to{opacity:1}50%{opacity:.6}} \ No newline at end of file diff --git a/assets/css/widget-loop-grid.min.css b/assets/css/widget-loop-grid.min.css new file mode 100644 index 00000000..60d2afad --- /dev/null +++ b/assets/css/widget-loop-grid.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.elementor-widget-loop-grid{scroll-margin-top:var(--auto-scroll-offset,initial)}.elementor-widget-loop-grid-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}@media (min-width:-1){.elementor-widget-loop-grid-widescreen-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-widescreen-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:-1){.elementor-widget-loop-grid-laptop-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-laptop-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:1024px){.elementor-widget-loop-grid-tablet-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-tablet-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:-1){.elementor-widget-loop-grid-mobile_extra-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile_extra-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}@media (max-width:767px){.elementor-widget-loop-grid-mobile-1 .elementor-grid{grid-template-columns:repeat(1,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-2 .elementor-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-3 .elementor-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-4 .elementor-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-5 .elementor-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-6 .elementor-grid{grid-template-columns:repeat(6,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-7 .elementor-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-8 .elementor-grid{grid-template-columns:repeat(8,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-9 .elementor-grid{grid-template-columns:repeat(9,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-10 .elementor-grid{grid-template-columns:repeat(10,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-11 .elementor-grid{grid-template-columns:repeat(11,minmax(0,1fr))}.elementor-widget-loop-grid-mobile-12 .elementor-grid{grid-template-columns:repeat(12,minmax(0,1fr))}}.elementor-widget-loop-grid .elementor-grid{grid-column-gap:var(--grid-column-gap,30px);grid-row-gap:var(--grid-row-gap,30px)}.elementor-widget-loop-grid.e-loading-overlay{animation:loadingOpacityAnimation 1s infinite alternate}.elementor-widget-loop-grid .e-loop__load-more{text-align:var(--load-more-button-align)}.elementor-widget-loop-grid .e-loop__load-more .elementor-button{width:var(--load-more-button-width)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-loop-grid.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-loop-grid.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-loop-grid.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-loop-grid.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-loop-grid.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-loop-grid>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-loop-grid:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-loop-grid>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative}.elementor-widget-loop-grid .e-loop-nothing-found-message{color:var(--e-loop-nothing-found-message-color,#1f2124);padding-block-end:var(--e-loop-nothing-found-message-space-from-bottom,30px);padding-block-start:var(--e-loop-nothing-found-message-space-from-top,30px);text-align:var(--e-loop-nothing-found-message-align,center)}.elementor-loop-container.elementor-posts-masonry{align-items:flex-start}.elementor-loop-container:not(.elementor-posts-masonry){align-items:stretch}@keyframes loadingOpacityAnimation{0%,to{opacity:1}50%{opacity:.6}} \ No newline at end of file diff --git a/assets/css/widget-lottie-rtl.min.css b/assets/css/widget-lottie-rtl.min.css new file mode 100644 index 00000000..72a742c4 --- /dev/null +++ b/assets/css/widget-lottie-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-lottie__container{display:inline-block;max-width:var(--lottie-container-max-width);opacity:var(--lottie-container-opacity);width:var(--lottie-container-width)}.e-lottie__container:hover{opacity:var(--lottie-container-opacity-hover);transition-duration:var(--lottie-container-transition-duration-hover)}.e-lottie__container svg,.e-lottie__container svg *{transition:none!important}.e-lottie__caption{color:var(--caption-color);margin-top:var(--caption-margin-top);text-align:var(--caption-text-align)} \ No newline at end of file diff --git a/assets/css/widget-lottie.min.css b/assets/css/widget-lottie.min.css new file mode 100644 index 00000000..72a742c4 --- /dev/null +++ b/assets/css/widget-lottie.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-lottie__container{display:inline-block;max-width:var(--lottie-container-max-width);opacity:var(--lottie-container-opacity);width:var(--lottie-container-width)}.e-lottie__container:hover{opacity:var(--lottie-container-opacity-hover);transition-duration:var(--lottie-container-transition-duration-hover)}.e-lottie__container svg,.e-lottie__container svg *{transition:none!important}.e-lottie__caption{color:var(--caption-color);margin-top:var(--caption-margin-top);text-align:var(--caption-text-align)} \ No newline at end of file diff --git a/assets/css/widget-media-carousel-rtl.min.css b/assets/css/widget-media-carousel-rtl.min.css new file mode 100644 index 00000000..de94df19 --- /dev/null +++ b/assets/css/widget-media-carousel-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-skin-carousel .elementor-main-swiper,.elementor-skin-coverflow .elementor-main-swiper{height:230px}.elementor-skin-slideshow .elementor-main-swiper{height:450px;position:relative}.elementor-skin-slideshow .elementor-thumbnails-swiper{height:auto}.elementor-skin-slideshow .elementor-thumbnails-swiper .elementor-custom-embed-play i{font-size:50px}.elementor-skin-slideshow .elementor-thumbnails-swiper .swiper-slide{cursor:pointer}.elementor-skin-slideshow .elementor-thumbnails-swiper .swiper-slide:not(.swiper-slide-active):after{background-color:rgba(0,0,0,.3);content:"";inset:0;position:absolute}.elementor-carousel-image{background:no-repeat 50%;background-size:cover;height:100%;position:relative}.elementor-carousel-image-overlay{align-items:center;background-color:hsla(213,9%,45%,.8);color:var(--e-carousel-image-overlay-color,#fff);display:flex;height:100%;justify-content:center;left:0;padding:20px;position:absolute;text-align:center;top:0;transition:transform .5s,opacity .5s;width:100%}.elementor-carousel-image-overlay i{font-size:var(--e-carousel-image-overlay-icon-size,21px)}.elementor-carousel-image-overlay svg{fill:var(--e-carousel-image-overlay-color,#fff);height:var(--e-carousel-image-overlay-icon-size,21px);width:var(--e-carousel-image-overlay-icon-size,21px)} \ No newline at end of file diff --git a/assets/css/widget-media-carousel.min.css b/assets/css/widget-media-carousel.min.css new file mode 100644 index 00000000..de94df19 --- /dev/null +++ b/assets/css/widget-media-carousel.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-skin-carousel .elementor-main-swiper,.elementor-skin-coverflow .elementor-main-swiper{height:230px}.elementor-skin-slideshow .elementor-main-swiper{height:450px;position:relative}.elementor-skin-slideshow .elementor-thumbnails-swiper{height:auto}.elementor-skin-slideshow .elementor-thumbnails-swiper .elementor-custom-embed-play i{font-size:50px}.elementor-skin-slideshow .elementor-thumbnails-swiper .swiper-slide{cursor:pointer}.elementor-skin-slideshow .elementor-thumbnails-swiper .swiper-slide:not(.swiper-slide-active):after{background-color:rgba(0,0,0,.3);content:"";inset:0;position:absolute}.elementor-carousel-image{background:no-repeat 50%;background-size:cover;height:100%;position:relative}.elementor-carousel-image-overlay{align-items:center;background-color:hsla(213,9%,45%,.8);color:var(--e-carousel-image-overlay-color,#fff);display:flex;height:100%;justify-content:center;left:0;padding:20px;position:absolute;text-align:center;top:0;transition:transform .5s,opacity .5s;width:100%}.elementor-carousel-image-overlay i{font-size:var(--e-carousel-image-overlay-icon-size,21px)}.elementor-carousel-image-overlay svg{fill:var(--e-carousel-image-overlay-color,#fff);height:var(--e-carousel-image-overlay-icon-size,21px);width:var(--e-carousel-image-overlay-icon-size,21px)} \ No newline at end of file diff --git a/assets/css/widget-mega-menu-rtl.min.css b/assets/css/widget-mega-menu-rtl.min.css new file mode 100644 index 00000000..2a26c75f --- /dev/null +++ b/assets/css/widget-mega-menu-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-n-menu{--n-menu-direction:column;--n-menu-wrapper-display:flex;--n-menu-heading-justify-content:initial;--n-menu-title-color-normal:#1f2124;--n-menu-title-color-active:#58d0f5;--n-menu-icon-color:var(--n-menu-title-color-normal);--n-menu-icon-color-active:var(--n-menu-title-color-active);--n-menu-icon-color-hover:var(--n-menu-title-color-hover);--n-menu-title-normal-color-dropdown:var(--n-menu-title-color-normal);--n-menu-title-active-color-dropdown:var(--n-menu-title-color-active);--n-menu-title-hover-color-fallback:#1f2124;--n-menu-title-font-size:1rem;--n-menu-title-justify-content:initial;--n-menu-title-flex-grow:initial;--n-menu-title-justify-content-mobile:initial;--n-menu-title-space-between:0px;--n-menu-title-distance-from-content:0px;--n-menu-title-color-hover:#1f2124;--n-menu-title-padding:0.5rem 1rem;--n-menu-title-transition:0.3s;--n-menu-title-line-height:1.5;--n-menu-title-order:initial;--n-menu-title-direction:initial;--n-menu-title-align-items:center;--n-menu-toggle-align:center;--n-menu-toggle-icon-wrapper-animation-duration:500ms;--n-menu-toggle-icon-hover-duration:500ms;--n-menu-toggle-icon-size:20px;--n-menu-toggle-icon-color:#1f2124;--n-menu-toggle-icon-color-hover:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-color-active:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-border-radius:initial;--n-menu-toggle-icon-padding:initial;--n-menu-toggle-icon-distance-from-dropdown:0px;--n-menu-icon-align-items:center;--n-menu-icon-order:initial;--n-menu-icon-gap:5px;--n-menu-dropdown-icon-gap:5px;--n-menu-dropdown-indicator-size:initial;--n-menu-dropdown-indicator-rotate:initial;--n-menu-dropdown-indicator-space:initial;--n-menu-dropdown-indicator-color-normal:initial;--n-menu-dropdown-indicator-color-hover:initial;--n-menu-dropdown-indicator-color-active:initial;--n-menu-dropdown-content-max-width:initial;--n-menu-dropdown-content-box-border-color:#fff;--n-menu-dropdown-content-box-border-inline-start-width:medium;--n-menu-dropdown-content-box-border-block-end-width:medium;--n-menu-dropdown-content-box-border-block-start-width:medium;--n-menu-dropdown-content-box-border-inline-end-width:medium;--n-menu-dropdown-content-box-border-style:none;--n-menu-dropdown-headings-height:0px;--n-menu-divider-border-width:var(--n-menu-divider-width,2px);--n-menu-open-animation-duration:500ms;--n-menu-heading-overflow-x:initial;--n-menu-heading-wrap:wrap;--stretch-width:100%;--stretch-left:initial;--stretch-right:initial}.elementor-widget-n-menu .e-n-menu{display:flex;flex-direction:column;position:relative}.elementor-widget-n-menu .e-n-menu-wrapper{display:var(--n-menu-wrapper-display);flex-direction:column}.elementor-widget-n-menu .e-n-menu-heading{display:flex;flex-direction:row;flex-wrap:var(--n-menu-heading-wrap);justify-content:var(--n-menu-heading-justify-content);margin:initial;overflow-x:var(--n-menu-heading-overflow-x);padding:initial;row-gap:var(--n-menu-title-space-between);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-n-menu .e-n-menu-heading::-webkit-scrollbar{display:none}.elementor-widget-n-menu .e-n-menu-heading.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active{position:relative}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-n-menu .e-n-menu-heading>.e-con,.elementor-widget-n-menu .e-n-menu-heading>.e-n-menu-item>.e-con{display:none}.elementor-widget-n-menu .e-n-menu-item{display:flex;list-style:none;margin-block:initial;padding-block:initial}.elementor-widget-n-menu .e-n-menu-item .e-n-menu-title{position:relative}.elementor-widget-n-menu .e-n-menu-item:not(:last-of-type) .e-n-menu-title:after{align-self:center;border-color:var(--n-menu-divider-color,#000);border-inline-start-style:var(--n-menu-divider-style,solid);border-inline-start-width:var(--n-menu-divider-border-width);content:var(--n-menu-divider-content,none);height:var(--n-menu-divider-height,35%);inset-inline-end:calc(var(--n-menu-title-space-between) / 2 * -1 - var(--n-menu-divider-border-width) / 2);position:absolute}.elementor-widget-n-menu .e-n-menu-content{background-color:transparent;display:flex;flex-direction:column;min-width:0;z-index:2147483620}.elementor-widget-n-menu .e-n-menu-content>.e-con{animation-duration:var(--n-menu-open-animation-duration);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}:where(.elementor-widget-n-menu .e-n-menu-content>.e-con){background-color:#fff}.elementor-widget-n-menu .e-n-menu-content>.e-con:not(.e-active){display:none}.elementor-widget-n-menu .e-n-menu-title{align-items:center;border:#fff;color:var(--n-menu-title-color-normal);display:flex;flex-direction:row;flex-grow:var(--n-menu-title-flex-grow);font-weight:500;gap:var(--n-menu-dropdown-indicator-space);justify-content:var(--n-menu-title-justify-content);margin:initial;padding:var(--n-menu-title-padding);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.elementor-widget-n-menu .e-n-menu-title.e-click,.elementor-widget-n-menu .e-n-menu-title.e-click *{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container{align-items:var(--n-menu-title-align-items);align-self:var(--n-menu-icon-align-items);display:flex;flex-direction:var(--n-menu-title-direction);gap:var(--n-menu-icon-gap);justify-content:var(--n-menu-title-justify-content)}.elementor-widget-n-menu .e-n-menu-title-container.e-link{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link),.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link) *{cursor:default}.elementor-widget-n-menu .e-n-menu-title-text{align-items:center;display:flex;font-size:var(--n-menu-title-font-size);line-height:var(--n-menu-title-line-height);transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon{align-items:center;display:flex;flex-direction:column;order:var(--n-menu-icon-order)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span{align-items:center;display:flex;justify-content:center;transition:transform 0s}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span i{font-size:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span svg{fill:var(--n-menu-title-color-normal);height:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-icon-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon{align-self:var(--n-menu-icon-align-items);background-color:initial;border:initial;color:inherit;display:flex;flex-direction:column;height:calc(var(--n-menu-title-font-size) * var(--n-menu-title-line-height));justify-content:center;margin-inline-start:var(--n-menu-dropdown-icon-gap);padding:initial;position:relative;text-align:center;transform:var(--n-menu-dropdown-indicator-rotate);transition:all var(--n-menu-title-transition);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span i{font-size:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span svg{height:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-opened{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-closed{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-closed{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-opened{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-color-normal)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon i{color:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon svg{fill:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current) .icon-active{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current span>svg{fill:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu-title.e-current a{color:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .icon-inactive{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>i{color:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>svg{fill:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-title-container:not(.e-link){cursor:default}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) svg{fill:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) i{color:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current),.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) a{color:var(--n-menu-title-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon i{color:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon svg{fill:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-toggle{align-self:var(--n-menu-toggle-align);background-color:initial;border:initial;color:inherit;display:none;padding:initial;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1000}.elementor-widget-n-menu .e-n-menu-toggle:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-toggle i{color:var(--n-menu-toggle-icon-color);font-size:var(--n-menu-toggle-icon-size);transition:all var(--n-menu-toggle-icon-hover-duration)}.elementor-widget-n-menu .e-n-menu-toggle svg{fill:var(--n-menu-toggle-icon-color);height:auto;transition:all var(--n-menu-toggle-icon-hover-duration);width:var(--n-menu-toggle-icon-size)}.elementor-widget-n-menu .e-n-menu-toggle span{align-items:center;border-radius:var(--n-menu-toggle-icon-border-radius);display:flex;justify-content:center;padding:var(--n-menu-toggle-icon-padding);text-align:center}.elementor-widget-n-menu .e-n-menu-toggle span.e-close{height:100%;inset:0;opacity:0;position:absolute;width:100%}.elementor-widget-n-menu .e-n-menu-toggle span.e-close svg{height:100%;-o-object-fit:contain;object-fit:contain}.elementor-widget-n-menu .e-n-menu-toggle [class^=elementor-animation-]{animation-duration:var(--n-menu-toggle-icon-wrapper-animation-duration);transition-duration:var(--n-menu-toggle-icon-wrapper-animation-duration)}.elementor-widget-n-menu .e-n-menu-toggle:hover i{color:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle:hover svg{fill:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-open{opacity:0}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-close{opacity:1}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] i{color:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] svg{fill:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-item:not(:last-child){margin-inline-end:var(--n-menu-title-space-between)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-content{left:var(--stretch-left);position:absolute;right:var(--stretch-right);width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]):not(.content-above) .e-active.e-n-menu-content{padding-block-start:var(--n-menu-title-distance-from-content);top:100%}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]).content-above .e-active.e-n-menu-content{bottom:100%;padding-block-end:var(--n-menu-title-distance-from-content)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown]{gap:0}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-wrapper{animation:hide-scroll .3s backwards;background-color:transparent;border-block-end:var(--n-menu-dropdown-content-box-border-width-block-end);border-block-start:var(--n-menu-dropdown-content-box-border-width-block-start);border-inline-end:var(--n-menu-dropdown-content-box-border-width-inline-end);border-inline-start:var(--n-menu-dropdown-content-box-border-width-inline-start);border-color:var(--n-menu-dropdown-content-box-border-color);border-radius:var(--n-menu-dropdown-content-box-border-radius);border-style:var(--n-menu-dropdown-content-box-border-style);box-shadow:var(--n-menu-dropdown-content-box-shadow-horizontal) var(--n-menu-dropdown-content-box-shadow-vertical) var(--n-menu-dropdown-content-box-shadow-blur) var(--n-menu-dropdown-content-box-shadow-spread) var(--n-menu-dropdown-content-box-shadow-color) var(--n-menu-dropdown-content-box-shadow-position, );flex-direction:column;left:var(--stretch-left);margin-block-start:var(--n-menu-toggle-icon-distance-from-dropdown);max-height:var(--n-menu-dropdown-content-box-height);min-width:0;overflow-x:hidden;overflow-y:auto;position:absolute;right:var(--stretch-right);top:100%;transition:max-height .3s;width:var(--stretch-width);z-index:2147483640}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-item{display:flex;flex-direction:column;width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title{background-color:#fff;flex-wrap:wrap;justify-content:var(--n-menu-title-justify-content-mobile);white-space:normal;width:auto}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-normal-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current a{color:var(--n-menu-title-active-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content{overflow:hidden;width:var(--stretch-width);--n-menu-dropdown-content-max-width:initial}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con{margin-block-start:var(--n-menu-title-distance-from-content);width:var(--width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con .elementor-empty-view{min-width:auto;width:100%}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con-inner{max-width:var(--content-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-toggle[aria-expanded=true]+.e-n-menu-wrapper{--n-menu-wrapper-display:flex}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con){--width:fit-content}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con).e-empty{--empty-top-level-menu-content-container-min-width:400px;--width:var(--empty-top-level-menu-content-container-min-width)}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con) .e-con.e-empty{--nested-containers-min-width-for-dropzone:150px;min-width:var(--nested-containers-min-width-for-dropzone)}.elementor-widget-n-menu.elementor-loading{pointer-events:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown .e-n-menu-toggle{display:flex}@media (max-width:767px){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile .e-n-menu-toggle{display:flex}}@media (max-width:-1){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra .e-n-menu-toggle{display:flex}}@media (max-width:1024px){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet .e-n-menu-toggle{display:flex}}@media (max-width:-1){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra .e-n-menu-toggle{display:flex}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop .e-n-menu-toggle{display:flex}}@keyframes hide-scroll{0%,to{overflow:hidden}}.e-con-inner>.elementor-widget-n-menu,.e-con>.elementor-widget-n-menu{--flex-grow:var(--container-widget-flex-grow)}[data-core-v316-plus=true] .elementor-widget-n-menu .e-n-menu .e-n-menu-content>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/widget-mega-menu.min.css b/assets/css/widget-mega-menu.min.css new file mode 100644 index 00000000..2a26c75f --- /dev/null +++ b/assets/css/widget-mega-menu.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-n-menu{--n-menu-direction:column;--n-menu-wrapper-display:flex;--n-menu-heading-justify-content:initial;--n-menu-title-color-normal:#1f2124;--n-menu-title-color-active:#58d0f5;--n-menu-icon-color:var(--n-menu-title-color-normal);--n-menu-icon-color-active:var(--n-menu-title-color-active);--n-menu-icon-color-hover:var(--n-menu-title-color-hover);--n-menu-title-normal-color-dropdown:var(--n-menu-title-color-normal);--n-menu-title-active-color-dropdown:var(--n-menu-title-color-active);--n-menu-title-hover-color-fallback:#1f2124;--n-menu-title-font-size:1rem;--n-menu-title-justify-content:initial;--n-menu-title-flex-grow:initial;--n-menu-title-justify-content-mobile:initial;--n-menu-title-space-between:0px;--n-menu-title-distance-from-content:0px;--n-menu-title-color-hover:#1f2124;--n-menu-title-padding:0.5rem 1rem;--n-menu-title-transition:0.3s;--n-menu-title-line-height:1.5;--n-menu-title-order:initial;--n-menu-title-direction:initial;--n-menu-title-align-items:center;--n-menu-toggle-align:center;--n-menu-toggle-icon-wrapper-animation-duration:500ms;--n-menu-toggle-icon-hover-duration:500ms;--n-menu-toggle-icon-size:20px;--n-menu-toggle-icon-color:#1f2124;--n-menu-toggle-icon-color-hover:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-color-active:var(--n-menu-toggle-icon-color);--n-menu-toggle-icon-border-radius:initial;--n-menu-toggle-icon-padding:initial;--n-menu-toggle-icon-distance-from-dropdown:0px;--n-menu-icon-align-items:center;--n-menu-icon-order:initial;--n-menu-icon-gap:5px;--n-menu-dropdown-icon-gap:5px;--n-menu-dropdown-indicator-size:initial;--n-menu-dropdown-indicator-rotate:initial;--n-menu-dropdown-indicator-space:initial;--n-menu-dropdown-indicator-color-normal:initial;--n-menu-dropdown-indicator-color-hover:initial;--n-menu-dropdown-indicator-color-active:initial;--n-menu-dropdown-content-max-width:initial;--n-menu-dropdown-content-box-border-color:#fff;--n-menu-dropdown-content-box-border-inline-start-width:medium;--n-menu-dropdown-content-box-border-block-end-width:medium;--n-menu-dropdown-content-box-border-block-start-width:medium;--n-menu-dropdown-content-box-border-inline-end-width:medium;--n-menu-dropdown-content-box-border-style:none;--n-menu-dropdown-headings-height:0px;--n-menu-divider-border-width:var(--n-menu-divider-width,2px);--n-menu-open-animation-duration:500ms;--n-menu-heading-overflow-x:initial;--n-menu-heading-wrap:wrap;--stretch-width:100%;--stretch-left:initial;--stretch-right:initial}.elementor-widget-n-menu .e-n-menu{display:flex;flex-direction:column;position:relative}.elementor-widget-n-menu .e-n-menu-wrapper{display:var(--n-menu-wrapper-display);flex-direction:column}.elementor-widget-n-menu .e-n-menu-heading{display:flex;flex-direction:row;flex-wrap:var(--n-menu-heading-wrap);justify-content:var(--n-menu-heading-justify-content);margin:initial;overflow-x:var(--n-menu-heading-overflow-x);padding:initial;row-gap:var(--n-menu-title-space-between);-ms-overflow-style:none;scrollbar-width:none}.elementor-widget-n-menu .e-n-menu-heading::-webkit-scrollbar{display:none}.elementor-widget-n-menu .e-n-menu-heading.e-scroll{cursor:grabbing;cursor:-webkit-grabbing}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active{position:relative}.elementor-widget-n-menu .e-n-menu-heading.e-scroll-active:before{content:"";inset-block:0;inset-inline:-1000vw;position:absolute;z-index:2}.elementor-widget-n-menu .e-n-menu-heading>.e-con,.elementor-widget-n-menu .e-n-menu-heading>.e-n-menu-item>.e-con{display:none}.elementor-widget-n-menu .e-n-menu-item{display:flex;list-style:none;margin-block:initial;padding-block:initial}.elementor-widget-n-menu .e-n-menu-item .e-n-menu-title{position:relative}.elementor-widget-n-menu .e-n-menu-item:not(:last-of-type) .e-n-menu-title:after{align-self:center;border-color:var(--n-menu-divider-color,#000);border-inline-start-style:var(--n-menu-divider-style,solid);border-inline-start-width:var(--n-menu-divider-border-width);content:var(--n-menu-divider-content,none);height:var(--n-menu-divider-height,35%);inset-inline-end:calc(var(--n-menu-title-space-between) / 2 * -1 - var(--n-menu-divider-border-width) / 2);position:absolute}.elementor-widget-n-menu .e-n-menu-content{background-color:transparent;display:flex;flex-direction:column;min-width:0;z-index:2147483620}.elementor-widget-n-menu .e-n-menu-content>.e-con{animation-duration:var(--n-menu-open-animation-duration);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}:where(.elementor-widget-n-menu .e-n-menu-content>.e-con){background-color:#fff}.elementor-widget-n-menu .e-n-menu-content>.e-con:not(.e-active){display:none}.elementor-widget-n-menu .e-n-menu-title{align-items:center;border:#fff;color:var(--n-menu-title-color-normal);display:flex;flex-direction:row;flex-grow:var(--n-menu-title-flex-grow);font-weight:500;gap:var(--n-menu-dropdown-indicator-space);justify-content:var(--n-menu-title-justify-content);margin:initial;padding:var(--n-menu-title-padding);-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.elementor-widget-n-menu .e-n-menu-title.e-click,.elementor-widget-n-menu .e-n-menu-title.e-click *{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container{align-items:var(--n-menu-title-align-items);align-self:var(--n-menu-icon-align-items);display:flex;flex-direction:var(--n-menu-title-direction);gap:var(--n-menu-icon-gap);justify-content:var(--n-menu-title-justify-content)}.elementor-widget-n-menu .e-n-menu-title-container.e-link{cursor:pointer}.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link),.elementor-widget-n-menu .e-n-menu-title-container:not(.e-link) *{cursor:default}.elementor-widget-n-menu .e-n-menu-title-text{align-items:center;display:flex;font-size:var(--n-menu-title-font-size);line-height:var(--n-menu-title-line-height);transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon{align-items:center;display:flex;flex-direction:column;order:var(--n-menu-icon-order)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span{align-items:center;display:flex;justify-content:center;transition:transform 0s}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span i{font-size:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition)}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-icon span svg{fill:var(--n-menu-title-color-normal);height:var(--n-menu-icon-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-icon-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon{align-self:var(--n-menu-icon-align-items);background-color:initial;border:initial;color:inherit;display:flex;flex-direction:column;height:calc(var(--n-menu-title-font-size) * var(--n-menu-title-line-height));justify-content:center;margin-inline-start:var(--n-menu-dropdown-icon-gap);padding:initial;position:relative;text-align:center;transform:var(--n-menu-dropdown-indicator-rotate);transition:all var(--n-menu-title-transition);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span i{font-size:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon span svg{height:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size));transition:all var(--n-menu-title-transition);width:var(--n-menu-dropdown-indicator-size,var(--n-menu-title-font-size))}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-opened{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=false] .e-n-menu-dropdown-icon-closed{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-closed{display:none}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon[aria-expanded=true] .e-n-menu-dropdown-icon-opened{display:flex}.elementor-widget-n-menu .e-n-menu-title .e-n-menu-dropdown-icon:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-color-normal)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon i{color:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-icon svg{fill:var(--n-menu-icon-color)}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current):not(:hover) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-color-normal))}.elementor-widget-n-menu .e-n-menu-title:not(.e-current) .icon-active{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current span>svg{fill:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu-title.e-current a{color:var(--n-menu-title-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .icon-inactive{height:0;opacity:0;transform:translateY(-100%)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>i{color:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-icon span>svg{fill:var(--n-menu-icon-color-active)}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-color-active))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-title-container:not(.e-link){cursor:default}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) svg{fill:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) i{color:var(--n-menu-title-color-hover,var(--n-menu-title-hover-color-fallback))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current),.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) a{color:var(--n-menu-title-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon i{color:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-icon svg{fill:var(--n-menu-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-title:hover:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-hover,var(--n-menu-title-color-hover))}.elementor-widget-n-menu .e-n-menu-toggle{align-self:var(--n-menu-toggle-align);background-color:initial;border:initial;color:inherit;display:none;padding:initial;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1000}.elementor-widget-n-menu .e-n-menu-toggle:focus:not(:focus-visible){outline:none}.elementor-widget-n-menu .e-n-menu-toggle i{color:var(--n-menu-toggle-icon-color);font-size:var(--n-menu-toggle-icon-size);transition:all var(--n-menu-toggle-icon-hover-duration)}.elementor-widget-n-menu .e-n-menu-toggle svg{fill:var(--n-menu-toggle-icon-color);height:auto;transition:all var(--n-menu-toggle-icon-hover-duration);width:var(--n-menu-toggle-icon-size)}.elementor-widget-n-menu .e-n-menu-toggle span{align-items:center;border-radius:var(--n-menu-toggle-icon-border-radius);display:flex;justify-content:center;padding:var(--n-menu-toggle-icon-padding);text-align:center}.elementor-widget-n-menu .e-n-menu-toggle span.e-close{height:100%;inset:0;opacity:0;position:absolute;width:100%}.elementor-widget-n-menu .e-n-menu-toggle span.e-close svg{height:100%;-o-object-fit:contain;object-fit:contain}.elementor-widget-n-menu .e-n-menu-toggle [class^=elementor-animation-]{animation-duration:var(--n-menu-toggle-icon-wrapper-animation-duration);transition-duration:var(--n-menu-toggle-icon-wrapper-animation-duration)}.elementor-widget-n-menu .e-n-menu-toggle:hover i{color:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle:hover svg{fill:var(--n-menu-toggle-icon-color-hover)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-open{opacity:0}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] .e-close{opacity:1}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] i{color:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu-toggle[aria-expanded=true] svg{fill:var(--n-menu-toggle-icon-color-active)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-item:not(:last-child){margin-inline-end:var(--n-menu-title-space-between)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]) .e-n-menu-content{left:var(--stretch-left);position:absolute;right:var(--stretch-right);width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]):not(.content-above) .e-active.e-n-menu-content{padding-block-start:var(--n-menu-title-distance-from-content);top:100%}.elementor-widget-n-menu .e-n-menu:not([data-layout=dropdown]).content-above .e-active.e-n-menu-content{bottom:100%;padding-block-end:var(--n-menu-title-distance-from-content)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown]{gap:0}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-wrapper{animation:hide-scroll .3s backwards;background-color:transparent;border-block-end:var(--n-menu-dropdown-content-box-border-width-block-end);border-block-start:var(--n-menu-dropdown-content-box-border-width-block-start);border-inline-end:var(--n-menu-dropdown-content-box-border-width-inline-end);border-inline-start:var(--n-menu-dropdown-content-box-border-width-inline-start);border-color:var(--n-menu-dropdown-content-box-border-color);border-radius:var(--n-menu-dropdown-content-box-border-radius);border-style:var(--n-menu-dropdown-content-box-border-style);box-shadow:var(--n-menu-dropdown-content-box-shadow-horizontal) var(--n-menu-dropdown-content-box-shadow-vertical) var(--n-menu-dropdown-content-box-shadow-blur) var(--n-menu-dropdown-content-box-shadow-spread) var(--n-menu-dropdown-content-box-shadow-color) var(--n-menu-dropdown-content-box-shadow-position, );flex-direction:column;left:var(--stretch-left);margin-block-start:var(--n-menu-toggle-icon-distance-from-dropdown);max-height:var(--n-menu-dropdown-content-box-height);min-width:0;overflow-x:hidden;overflow-y:auto;position:absolute;right:var(--stretch-right);top:100%;transition:max-height .3s;width:var(--stretch-width);z-index:2147483640}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-item{display:flex;flex-direction:column;width:var(--stretch-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title{background-color:#fff;flex-wrap:wrap;justify-content:var(--n-menu-title-justify-content-mobile);white-space:normal;width:auto}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-title-container .e-n-menu-title-text{color:var(--n-menu-title-normal-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title:not(.e-current) .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-normal,var(--n-menu-title-normal-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current,.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current a{color:var(--n-menu-title-active-color-dropdown)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon i{color:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-title.e-current .e-n-menu-dropdown-icon svg{fill:var(--n-menu-dropdown-indicator-color-active,var(--n-menu-title-active-color-dropdown))}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content{overflow:hidden;width:var(--stretch-width);--n-menu-dropdown-content-max-width:initial}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con{margin-block-start:var(--n-menu-title-distance-from-content);width:var(--width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con .elementor-empty-view{min-width:auto;width:100%}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-content>.e-con-inner{max-width:var(--content-width)}.elementor-widget-n-menu .e-n-menu[data-layout=dropdown] .e-n-menu-toggle[aria-expanded=true]+.e-n-menu-wrapper{--n-menu-wrapper-display:flex}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con){--width:fit-content}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con).e-empty{--empty-top-level-menu-content-container-min-width:400px;--width:var(--empty-top-level-menu-content-container-min-width)}.elementor-widget-n-menu.e-fit_to_content :where(.e-n-menu-content>.e-con) .e-con.e-empty{--nested-containers-min-width-for-dropzone:150px;min-width:var(--nested-containers-min-width-for-dropzone)}.elementor-widget-n-menu.elementor-loading{pointer-events:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-layout-dropdown .e-n-menu-toggle{display:flex}@media (max-width:767px){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile .e-n-menu-toggle{display:flex}}@media (max-width:-1){.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-mobile_extra .e-n-menu-toggle{display:flex}}@media (max-width:1024px){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet .e-n-menu-toggle{display:flex}}@media (max-width:-1){.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-tablet_extra .e-n-menu-toggle{display:flex}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop{--n-menu-wrapper-display:none}.elementor.elementor .elementor-widget-n-menu.e-n-menu-laptop .e-n-menu-toggle{display:flex}}@keyframes hide-scroll{0%,to{overflow:hidden}}.e-con-inner>.elementor-widget-n-menu,.e-con>.elementor-widget-n-menu{--flex-grow:var(--container-widget-flex-grow)}[data-core-v316-plus=true] .elementor-widget-n-menu .e-n-menu .e-n-menu-content>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/widget-nav-menu-rtl.min.css b/assets/css/widget-nav-menu-rtl.min.css new file mode 100644 index 00000000..ce9a3f4b --- /dev/null +++ b/assets/css/widget-nav-menu-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.site-main .menu-navigation-container{overflow:visible}.elementor-item:after,.elementor-item:before{display:block;position:absolute;transition:.3s;transition-timing-function:cubic-bezier(.58,.3,.005,1)}.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{opacity:0}.elementor-item-active:after,.elementor-item-active:before,.elementor-item.highlighted:after,.elementor-item.highlighted:before,.elementor-item:focus:after,.elementor-item:focus:before,.elementor-item:hover:after,.elementor-item:hover:before{transform:scale(1)}.e--pointer-double-line .elementor-item:after,.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:after,.e--pointer-overline .elementor-item:before,.e--pointer-underline .elementor-item:after,.e--pointer-underline .elementor-item:before{background-color:#3f444b;height:3px;left:0;width:100%;z-index:2}.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{height:0;left:50%;width:0}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:10px}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:-10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:-10px}.e--pointer-double-line.e--animation-none,.e--pointer-double-line.e--animation-none .elementor-item,.e--pointer-double-line.e--animation-none .elementor-item:after,.e--pointer-double-line.e--animation-none .elementor-item:before,.e--pointer-double-line.e--animation-none .elementor-item:focus,.e--pointer-double-line.e--animation-none .elementor-item:hover,.e--pointer-double-line.e--animation-none:after,.e--pointer-double-line.e--animation-none:before,.e--pointer-double-line.e--animation-none:focus,.e--pointer-double-line.e--animation-none:hover,.e--pointer-overline.e--animation-none,.e--pointer-overline.e--animation-none .elementor-item,.e--pointer-overline.e--animation-none .elementor-item:after,.e--pointer-overline.e--animation-none .elementor-item:before,.e--pointer-overline.e--animation-none .elementor-item:focus,.e--pointer-overline.e--animation-none .elementor-item:hover,.e--pointer-overline.e--animation-none:after,.e--pointer-overline.e--animation-none:before,.e--pointer-overline.e--animation-none:focus,.e--pointer-overline.e--animation-none:hover,.e--pointer-underline.e--animation-none,.e--pointer-underline.e--animation-none .elementor-item,.e--pointer-underline.e--animation-none .elementor-item:after,.e--pointer-underline.e--animation-none .elementor-item:before,.e--pointer-underline.e--animation-none .elementor-item:focus,.e--pointer-underline.e--animation-none .elementor-item:hover,.e--pointer-underline.e--animation-none:after,.e--pointer-underline.e--animation-none:before,.e--pointer-underline.e--animation-none:focus,.e--pointer-underline.e--animation-none:hover{transition-duration:0s}.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:before{content:"";top:0}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:-20px;width:10px}.e--pointer-double-line .elementor-item:after,.e--pointer-underline .elementor-item:after{bottom:0;content:""}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{inset-inline-start:100%;width:10px}.e--pointer-framed .elementor-item:after,.e--pointer-framed .elementor-item:before{background:transparent;border:3px solid #3f444b;bottom:0;left:0;right:0;top:0}.e--pointer-framed .elementor-item:before{content:""}.e--pointer-framed.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(.75)}.e--pointer-framed.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.25)}.e--pointer-framed.e--animation-grow .elementor-item:before,.e--pointer-framed.e--animation-shrink .elementor-item:before{transition:opacity .2s,transform .4s}.e--pointer-framed.e--animation-draw .elementor-item:after,.e--pointer-framed.e--animation-draw .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-draw .elementor-item:before{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:0;border-inline-start-width:3px;transition:width .1s .2s,height .1s .3s,opacity .12s .22s}.e--pointer-framed.e--animation-draw .elementor-item:after{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto;transition:width .1s,height .1s .1s,opacity .02s .18s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{height:100%;width:100%}.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{transition:opacity .02s,height .1s,width .1s .1s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:after{transition:opacity .02s .2s,height .1s .2s,width .1s .3s}.e--pointer-framed.e--animation-corners .elementor-item:after,.e--pointer-framed.e--animation-corners .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-corners .elementor-item:before{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:0;border-inline-start-width:3px}.e--pointer-framed.e--animation-corners .elementor-item:after{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto}.e--pointer-framed.e--animation-corners .elementor-item-active:after,.e--pointer-framed.e--animation-corners .elementor-item-active:before,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:after,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:before,.e--pointer-framed.e--animation-corners .elementor-item:focus:after,.e--pointer-framed.e--animation-corners .elementor-item:focus:before,.e--pointer-framed.e--animation-corners .elementor-item:hover:after,.e--pointer-framed.e--animation-corners .elementor-item:hover:before{height:100%;transition:opacity 2ms,width .4s,height .4s;width:100%}.e--pointer-framed.e--animation-none,.e--pointer-framed.e--animation-none .elementor-item,.e--pointer-framed.e--animation-none .elementor-item:after,.e--pointer-framed.e--animation-none .elementor-item:before,.e--pointer-framed.e--animation-none .elementor-item:focus,.e--pointer-framed.e--animation-none .elementor-item:hover,.e--pointer-framed.e--animation-none:after,.e--pointer-framed.e--animation-none:before,.e--pointer-framed.e--animation-none:focus,.e--pointer-framed.e--animation-none:hover{transition-duration:0s}.e--pointer-background .elementor-item:after,.e--pointer-background .elementor-item:before{content:"";transition:.3s}.e--pointer-background .elementor-item:before{background:#3f444b;inset:0;z-index:-1}.e--pointer-background .elementor-item-active,.e--pointer-background .elementor-item.highlighted,.e--pointer-background .elementor-item:focus,.e--pointer-background .elementor-item:hover{color:#fff}.e--pointer-background.e--animation-grow .elementor-item:before{transform:scale(.5)}.e--pointer-background.e--animation-grow .elementor-item-active:before,.e--pointer-background.e--animation-grow .elementor-item.highlighted:before,.e--pointer-background.e--animation-grow .elementor-item:focus:before,.e--pointer-background.e--animation-grow .elementor-item:hover:before{opacity:1;transform:scale(1)}.e--pointer-background.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.2);transition:.3s}.e--pointer-background.e--animation-shrink .elementor-item-active:before,.e--pointer-background.e--animation-shrink .elementor-item.highlighted:before,.e--pointer-background.e--animation-shrink .elementor-item:focus:before,.e--pointer-background.e--animation-shrink .elementor-item:hover:before{transition:opacity .15s,transform .4s}.e--pointer-background.e--animation-sweep-left .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:100%}.e--pointer-background.e--animation-sweep-right .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{right:100%}.e--pointer-background.e--animation-sweep-up .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:100%}.e--pointer-background.e--animation-sweep-down .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:100%}.e--pointer-background.e--animation-shutter-out-vertical .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:50%;top:50%}.e--pointer-background.e--animation-shutter-out-horizontal .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:50%;right:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{background:#3f444b;inset:0;z-index:-1}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:before{bottom:100%;top:0}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{bottom:0;top:100%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:before{bottom:50%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:after{top:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:before{left:100%;right:0}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after{left:0;right:100%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:before{left:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:after{right:50%}.e--pointer-background.e--animation-none,.e--pointer-background.e--animation-none .elementor-item,.e--pointer-background.e--animation-none .elementor-item:after,.e--pointer-background.e--animation-none .elementor-item:before,.e--pointer-background.e--animation-none .elementor-item:focus,.e--pointer-background.e--animation-none .elementor-item:hover,.e--pointer-background.e--animation-none:after,.e--pointer-background.e--animation-none:before,.e--pointer-background.e--animation-none:focus,.e--pointer-background.e--animation-none:hover{transition-duration:0s}.e--pointer-text.e--animation-skew .elementor-item:focus,.e--pointer-text.e--animation-skew .elementor-item:hover{transform:skew(-8deg)}.e--pointer-text.e--animation-grow .elementor-item:focus,.e--pointer-text.e--animation-grow .elementor-item:hover{transform:scale(1.2)}.e--pointer-text.e--animation-shrink .elementor-item:focus,.e--pointer-text.e--animation-shrink .elementor-item:hover{transform:scale(.8)}.e--pointer-text.e--animation-float .elementor-item:focus,.e--pointer-text.e--animation-float .elementor-item:hover{transform:translateY(-8px)}.e--pointer-text.e--animation-sink .elementor-item:focus,.e--pointer-text.e--animation-sink .elementor-item:hover{transform:translateY(8px)}.e--pointer-text.e--animation-rotate .elementor-item:focus,.e--pointer-text.e--animation-rotate .elementor-item:hover{transform:rotate(6deg)}.e--pointer-text.e--animation-none,.e--pointer-text.e--animation-none .elementor-item,.e--pointer-text.e--animation-none .elementor-item:after,.e--pointer-text.e--animation-none .elementor-item:before,.e--pointer-text.e--animation-none .elementor-item:focus,.e--pointer-text.e--animation-none .elementor-item:hover,.e--pointer-text.e--animation-none:after,.e--pointer-text.e--animation-none:before,.e--pointer-text.e--animation-none:focus,.e--pointer-text.e--animation-none:hover{transition-duration:0s}.elementor-nav-menu--main .elementor-nav-menu a{transition:.4s}.elementor-nav-menu--main .elementor-nav-menu a,.elementor-nav-menu--main .elementor-nav-menu a.highlighted,.elementor-nav-menu--main .elementor-nav-menu a:focus,.elementor-nav-menu--main .elementor-nav-menu a:hover{padding:13px 20px}.elementor-nav-menu--main .elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu--main .elementor-nav-menu a.disabled{background:#3f444b;color:#88909b}.elementor-nav-menu--main .elementor-nav-menu ul{border-style:solid;border-width:0;padding:0;position:absolute;width:12em}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up{background:#fff;display:none;height:20px;overflow:hidden;position:absolute;visibility:hidden}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up-arrow{border:8px dashed transparent;border-bottom:8px solid #33373d;height:0;inset-block-start:-2px;inset-inline-start:50%;margin-inline-start:-8px;overflow:hidden;position:absolute;width:0}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow{border-color:#33373d transparent transparent;border-style:solid dashed dashed;top:6px}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg,.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i{transform:rotate(calc(-90deg * var(--direction-multiplier, 1)))}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg{fill:currentColor;height:1em;width:1em}.elementor-nav-menu--layout-horizontal{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu{display:flex;flex-wrap:wrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu a{flex-grow:1;white-space:nowrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li ul,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>.scroll-down{top:100%!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>a{margin-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-down,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-up,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>ul{inset-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child)>a{margin-inline-end:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child):after{align-self:center;border-color:var(--e-nav-menu-divider-color,#000);border-left-style:var(--e-nav-menu-divider-style,solid);border-left-width:var(--e-nav-menu-divider-width,2px);content:var(--e-nav-menu-divider-content,none);height:var(--e-nav-menu-divider-height,35%)}.elementor-nav-menu__align-right .elementor-nav-menu{justify-content:flex-start;margin-left:auto}.elementor-nav-menu__align-right .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-left .elementor-nav-menu{justify-content:flex-end;margin-right:auto}.elementor-nav-menu__align-left .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-start .elementor-nav-menu{justify-content:flex-start;margin-inline-end:auto}.elementor-nav-menu__align-start .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-end .elementor-nav-menu{justify-content:flex-end;margin-inline-start:auto}.elementor-nav-menu__align-end .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-center .elementor-nav-menu{justify-content:center;margin-inline-end:auto;margin-inline-start:auto}.elementor-nav-menu__align-center .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:center}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu{width:100%}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{flex-grow:1}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>a{justify-content:center}.elementor-widget-nav-menu:not(.elementor-nav-menu--toggle) .elementor-menu-toggle{display:none}.elementor-widget-nav-menu .elementor-widget-container,.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*=elementor-hidden-]){display:flex;flex-direction:column}.elementor-nav-menu{position:relative;z-index:2}.elementor-nav-menu:after{clear:both;content:" ";display:block;font:0/0 serif;height:0;overflow:hidden;visibility:hidden}.elementor-nav-menu,.elementor-nav-menu li,.elementor-nav-menu ul{display:block;line-height:normal;list-style:none;margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.elementor-nav-menu ul{display:none}.elementor-nav-menu ul ul a,.elementor-nav-menu ul ul a:active,.elementor-nav-menu ul ul a:focus,.elementor-nav-menu ul ul a:hover{border-left:16px solid transparent}.elementor-nav-menu ul ul ul a,.elementor-nav-menu ul ul ul a:active,.elementor-nav-menu ul ul ul a:focus,.elementor-nav-menu ul ul ul a:hover{border-left:24px solid transparent}.elementor-nav-menu ul ul ul ul a,.elementor-nav-menu ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul a:hover{border-left:32px solid transparent}.elementor-nav-menu ul ul ul ul ul a,.elementor-nav-menu ul ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul ul a:hover{border-left:40px solid transparent}.elementor-nav-menu a,.elementor-nav-menu li{position:relative}.elementor-nav-menu li{border-width:0}.elementor-nav-menu a{align-items:center;display:flex}.elementor-nav-menu a,.elementor-nav-menu a:focus,.elementor-nav-menu a:hover{line-height:20px;padding:10px 20px}.elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu a.disabled{color:#88909b;cursor:not-allowed}.elementor-nav-menu .e-plus-icon:before{content:"+"}.elementor-nav-menu .sub-arrow{align-items:center;display:flex;line-height:1;margin-block-end:-10px;margin-block-start:-10px;padding:10px;padding-inline-end:0}.elementor-nav-menu .sub-arrow i{pointer-events:none}.elementor-nav-menu .sub-arrow .fa.fa-chevron-down,.elementor-nav-menu .sub-arrow .fas.fa-chevron-down{font-size:.7em}.elementor-nav-menu .sub-arrow .e-font-icon-svg{height:1em;width:1em}.elementor-nav-menu .sub-arrow .e-font-icon-svg.fa-svg-chevron-down{height:.7em;width:.7em}.elementor-nav-menu--dropdown .elementor-item.elementor-item-active,.elementor-nav-menu--dropdown .elementor-item.highlighted,.elementor-nav-menu--dropdown .elementor-item:focus,.elementor-nav-menu--dropdown .elementor-item:hover,.elementor-sub-item.elementor-item-active,.elementor-sub-item.highlighted,.elementor-sub-item:focus,.elementor-sub-item:hover{background-color:#3f444b;color:#fff}.elementor-menu-toggle{align-items:center;background-color:rgba(0,0,0,.05);border:0 solid;border-radius:3px;color:#33373d;cursor:pointer;display:flex;font-size:var(--nav-menu-icon-size,22px);justify-content:center;padding:.25em}.elementor-menu-toggle.elementor-active .elementor-menu-toggle__icon--open,.elementor-menu-toggle:not(.elementor-active) .elementor-menu-toggle__icon--close{display:none}.elementor-menu-toggle .e-font-icon-svg{fill:#33373d;height:1em;width:1em}.elementor-menu-toggle svg{height:auto;width:1em;fill:var(--nav-menu-icon-color,currentColor)}span.elementor-menu-toggle__icon--close,span.elementor-menu-toggle__icon--open{line-height:1}.elementor-nav-menu--dropdown{background-color:#fff;font-size:13px}.elementor-nav-menu--dropdown-none .elementor-menu-toggle,.elementor-nav-menu--dropdown-none .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown.elementor-nav-menu__container{margin-top:10px;overflow-x:hidden;overflow-y:auto;transform-origin:top;transition:max-height .3s,transform .3s}.elementor-nav-menu--dropdown.elementor-nav-menu__container .elementor-sub-item{font-size:.85em}.elementor-nav-menu--dropdown a{color:#33373d}.elementor-nav-menu--dropdown a.current{background:#1f2124;color:#fff}.elementor-nav-menu--dropdown a.disabled{color:#b3b3b3}ul.elementor-nav-menu--dropdown a,ul.elementor-nav-menu--dropdown a:focus,ul.elementor-nav-menu--dropdown a:hover{border-inline-start:8px solid transparent;text-shadow:none}.elementor-nav-menu__text-align-center .elementor-nav-menu--dropdown .elementor-nav-menu a{justify-content:center}.elementor-nav-menu--toggle{--menu-height:100vh}.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{max-height:0;overflow:hidden;transform:scaleY(0)}.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{animation:hide-scroll .3s backwards;max-height:var(--menu-height);transform:scaleY(1)}.elementor-nav-menu--stretch .elementor-nav-menu__container.elementor-nav-menu--dropdown{position:absolute;z-index:9997}@media (max-width:767px){.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--main{display:none}}@media (min-width:768px){.elementor-nav-menu--dropdown-mobile .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:1024px){.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--main{display:none}}@media (min-width:1025px){.elementor-nav-menu--dropdown-tablet .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@keyframes hide-scroll{0%,to{overflow:hidden}} \ No newline at end of file diff --git a/assets/css/widget-nav-menu.min.css b/assets/css/widget-nav-menu.min.css new file mode 100644 index 00000000..11ff79e6 --- /dev/null +++ b/assets/css/widget-nav-menu.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.site-main .menu-navigation-container{overflow:visible}.elementor-item:after,.elementor-item:before{display:block;position:absolute;transition:.3s;transition-timing-function:cubic-bezier(.58,.3,.005,1)}.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{opacity:0}.elementor-item-active:after,.elementor-item-active:before,.elementor-item.highlighted:after,.elementor-item.highlighted:before,.elementor-item:focus:after,.elementor-item:focus:before,.elementor-item:hover:after,.elementor-item:hover:before{transform:scale(1)}.e--pointer-double-line .elementor-item:after,.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:after,.e--pointer-overline .elementor-item:before,.e--pointer-underline .elementor-item:after,.e--pointer-underline .elementor-item:before{background-color:#3f444b;height:3px;left:0;width:100%;z-index:2}.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-double-line.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{height:0;left:50%;width:0}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:10px}.e--pointer-double-line.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-out .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:-10px}.e--pointer-double-line.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-overline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-drop-in .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{bottom:-10px}.e--pointer-double-line.e--animation-none,.e--pointer-double-line.e--animation-none .elementor-item,.e--pointer-double-line.e--animation-none .elementor-item:after,.e--pointer-double-line.e--animation-none .elementor-item:before,.e--pointer-double-line.e--animation-none .elementor-item:focus,.e--pointer-double-line.e--animation-none .elementor-item:hover,.e--pointer-double-line.e--animation-none:after,.e--pointer-double-line.e--animation-none:before,.e--pointer-double-line.e--animation-none:focus,.e--pointer-double-line.e--animation-none:hover,.e--pointer-overline.e--animation-none,.e--pointer-overline.e--animation-none .elementor-item,.e--pointer-overline.e--animation-none .elementor-item:after,.e--pointer-overline.e--animation-none .elementor-item:before,.e--pointer-overline.e--animation-none .elementor-item:focus,.e--pointer-overline.e--animation-none .elementor-item:hover,.e--pointer-overline.e--animation-none:after,.e--pointer-overline.e--animation-none:before,.e--pointer-overline.e--animation-none:focus,.e--pointer-overline.e--animation-none:hover,.e--pointer-underline.e--animation-none,.e--pointer-underline.e--animation-none .elementor-item,.e--pointer-underline.e--animation-none .elementor-item:after,.e--pointer-underline.e--animation-none .elementor-item:before,.e--pointer-underline.e--animation-none .elementor-item:focus,.e--pointer-underline.e--animation-none .elementor-item:hover,.e--pointer-underline.e--animation-none:after,.e--pointer-underline.e--animation-none:before,.e--pointer-underline.e--animation-none:focus,.e--pointer-underline.e--animation-none:hover{transition-duration:0s}.e--pointer-double-line .elementor-item:before,.e--pointer-overline .elementor-item:before{content:"";top:0}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before,.e--pointer-overline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:-20px;width:10px}.e--pointer-double-line .elementor-item:after,.e--pointer-underline .elementor-item:after{bottom:0;content:""}.e--pointer-double-line.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after,.e--pointer-underline.e--animation-slide .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):after{inset-inline-start:100%;width:10px}.e--pointer-framed .elementor-item:after,.e--pointer-framed .elementor-item:before{background:transparent;border:3px solid #3f444b;bottom:0;left:0;right:0;top:0}.e--pointer-framed .elementor-item:before{content:""}.e--pointer-framed.e--animation-grow .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(.75)}.e--pointer-framed.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.25)}.e--pointer-framed.e--animation-grow .elementor-item:before,.e--pointer-framed.e--animation-shrink .elementor-item:before{transition:opacity .2s,transform .4s}.e--pointer-framed.e--animation-draw .elementor-item:after,.e--pointer-framed.e--animation-draw .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-draw .elementor-item:before{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:0;border-inline-start-width:3px;transition:width .1s .2s,height .1s .3s,opacity .12s .22s}.e--pointer-framed.e--animation-draw .elementor-item:after{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto;transition:width .1s,height .1s .1s,opacity .02s .18s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{height:100%;width:100%}.e--pointer-framed.e--animation-draw .elementor-item-active:before,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:before,.e--pointer-framed.e--animation-draw .elementor-item:focus:before,.e--pointer-framed.e--animation-draw .elementor-item:hover:before{transition:opacity .02s,height .1s,width .1s .1s}.e--pointer-framed.e--animation-draw .elementor-item-active:after,.e--pointer-framed.e--animation-draw .elementor-item.highlighted:after,.e--pointer-framed.e--animation-draw .elementor-item:focus:after,.e--pointer-framed.e--animation-draw .elementor-item:hover:after{transition:opacity .02s .2s,height .1s .2s,width .1s .3s}.e--pointer-framed.e--animation-corners .elementor-item:after,.e--pointer-framed.e--animation-corners .elementor-item:before{height:3px;width:3px}.e--pointer-framed.e--animation-corners .elementor-item:before{border-block-end-width:0;border-block-start-width:3px;border-inline-end-width:0;border-inline-start-width:3px}.e--pointer-framed.e--animation-corners .elementor-item:after{border-block-end-width:3px;border-block-start-width:0;border-inline-end-width:3px;border-inline-start-width:0;content:"";inset-block-end:0;inset-block-start:auto;inset-inline-end:0;inset-inline-start:auto}.e--pointer-framed.e--animation-corners .elementor-item-active:after,.e--pointer-framed.e--animation-corners .elementor-item-active:before,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:after,.e--pointer-framed.e--animation-corners .elementor-item.highlighted:before,.e--pointer-framed.e--animation-corners .elementor-item:focus:after,.e--pointer-framed.e--animation-corners .elementor-item:focus:before,.e--pointer-framed.e--animation-corners .elementor-item:hover:after,.e--pointer-framed.e--animation-corners .elementor-item:hover:before{height:100%;transition:opacity 2ms,width .4s,height .4s;width:100%}.e--pointer-framed.e--animation-none,.e--pointer-framed.e--animation-none .elementor-item,.e--pointer-framed.e--animation-none .elementor-item:after,.e--pointer-framed.e--animation-none .elementor-item:before,.e--pointer-framed.e--animation-none .elementor-item:focus,.e--pointer-framed.e--animation-none .elementor-item:hover,.e--pointer-framed.e--animation-none:after,.e--pointer-framed.e--animation-none:before,.e--pointer-framed.e--animation-none:focus,.e--pointer-framed.e--animation-none:hover{transition-duration:0s}.e--pointer-background .elementor-item:after,.e--pointer-background .elementor-item:before{content:"";transition:.3s}.e--pointer-background .elementor-item:before{background:#3f444b;inset:0;z-index:-1}.e--pointer-background .elementor-item-active,.e--pointer-background .elementor-item.highlighted,.e--pointer-background .elementor-item:focus,.e--pointer-background .elementor-item:hover{color:#fff}.e--pointer-background.e--animation-grow .elementor-item:before{transform:scale(.5)}.e--pointer-background.e--animation-grow .elementor-item-active:before,.e--pointer-background.e--animation-grow .elementor-item.highlighted:before,.e--pointer-background.e--animation-grow .elementor-item:focus:before,.e--pointer-background.e--animation-grow .elementor-item:hover:before{opacity:1;transform:scale(1)}.e--pointer-background.e--animation-shrink .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{transform:scale(1.2);transition:.3s}.e--pointer-background.e--animation-shrink .elementor-item-active:before,.e--pointer-background.e--animation-shrink .elementor-item.highlighted:before,.e--pointer-background.e--animation-shrink .elementor-item:focus:before,.e--pointer-background.e--animation-shrink .elementor-item:hover:before{transition:opacity .15s,transform .4s}.e--pointer-background.e--animation-sweep-left .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:100%}.e--pointer-background.e--animation-sweep-right .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{right:100%}.e--pointer-background.e--animation-sweep-up .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{top:100%}.e--pointer-background.e--animation-sweep-down .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:100%}.e--pointer-background.e--animation-shutter-out-vertical .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{bottom:50%;top:50%}.e--pointer-background.e--animation-shutter-out-horizontal .elementor-item:not(:hover):not(:focus):not(.elementor-item-active):not(.highlighted):before{left:50%;right:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{background:#3f444b;inset:0;z-index:-1}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:before{bottom:100%;top:0}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:after{bottom:0;top:100%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:before{bottom:50%}.e--pointer-background.e--animation-shutter-in-vertical .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-vertical .elementor-item:hover:after{top:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:before{left:100%;right:0}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:after{left:0;right:100%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:before,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:before{left:50%}.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item-active:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item.highlighted:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:focus:after,.e--pointer-background.e--animation-shutter-in-horizontal .elementor-item:hover:after{right:50%}.e--pointer-background.e--animation-none,.e--pointer-background.e--animation-none .elementor-item,.e--pointer-background.e--animation-none .elementor-item:after,.e--pointer-background.e--animation-none .elementor-item:before,.e--pointer-background.e--animation-none .elementor-item:focus,.e--pointer-background.e--animation-none .elementor-item:hover,.e--pointer-background.e--animation-none:after,.e--pointer-background.e--animation-none:before,.e--pointer-background.e--animation-none:focus,.e--pointer-background.e--animation-none:hover{transition-duration:0s}.e--pointer-text.e--animation-skew .elementor-item:focus,.e--pointer-text.e--animation-skew .elementor-item:hover{transform:skew(-8deg)}.e--pointer-text.e--animation-grow .elementor-item:focus,.e--pointer-text.e--animation-grow .elementor-item:hover{transform:scale(1.2)}.e--pointer-text.e--animation-shrink .elementor-item:focus,.e--pointer-text.e--animation-shrink .elementor-item:hover{transform:scale(.8)}.e--pointer-text.e--animation-float .elementor-item:focus,.e--pointer-text.e--animation-float .elementor-item:hover{transform:translateY(-8px)}.e--pointer-text.e--animation-sink .elementor-item:focus,.e--pointer-text.e--animation-sink .elementor-item:hover{transform:translateY(8px)}.e--pointer-text.e--animation-rotate .elementor-item:focus,.e--pointer-text.e--animation-rotate .elementor-item:hover{transform:rotate(6deg)}.e--pointer-text.e--animation-none,.e--pointer-text.e--animation-none .elementor-item,.e--pointer-text.e--animation-none .elementor-item:after,.e--pointer-text.e--animation-none .elementor-item:before,.e--pointer-text.e--animation-none .elementor-item:focus,.e--pointer-text.e--animation-none .elementor-item:hover,.e--pointer-text.e--animation-none:after,.e--pointer-text.e--animation-none:before,.e--pointer-text.e--animation-none:focus,.e--pointer-text.e--animation-none:hover{transition-duration:0s}.elementor-nav-menu--main .elementor-nav-menu a{transition:.4s}.elementor-nav-menu--main .elementor-nav-menu a,.elementor-nav-menu--main .elementor-nav-menu a.highlighted,.elementor-nav-menu--main .elementor-nav-menu a:focus,.elementor-nav-menu--main .elementor-nav-menu a:hover{padding:13px 20px}.elementor-nav-menu--main .elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu--main .elementor-nav-menu a.disabled{background:#3f444b;color:#88909b}.elementor-nav-menu--main .elementor-nav-menu ul{border-style:solid;border-width:0;padding:0;position:absolute;width:12em}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up{background:#fff;display:none;height:20px;overflow:hidden;position:absolute;visibility:hidden}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow,.elementor-nav-menu--main .elementor-nav-menu span.scroll-up-arrow{border:8px dashed transparent;border-bottom:8px solid #33373d;height:0;inset-block-start:-2px;inset-inline-start:50%;margin-inline-start:-8px;overflow:hidden;position:absolute;width:0}.elementor-nav-menu--main .elementor-nav-menu span.scroll-down-arrow{border-color:#33373d transparent transparent;border-style:solid dashed dashed;top:6px}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg,.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow i{transform:rotate(calc(-90deg * var(--direction-multiplier, 1)))}.elementor-nav-menu--main .elementor-nav-menu--dropdown .sub-arrow .e-font-icon-svg{fill:currentColor;height:1em;width:1em}.elementor-nav-menu--layout-horizontal{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu{display:flex;flex-wrap:wrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu a{flex-grow:1;white-space:nowrap}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{display:flex}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li ul,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>.scroll-down{top:100%!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>a{margin-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-down,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>.scroll-up,.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:first-child)>ul{inset-inline-start:var(--e-nav-menu-horizontal-menu-item-margin)!important}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child)>a{margin-inline-end:var(--e-nav-menu-horizontal-menu-item-margin)}.elementor-nav-menu--layout-horizontal .elementor-nav-menu>li:not(:last-child):after{align-self:center;border-color:var(--e-nav-menu-divider-color,#000);border-left-style:var(--e-nav-menu-divider-style,solid);border-left-width:var(--e-nav-menu-divider-width,2px);content:var(--e-nav-menu-divider-content,none);height:var(--e-nav-menu-divider-height,35%)}.elementor-nav-menu__align-right .elementor-nav-menu{justify-content:flex-end;margin-left:auto}.elementor-nav-menu__align-right .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-left .elementor-nav-menu{justify-content:flex-start;margin-right:auto}.elementor-nav-menu__align-left .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-start .elementor-nav-menu{justify-content:flex-start;margin-inline-end:auto}.elementor-nav-menu__align-start .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-start}.elementor-nav-menu__align-end .elementor-nav-menu{justify-content:flex-end;margin-inline-start:auto}.elementor-nav-menu__align-end .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:flex-end}.elementor-nav-menu__align-center .elementor-nav-menu{justify-content:center;margin-inline-end:auto;margin-inline-start:auto}.elementor-nav-menu__align-center .elementor-nav-menu--layout-vertical>ul>li>a{justify-content:center}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu{width:100%}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li{flex-grow:1}.elementor-nav-menu__align-justify .elementor-nav-menu--layout-horizontal .elementor-nav-menu>li>a{justify-content:center}.elementor-widget-nav-menu:not(.elementor-nav-menu--toggle) .elementor-menu-toggle{display:none}.elementor-widget-nav-menu .elementor-widget-container,.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*=elementor-hidden-]){display:flex;flex-direction:column}.elementor-nav-menu{position:relative;z-index:2}.elementor-nav-menu:after{clear:both;content:" ";display:block;font:0/0 serif;height:0;overflow:hidden;visibility:hidden}.elementor-nav-menu,.elementor-nav-menu li,.elementor-nav-menu ul{display:block;line-height:normal;list-style:none;margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.elementor-nav-menu ul{display:none}.elementor-nav-menu ul ul a,.elementor-nav-menu ul ul a:active,.elementor-nav-menu ul ul a:focus,.elementor-nav-menu ul ul a:hover{border-left:16px solid transparent}.elementor-nav-menu ul ul ul a,.elementor-nav-menu ul ul ul a:active,.elementor-nav-menu ul ul ul a:focus,.elementor-nav-menu ul ul ul a:hover{border-left:24px solid transparent}.elementor-nav-menu ul ul ul ul a,.elementor-nav-menu ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul a:hover{border-left:32px solid transparent}.elementor-nav-menu ul ul ul ul ul a,.elementor-nav-menu ul ul ul ul ul a:active,.elementor-nav-menu ul ul ul ul ul a:focus,.elementor-nav-menu ul ul ul ul ul a:hover{border-left:40px solid transparent}.elementor-nav-menu a,.elementor-nav-menu li{position:relative}.elementor-nav-menu li{border-width:0}.elementor-nav-menu a{align-items:center;display:flex}.elementor-nav-menu a,.elementor-nav-menu a:focus,.elementor-nav-menu a:hover{line-height:20px;padding:10px 20px}.elementor-nav-menu a.current{background:#1f2124;color:#fff}.elementor-nav-menu a.disabled{color:#88909b;cursor:not-allowed}.elementor-nav-menu .e-plus-icon:before{content:"+"}.elementor-nav-menu .sub-arrow{align-items:center;display:flex;line-height:1;margin-block-end:-10px;margin-block-start:-10px;padding:10px;padding-inline-end:0}.elementor-nav-menu .sub-arrow i{pointer-events:none}.elementor-nav-menu .sub-arrow .fa.fa-chevron-down,.elementor-nav-menu .sub-arrow .fas.fa-chevron-down{font-size:.7em}.elementor-nav-menu .sub-arrow .e-font-icon-svg{height:1em;width:1em}.elementor-nav-menu .sub-arrow .e-font-icon-svg.fa-svg-chevron-down{height:.7em;width:.7em}.elementor-nav-menu--dropdown .elementor-item.elementor-item-active,.elementor-nav-menu--dropdown .elementor-item.highlighted,.elementor-nav-menu--dropdown .elementor-item:focus,.elementor-nav-menu--dropdown .elementor-item:hover,.elementor-sub-item.elementor-item-active,.elementor-sub-item.highlighted,.elementor-sub-item:focus,.elementor-sub-item:hover{background-color:#3f444b;color:#fff}.elementor-menu-toggle{align-items:center;background-color:rgba(0,0,0,.05);border:0 solid;border-radius:3px;color:#33373d;cursor:pointer;display:flex;font-size:var(--nav-menu-icon-size,22px);justify-content:center;padding:.25em}.elementor-menu-toggle.elementor-active .elementor-menu-toggle__icon--open,.elementor-menu-toggle:not(.elementor-active) .elementor-menu-toggle__icon--close{display:none}.elementor-menu-toggle .e-font-icon-svg{fill:#33373d;height:1em;width:1em}.elementor-menu-toggle svg{height:auto;width:1em;fill:var(--nav-menu-icon-color,currentColor)}span.elementor-menu-toggle__icon--close,span.elementor-menu-toggle__icon--open{line-height:1}.elementor-nav-menu--dropdown{background-color:#fff;font-size:13px}.elementor-nav-menu--dropdown-none .elementor-menu-toggle,.elementor-nav-menu--dropdown-none .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown.elementor-nav-menu__container{margin-top:10px;overflow-x:hidden;overflow-y:auto;transform-origin:top;transition:max-height .3s,transform .3s}.elementor-nav-menu--dropdown.elementor-nav-menu__container .elementor-sub-item{font-size:.85em}.elementor-nav-menu--dropdown a{color:#33373d}.elementor-nav-menu--dropdown a.current{background:#1f2124;color:#fff}.elementor-nav-menu--dropdown a.disabled{color:#b3b3b3}ul.elementor-nav-menu--dropdown a,ul.elementor-nav-menu--dropdown a:focus,ul.elementor-nav-menu--dropdown a:hover{border-inline-start:8px solid transparent;text-shadow:none}.elementor-nav-menu__text-align-center .elementor-nav-menu--dropdown .elementor-nav-menu a{justify-content:center}.elementor-nav-menu--toggle{--menu-height:100vh}.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{max-height:0;overflow:hidden;transform:scaleY(0)}.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{animation:hide-scroll .3s backwards;max-height:var(--menu-height);transform:scaleY(1)}.elementor-nav-menu--stretch .elementor-nav-menu__container.elementor-nav-menu--dropdown{position:absolute;z-index:9997}@media (max-width:767px){.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--main{display:none}}@media (min-width:768px){.elementor-nav-menu--dropdown-mobile .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-mobile_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-mobile_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:1024px){.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--main{display:none}}@media (min-width:1025px){.elementor-nav-menu--dropdown-tablet .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@media (max-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--main{display:none}}@media (min-width:-1){.elementor-nav-menu--dropdown-tablet_extra .elementor-menu-toggle,.elementor-nav-menu--dropdown-tablet_extra .elementor-nav-menu--dropdown{display:none}.elementor-nav-menu--dropdown-tablet_extra nav.elementor-nav-menu--dropdown.elementor-nav-menu__container{overflow-y:hidden}}@keyframes hide-scroll{0%,to{overflow:hidden}} \ No newline at end of file diff --git a/assets/css/widget-nested-carousel-rtl.min.css b/assets/css/widget-nested-carousel-rtl.min.css new file mode 100644 index 00000000..533e6e43 --- /dev/null +++ b/assets/css/widget-nested-carousel-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-n-carousel{--e-n-carousel-slides-to-show:3;--e-n-carousel-swiper-slides-gap:10px;--e-n-carousel-swiper-slides-to-display:3;--e-n-carousel-swiper-pagination-size:0;--e-n-carousel-swiper-pagination-spacing:10px;--e-n-carousel-swiper-offset-size:0;height:-moz-fit-content;height:fit-content;--e-n-carousel-arrow-prev-top-align:50%;--e-n-carousel-arrow-prev-top-position:0px;--e-n-carousel-arrow-prev-caption-spacing:15px;--e-n-carousel-arrow-next-top-align:50%;--e-n-carousel-arrow-next-top-position:0px;--e-n-carousel-arrow-next-caption-spacing:15px;--e-n-carousel-arrow-prev-left-align:0px;--e-n-carousel-arrow-prev-left-position:0px;--e-n-carousel-arrow-next-right-align:0px;--e-n-carousel-arrow-next-right-position:0px;--e-n-carousel-arrow-next-translate-x:0px;--e-n-carousel-arrow-next-translate-y:0px;--e-n-carousel-arrow-prev-translate-x:0px;--e-n-carousel-arrow-prev-translate-y:0px;--e-n-carousel-swiper-padding-bottom:calc(var(--e-n-carousel-swiper-pagination-size) + var(--e-n-carousel-swiper-pagination-spacing));--e-n-carousel-dots-vertical-position:100%;--e-n-carousel-dots-vertical-offset:0px;--e-n-carousel-dots-horizontal-position:50%;--e-n-carousel-dots-horizontal-offset:0px;--e-n-carousel-dots-horizontal-transform:-50%;--e-n-carousel-dots-vertical-transform:-100%;--e-n-carousel-fraction-vertical-position:100%;--e-n-carousel-fraction-vertical-offset:0px;--e-n-carousel-fraction-horizontal-position:50%;--e-n-carousel-fraction-horizontal-offset:0px;--e-n-carousel-fraction-horizontal-transform:-50%;--e-n-carousel-fraction-vertical-transform:-100%}.elementor-widget-n-carousel .e-n-carousel{display:flex;min-width:0}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide-active.elementor-edit-area-active{overflow:initial}.elementor-widget-n-carousel .e-n-carousel.offset-left{padding-inline-start:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel.offset-both,.elementor-widget-n-carousel .e-n-carousel.offset-right{padding-inline-end:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel.offset-both{padding-inline-start:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper .swiper-slide a.e-con{display:var(--display)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide{flex-shrink:0;height:var(--e-n-carousel-slide-height,initial)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide>.e-con{height:var(--e-n-carousel-slide-container-height,initial);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev{border-style:var(--e-n-carousel-arrow-normal-border-type);color:var(--e-n-carousel-arrow-normal-color,hsla(0,0%,93%,.9));font-size:var(--e-n-carousel-arrow-size,25px);transition-duration:.25s;z-index:2}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next svg,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev svg{fill:var(--e-n-carousel-arrow-normal-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next:hover,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover{border-style:var(--e-n-carousel-arrow-hover-border-type);color:var(--e-n-carousel-arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next:hover svg,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover svg{fill:var(--e-n-carousel-arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-next{right:calc(var(--e-n-carousel-arrow-next-right-align) + var(--e-n-carousel-arrow-next-right-position));top:calc(var(--e-n-carousel-arrow-next-top-align) + var(--e-n-carousel-arrow-next-top-position) - var(--e-n-carousel-arrow-next-caption-spacing));transform:translate(var(--e-n-carousel-arrow-next-translate-x),var(--e-n-carousel-arrow-next-translate-y))}.elementor-widget-n-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-prev{left:calc(var(--e-n-carousel-arrow-prev-left-align) + var(--e-n-carousel-arrow-prev-left-position));top:calc(var(--e-n-carousel-arrow-prev-top-align) + var(--e-n-carousel-arrow-prev-top-position) - var(--e-n-carousel-arrow-prev-caption-spacing));transform:translate(var(--e-n-carousel-arrow-prev-translate-x),var(--e-n-carousel-arrow-prev-translate-y))}.elementor-widget-n-carousel.elementor-pagination-type-bullets{--e-n-carousel-swiper-pagination-size:6px}.elementor-widget-n-carousel.elementor-pagination-type-fraction{--e-n-carousel-swiper-pagination-size:16px}.elementor-widget-n-carousel.elementor-pagination-type-progressbar{--e-n-carousel-swiper-pagination-size:4px}.elementor-widget-n-carousel .swiper-pagination-progressbar{height:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--e-n-carousel-progressbar-normal-color,#000)}.elementor-widget-n-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill:hover{background:var(--e-n-carousel-progressbar-hover-color,#000)}.elementor-widget-n-carousel .swiper-pagination-fraction{color:var(--e-n-carousel-fraction-color,#000)}.elementor-widget-n-carousel .swiper-pagination-bullet{background:var(--e-n-carousel-dots-normal-color,#000);height:var(--e-n-carousel-swiper-pagination-size);width:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel .swiper-pagination-bullet:hover{background:var(--e-n-carousel-dots-hover-color,#000);opacity:1}.elementor-widget-n-carousel .swiper-horizontal>.swiper-pagination-bullets,.elementor-widget-n-carousel .swiper-pagination,.elementor-widget-n-carousel .swiper-pagination-bullets.swiper-pagination-horizontal,.elementor-widget-n-carousel .swiper-pagination-custom,.elementor-widget-n-carousel .swiper-pagination-fraction{font-size:var(--e-n-carousel-swiper-pagination-size);line-height:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper,.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container{padding-bottom:var(--e-n-carousel-swiper-padding-bottom)}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container .elementor-background-slideshow{padding-bottom:0}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container)) .swiper-pagination-bullet,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container .swiper-pagination-bullet{vertical-align:top}.elementor-widget-n-carousel .swiper-pagination-bullets{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--e-n-carousel-dots-horizontal-position) + var(--e-n-carousel-dots-horizontal-offset));top:calc(var(--e-n-carousel-dots-vertical-position) + var(--e-n-carousel-dots-vertical-offset));transform:translate(calc(var(--e-n-carousel-dots-horizontal-transform) * var(--direction-multiplier, 1)),var(--e-n-carousel-dots-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.elementor-widget-n-carousel .swiper-pagination-fraction{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--e-n-carousel-fraction-horizontal-position) + var(--e-n-carousel-fraction-horizontal-offset));top:calc(var(--e-n-carousel-fraction-vertical-position) + var(--e-n-carousel-fraction-vertical-offset));transform:translate(calc(var(--e-n-carousel-fraction-horizontal-transform) * var(--direction-multiplier, 1)),var(--e-n-carousel-fraction-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.swiper-container:not(.swiper-container-initialized)>.swiper-wrapper,.swiper:not(.swiper-initialized)>.swiper-wrapper{gap:var(--e-n-carousel-swiper-slides-gap);overflow:hidden}.swiper-container:not(.swiper-container-initialized)>.swiper-wrapper>.swiper--slide,.swiper:not(.swiper-initialized)>.swiper-wrapper>.swiper--slide{--e-n-carousel-number-of-gaps:max(calc(var(--e-n-carousel-swiper-slides-to-display) - 1),0);--e-n-carousel-gaps-width-total:calc(var(--e-n-carousel-number-of-gaps) * var(--e-n-carousel-swiper-slides-gap));max-width:calc((100% - var(--e-n-carousel-gaps-width-total)) / var(--e-n-carousel-swiper-slides-to-display, 1))}[data-core-v316-plus=true] .elementor-widget-n-carousel .e-n-carousel .swiper-slide>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/widget-nested-carousel.min.css b/assets/css/widget-nested-carousel.min.css new file mode 100644 index 00000000..533e6e43 --- /dev/null +++ b/assets/css/widget-nested-carousel.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-n-carousel{--e-n-carousel-slides-to-show:3;--e-n-carousel-swiper-slides-gap:10px;--e-n-carousel-swiper-slides-to-display:3;--e-n-carousel-swiper-pagination-size:0;--e-n-carousel-swiper-pagination-spacing:10px;--e-n-carousel-swiper-offset-size:0;height:-moz-fit-content;height:fit-content;--e-n-carousel-arrow-prev-top-align:50%;--e-n-carousel-arrow-prev-top-position:0px;--e-n-carousel-arrow-prev-caption-spacing:15px;--e-n-carousel-arrow-next-top-align:50%;--e-n-carousel-arrow-next-top-position:0px;--e-n-carousel-arrow-next-caption-spacing:15px;--e-n-carousel-arrow-prev-left-align:0px;--e-n-carousel-arrow-prev-left-position:0px;--e-n-carousel-arrow-next-right-align:0px;--e-n-carousel-arrow-next-right-position:0px;--e-n-carousel-arrow-next-translate-x:0px;--e-n-carousel-arrow-next-translate-y:0px;--e-n-carousel-arrow-prev-translate-x:0px;--e-n-carousel-arrow-prev-translate-y:0px;--e-n-carousel-swiper-padding-bottom:calc(var(--e-n-carousel-swiper-pagination-size) + var(--e-n-carousel-swiper-pagination-spacing));--e-n-carousel-dots-vertical-position:100%;--e-n-carousel-dots-vertical-offset:0px;--e-n-carousel-dots-horizontal-position:50%;--e-n-carousel-dots-horizontal-offset:0px;--e-n-carousel-dots-horizontal-transform:-50%;--e-n-carousel-dots-vertical-transform:-100%;--e-n-carousel-fraction-vertical-position:100%;--e-n-carousel-fraction-vertical-offset:0px;--e-n-carousel-fraction-horizontal-position:50%;--e-n-carousel-fraction-horizontal-offset:0px;--e-n-carousel-fraction-horizontal-transform:-50%;--e-n-carousel-fraction-vertical-transform:-100%}.elementor-widget-n-carousel .e-n-carousel{display:flex;min-width:0}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide-active.elementor-edit-area-active{overflow:initial}.elementor-widget-n-carousel .e-n-carousel.offset-left{padding-inline-start:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel.offset-both,.elementor-widget-n-carousel .e-n-carousel.offset-right{padding-inline-end:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel.offset-both{padding-inline-start:var(--e-n-carousel-swiper-offset-size,0)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper .swiper-slide a.e-con{display:var(--display)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide{flex-shrink:0;height:var(--e-n-carousel-slide-height,initial)}.elementor-widget-n-carousel .e-n-carousel>.swiper-wrapper>.swiper-slide>.e-con{height:var(--e-n-carousel-slide-container-height,initial);max-width:calc(100% - var(--margin-inline-start, var(--margin-left)) - var(--margin-inline-end, var(--margin-right)))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev{border-style:var(--e-n-carousel-arrow-normal-border-type);color:var(--e-n-carousel-arrow-normal-color,hsla(0,0%,93%,.9));font-size:var(--e-n-carousel-arrow-size,25px);transition-duration:.25s;z-index:2}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next svg,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev svg{fill:var(--e-n-carousel-arrow-normal-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next:hover,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover{border-style:var(--e-n-carousel-arrow-hover-border-type);color:var(--e-n-carousel-arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-next:hover svg,.elementor-widget-n-carousel .elementor-swiper-button.elementor-swiper-button-prev:hover svg{fill:var(--e-n-carousel-arrow-hover-color,hsla(0,0%,93%,.9))}.elementor-widget-n-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-next{right:calc(var(--e-n-carousel-arrow-next-right-align) + var(--e-n-carousel-arrow-next-right-position));top:calc(var(--e-n-carousel-arrow-next-top-align) + var(--e-n-carousel-arrow-next-top-position) - var(--e-n-carousel-arrow-next-caption-spacing));transform:translate(var(--e-n-carousel-arrow-next-translate-x),var(--e-n-carousel-arrow-next-translate-y))}.elementor-widget-n-carousel.elementor-element :is(.swiper,.swiper-container)~.elementor-swiper-button-prev{left:calc(var(--e-n-carousel-arrow-prev-left-align) + var(--e-n-carousel-arrow-prev-left-position));top:calc(var(--e-n-carousel-arrow-prev-top-align) + var(--e-n-carousel-arrow-prev-top-position) - var(--e-n-carousel-arrow-prev-caption-spacing));transform:translate(var(--e-n-carousel-arrow-prev-translate-x),var(--e-n-carousel-arrow-prev-translate-y))}.elementor-widget-n-carousel.elementor-pagination-type-bullets{--e-n-carousel-swiper-pagination-size:6px}.elementor-widget-n-carousel.elementor-pagination-type-fraction{--e-n-carousel-swiper-pagination-size:16px}.elementor-widget-n-carousel.elementor-pagination-type-progressbar{--e-n-carousel-swiper-pagination-size:4px}.elementor-widget-n-carousel .swiper-pagination-progressbar{height:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--e-n-carousel-progressbar-normal-color,#000)}.elementor-widget-n-carousel .swiper-pagination-progressbar .swiper-pagination-progressbar-fill:hover{background:var(--e-n-carousel-progressbar-hover-color,#000)}.elementor-widget-n-carousel .swiper-pagination-fraction{color:var(--e-n-carousel-fraction-color,#000)}.elementor-widget-n-carousel .swiper-pagination-bullet{background:var(--e-n-carousel-dots-normal-color,#000);height:var(--e-n-carousel-swiper-pagination-size);width:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel .swiper-pagination-bullet:hover{background:var(--e-n-carousel-dots-hover-color,#000);opacity:1}.elementor-widget-n-carousel .swiper-horizontal>.swiper-pagination-bullets,.elementor-widget-n-carousel .swiper-pagination,.elementor-widget-n-carousel .swiper-pagination-bullets.swiper-pagination-horizontal,.elementor-widget-n-carousel .swiper-pagination-custom,.elementor-widget-n-carousel .swiper-pagination-fraction{font-size:var(--e-n-carousel-swiper-pagination-size);line-height:var(--e-n-carousel-swiper-pagination-size)}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper,.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container{padding-bottom:var(--e-n-carousel-swiper-padding-bottom)}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container))>.swiper-container .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper .elementor-background-slideshow,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container>.swiper-container .elementor-background-slideshow{padding-bottom:0}.elementor-widget-n-carousel.elementor-pagination-position-outside:not(:has(>.elementor-widget-container)) .swiper-pagination-bullet,.elementor-widget-n-carousel.elementor-pagination-position-outside>.elementor-widget-container .swiper-pagination-bullet{vertical-align:top}.elementor-widget-n-carousel .swiper-pagination-bullets{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--e-n-carousel-dots-horizontal-position) + var(--e-n-carousel-dots-horizontal-offset));top:calc(var(--e-n-carousel-dots-vertical-position) + var(--e-n-carousel-dots-vertical-offset));transform:translate(calc(var(--e-n-carousel-dots-horizontal-transform) * var(--direction-multiplier, 1)),var(--e-n-carousel-dots-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.elementor-widget-n-carousel .swiper-pagination-fraction{height:-moz-max-content;height:max-content;inset-inline-start:calc(var(--e-n-carousel-fraction-horizontal-position) + var(--e-n-carousel-fraction-horizontal-offset));top:calc(var(--e-n-carousel-fraction-vertical-position) + var(--e-n-carousel-fraction-vertical-offset));transform:translate(calc(var(--e-n-carousel-fraction-horizontal-transform) * var(--direction-multiplier, 1)),var(--e-n-carousel-fraction-vertical-transform));width:-moz-max-content;width:max-content;z-index:3}.swiper-container:not(.swiper-container-initialized)>.swiper-wrapper,.swiper:not(.swiper-initialized)>.swiper-wrapper{gap:var(--e-n-carousel-swiper-slides-gap);overflow:hidden}.swiper-container:not(.swiper-container-initialized)>.swiper-wrapper>.swiper--slide,.swiper:not(.swiper-initialized)>.swiper-wrapper>.swiper--slide{--e-n-carousel-number-of-gaps:max(calc(var(--e-n-carousel-swiper-slides-to-display) - 1),0);--e-n-carousel-gaps-width-total:calc(var(--e-n-carousel-number-of-gaps) * var(--e-n-carousel-swiper-slides-gap));max-width:calc((100% - var(--e-n-carousel-gaps-width-total)) / var(--e-n-carousel-swiper-slides-to-display, 1))}[data-core-v316-plus=true] .elementor-widget-n-carousel .e-n-carousel .swiper-slide>.e-con{--padding-top:initial;--padding-right:initial;--padding-bottom:initial;--padding-left:initial} \ No newline at end of file diff --git a/assets/css/widget-off-canvas-rtl.min.css b/assets/css/widget-off-canvas-rtl.min.css new file mode 100644 index 00000000..020d9e69 --- /dev/null +++ b/assets/css/widget-off-canvas-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +body.e-off-canvas__no-scroll,body.e-off-canvas__no-scroll-animation{overflow:hidden}.elementor-widget-off-canvas{height:-moz-fit-content;height:fit-content;--e-off-canvas-width:400px;--e-off-canvas-height:100vh;--e-off-canvas-justify-content:flex-start;--e-off-canvas-align-items:flex-start;--e-off-canvas-animation-duration:1.5s;--e-off-canvas-content-overflow:auto;--e-off-canvas-overlay-opacity:1;--e-off-canvas-animation-duration-minimum:Max(0.001s,var(--e-off-canvas-animation-duration))}.elementor-widget-off-canvas .e-off-canvas{height:100%;left:0;pointer-events:none;position:fixed;top:0;width:100%;z-index:2147483630}.elementor-widget-off-canvas .e-off-canvas[aria-hidden=true]{opacity:0;visibility:hidden}.elementor-widget-off-canvas .e-off-canvas[aria-hidden=true] .elementor-add-section{display:none}.elementor-widget-off-canvas .e-off-canvas__overlay{background-color:rgba(0,0,0,.5);height:100%;left:0;opacity:var(--e-off-canvas-overlay-opacity);pointer-events:all;position:absolute;top:0;transition:0s;width:100%}.elementor-widget-off-canvas .e-off-canvas__main{align-items:var(--e-off-canvas-align-items);display:flex;height:100%;justify-content:var(--e-off-canvas-justify-content);left:0;position:absolute;top:0;width:100%}.elementor-widget-off-canvas .e-off-canvas__main.animated{animation-duration:var(--e-off-canvas-animation-duration-minimum)}.elementor-widget-off-canvas .e-off-canvas__main.animated.none{animation:e-off-canvas-without-animation 1ms;opacity:1;visibility:visible}.elementor-widget-off-canvas .e-off-canvas__main.animated.none.reversed{opacity:0;visibility:hidden}.elementor-widget-off-canvas .e-off-canvas__content{background-color:#fff;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);height:var(--e-off-canvas-height);overflow:var(--e-off-canvas-content-overflow);pointer-events:all;width:var(--e-off-canvas-width)}.elementor-widget-off-canvas .animated-reverse-wrapper{opacity:0;transform:none;visibility:hidden}.elementor-widget-off-canvas .animated-reverse-wrapper:not(.no-animation){animation:e-off-canvas-close var(--e-off-canvas-animation-duration-minimum)}.elementor-widget-off-canvas .animated-reverse-wrapper .no-animation{animation:e-off-canvas-close 1ms}body:not(.elementor-editor-active) .e-con .elementor-widget-off-canvas{position:absolute}body:not(.elementor-editor-active) .elementor-section .e-element-before-off-canvas:has(>.elementor-widget-container),body:not(.elementor-editor-active) .elementor-section .elementor-element:has(>.elementor-widget-container+.elementor-widget-off-canvas){margin-block-end:0}body:not(.elementor-editor-active) .elementor-section .e-element-before-off-canvas,body:not(.elementor-editor-active) .elementor-section .elementor-element:has(+.elementor-widget-off-canvas){--kit-widget-spacing:0px}body:not(.elementor-editor-active) .elementor-section .elementor-widget-off-canvas:first-child{position:absolute}@keyframes e-off-canvas-close{0%,99.99%{opacity:1;visibility:visible}to{opacity:0;transform:none;visibility:hidden}}@keyframes e-off-canvas-without-animation{0%{opacity:0;visibility:hidden}to{opacity:1;visibility:visible}} \ No newline at end of file diff --git a/assets/css/widget-off-canvas.min.css b/assets/css/widget-off-canvas.min.css new file mode 100644 index 00000000..020d9e69 --- /dev/null +++ b/assets/css/widget-off-canvas.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +body.e-off-canvas__no-scroll,body.e-off-canvas__no-scroll-animation{overflow:hidden}.elementor-widget-off-canvas{height:-moz-fit-content;height:fit-content;--e-off-canvas-width:400px;--e-off-canvas-height:100vh;--e-off-canvas-justify-content:flex-start;--e-off-canvas-align-items:flex-start;--e-off-canvas-animation-duration:1.5s;--e-off-canvas-content-overflow:auto;--e-off-canvas-overlay-opacity:1;--e-off-canvas-animation-duration-minimum:Max(0.001s,var(--e-off-canvas-animation-duration))}.elementor-widget-off-canvas .e-off-canvas{height:100%;left:0;pointer-events:none;position:fixed;top:0;width:100%;z-index:2147483630}.elementor-widget-off-canvas .e-off-canvas[aria-hidden=true]{opacity:0;visibility:hidden}.elementor-widget-off-canvas .e-off-canvas[aria-hidden=true] .elementor-add-section{display:none}.elementor-widget-off-canvas .e-off-canvas__overlay{background-color:rgba(0,0,0,.5);height:100%;left:0;opacity:var(--e-off-canvas-overlay-opacity);pointer-events:all;position:absolute;top:0;transition:0s;width:100%}.elementor-widget-off-canvas .e-off-canvas__main{align-items:var(--e-off-canvas-align-items);display:flex;height:100%;justify-content:var(--e-off-canvas-justify-content);left:0;position:absolute;top:0;width:100%}.elementor-widget-off-canvas .e-off-canvas__main.animated{animation-duration:var(--e-off-canvas-animation-duration-minimum)}.elementor-widget-off-canvas .e-off-canvas__main.animated.none{animation:e-off-canvas-without-animation 1ms;opacity:1;visibility:visible}.elementor-widget-off-canvas .e-off-canvas__main.animated.none.reversed{opacity:0;visibility:hidden}.elementor-widget-off-canvas .e-off-canvas__content{background-color:#fff;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);height:var(--e-off-canvas-height);overflow:var(--e-off-canvas-content-overflow);pointer-events:all;width:var(--e-off-canvas-width)}.elementor-widget-off-canvas .animated-reverse-wrapper{opacity:0;transform:none;visibility:hidden}.elementor-widget-off-canvas .animated-reverse-wrapper:not(.no-animation){animation:e-off-canvas-close var(--e-off-canvas-animation-duration-minimum)}.elementor-widget-off-canvas .animated-reverse-wrapper .no-animation{animation:e-off-canvas-close 1ms}body:not(.elementor-editor-active) .e-con .elementor-widget-off-canvas{position:absolute}body:not(.elementor-editor-active) .elementor-section .e-element-before-off-canvas:has(>.elementor-widget-container),body:not(.elementor-editor-active) .elementor-section .elementor-element:has(>.elementor-widget-container+.elementor-widget-off-canvas){margin-block-end:0}body:not(.elementor-editor-active) .elementor-section .e-element-before-off-canvas,body:not(.elementor-editor-active) .elementor-section .elementor-element:has(+.elementor-widget-off-canvas){--kit-widget-spacing:0px}body:not(.elementor-editor-active) .elementor-section .elementor-widget-off-canvas:first-child{position:absolute}@keyframes e-off-canvas-close{0%,99.99%{opacity:1;visibility:visible}to{opacity:0;transform:none;visibility:hidden}}@keyframes e-off-canvas-without-animation{0%{opacity:0;visibility:hidden}to{opacity:1;visibility:visible}} \ No newline at end of file diff --git a/assets/css/widget-post-info-rtl.min.css b/assets/css/widget-post-info-rtl.min.css new file mode 100644 index 00000000..0d708694 --- /dev/null +++ b/assets/css/widget-post-info-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-post-info__terms-list{display:inline-block}.elementor-post-info .elementor-icon-list-icon .elementor-avatar{border-radius:100%}.elementor-widget-post-info.elementor-align-center .elementor-icon-list-item:after{margin:initial}.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text{display:inline-block}.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text a,.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text span{display:inline} \ No newline at end of file diff --git a/assets/css/widget-post-info.min.css b/assets/css/widget-post-info.min.css new file mode 100644 index 00000000..0d708694 --- /dev/null +++ b/assets/css/widget-post-info.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-post-info__terms-list{display:inline-block}.elementor-post-info .elementor-icon-list-icon .elementor-avatar{border-radius:100%}.elementor-widget-post-info.elementor-align-center .elementor-icon-list-item:after{margin:initial}.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text{display:inline-block}.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text a,.elementor-icon-list-items .elementor-icon-list-item .elementor-icon-list-text span{display:inline} \ No newline at end of file diff --git a/assets/css/widget-post-navigation-rtl.min.css b/assets/css/widget-post-navigation-rtl.min.css new file mode 100644 index 00000000..9df7603d --- /dev/null +++ b/assets/css/widget-post-navigation-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-post-navigation-borders-yes .elementor-post-navigation.elementor-grid{border:1px solid;border-left:none;border-right:none;color:#d5d8dc;padding-bottom:10px;padding-top:10px}.elementor-post-navigation-borders-yes .elementor-post-navigation__separator{background-color:#d5d8dc;height:100%;margin:0 auto;width:1px}.elementor-post-navigation{display:flex;overflow:hidden}.elementor-post-navigation .post-navigation__arrow-wrapper{color:#d5d8dc;display:flex;fill:#d5d8dc}.elementor-post-navigation .post-navigation__arrow-wrapper.post-navigation__arrow-next,.elementor-post-navigation .post-navigation__arrow-wrapper.post-navigation__arrow-prev{font-size:30px}.elementor-post-navigation .post-navigation__arrow-wrapper i{transform:translateY(-5%)}.elementor-post-navigation .post-navigation__arrow-wrapper svg{height:auto;width:1em}.elementor-post-navigation .post-navigation__arrow-wrapper .e-font-icon-svg{height:1em}.elementor-post-navigation .elementor-post-navigation__link__next,.elementor-post-navigation .elementor-post-navigation__link__prev{overflow:hidden}.elementor-post-navigation .elementor-post-navigation__link a{align-items:center;display:flex;gap:15px;max-width:100%}.elementor-post-navigation .post-navigation__next--label,.elementor-post-navigation .post-navigation__prev--label{font-size:.8em;text-transform:uppercase}.elementor-post-navigation .post-navigation__next--title,.elementor-post-navigation .post-navigation__prev--title{font-size:.7em}.elementor-post-navigation .post-navigation__next--label,.elementor-post-navigation .post-navigation__next--title,.elementor-post-navigation .post-navigation__prev--label,.elementor-post-navigation .post-navigation__prev--title{overflow:hidden;text-overflow:ellipsis}.elementor-post-navigation span.elementor-post-navigation__link__next{text-align:end}.elementor-post-navigation span.elementor-post-navigation__link__next,.elementor-post-navigation span.elementor-post-navigation__link__prev{display:flex;flex-direction:column}.elementor-post-navigation .elementor-grid{justify-content:space-between}.elementor-post-navigation .elementor-post-navigation__link{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:calc(50% - .5px)}.elementor-post-navigation .elementor-post-navigation__separator-wrapper{text-align:center}.elementor-post-navigation .elementor-post-navigation__next{text-align:end}.elementor-post-navigation .elementor-post-navigation__next a{justify-content:flex-end} \ No newline at end of file diff --git a/assets/css/widget-post-navigation.min.css b/assets/css/widget-post-navigation.min.css new file mode 100644 index 00000000..9df7603d --- /dev/null +++ b/assets/css/widget-post-navigation.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-post-navigation-borders-yes .elementor-post-navigation.elementor-grid{border:1px solid;border-left:none;border-right:none;color:#d5d8dc;padding-bottom:10px;padding-top:10px}.elementor-post-navigation-borders-yes .elementor-post-navigation__separator{background-color:#d5d8dc;height:100%;margin:0 auto;width:1px}.elementor-post-navigation{display:flex;overflow:hidden}.elementor-post-navigation .post-navigation__arrow-wrapper{color:#d5d8dc;display:flex;fill:#d5d8dc}.elementor-post-navigation .post-navigation__arrow-wrapper.post-navigation__arrow-next,.elementor-post-navigation .post-navigation__arrow-wrapper.post-navigation__arrow-prev{font-size:30px}.elementor-post-navigation .post-navigation__arrow-wrapper i{transform:translateY(-5%)}.elementor-post-navigation .post-navigation__arrow-wrapper svg{height:auto;width:1em}.elementor-post-navigation .post-navigation__arrow-wrapper .e-font-icon-svg{height:1em}.elementor-post-navigation .elementor-post-navigation__link__next,.elementor-post-navigation .elementor-post-navigation__link__prev{overflow:hidden}.elementor-post-navigation .elementor-post-navigation__link a{align-items:center;display:flex;gap:15px;max-width:100%}.elementor-post-navigation .post-navigation__next--label,.elementor-post-navigation .post-navigation__prev--label{font-size:.8em;text-transform:uppercase}.elementor-post-navigation .post-navigation__next--title,.elementor-post-navigation .post-navigation__prev--title{font-size:.7em}.elementor-post-navigation .post-navigation__next--label,.elementor-post-navigation .post-navigation__next--title,.elementor-post-navigation .post-navigation__prev--label,.elementor-post-navigation .post-navigation__prev--title{overflow:hidden;text-overflow:ellipsis}.elementor-post-navigation span.elementor-post-navigation__link__next{text-align:end}.elementor-post-navigation span.elementor-post-navigation__link__next,.elementor-post-navigation span.elementor-post-navigation__link__prev{display:flex;flex-direction:column}.elementor-post-navigation .elementor-grid{justify-content:space-between}.elementor-post-navigation .elementor-post-navigation__link{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:calc(50% - .5px)}.elementor-post-navigation .elementor-post-navigation__separator-wrapper{text-align:center}.elementor-post-navigation .elementor-post-navigation__next{text-align:end}.elementor-post-navigation .elementor-post-navigation__next a{justify-content:flex-end} \ No newline at end of file diff --git a/assets/css/widget-posts-rtl.min.css b/assets/css/widget-posts-rtl.min.css new file mode 100644 index 00000000..0d78e21d --- /dev/null +++ b/assets/css/widget-posts-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.elementor-widget-archive-posts:after,.elementor-widget-posts:after{display:none}.elementor-post__thumbnail__link{transition:none}.elementor-posts-container.elementor-posts-masonry{align-items:flex-start}.elementor-posts-container:not(.elementor-posts-masonry){align-items:stretch}.elementor-posts-container .elementor-post{margin:0;padding:0}.elementor-posts-container .elementor-post__excerpt{flex-grow:var(--read-more-alignment,0)}.elementor-posts-container .elementor-post__thumbnail{overflow:hidden}.elementor-posts-container .elementor-post__thumbnail img{display:block;max-height:none;max-width:none;transition:filter .3s;width:100%}.elementor-posts-container .elementor-post__thumbnail__link{display:block;position:relative;width:100%}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail{inset:0}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail img{height:auto;left:calc(50% + 1px);position:absolute;top:calc(50% + 1px);transform:scale(1.01) translate(-50%,-50%)}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail.elementor-fit-height img{height:100%;width:auto}.elementor-posts .elementor-post{flex-direction:column;transition-duration:.25s;transition-property:background,border,box-shadow}.elementor-posts .elementor-post__title{font-size:18px;margin:0}.elementor-posts .elementor-post__excerpt{margin-bottom:10px}.elementor-posts .elementor-post__excerpt p{color:#777;font-size:14px;line-height:1.5em;margin:0}.elementor-posts .elementor-post__text{display:var(--item-display,block);flex-direction:column;flex-grow:1}.elementor-posts .elementor-post__meta-data{color:#adadad;font-size:12px;line-height:1.3em;margin-bottom:13px}.elementor-posts .elementor-post__read-more{align-self:flex-start;font-size:12px;font-weight:700}.elementor-posts .elementor-post__thumbnail{position:relative}.elementor-posts--skin-classic .elementor-post{overflow:hidden}.elementor-posts--align-left .elementor-post{text-align:left}.elementor-posts--align-right .elementor-post{text-align:right}.elementor-posts--align-center .elementor-post{text-align:center}.elementor-posts--thumbnail-top .elementor-post__thumbnail__link{margin-bottom:20px}.elementor-posts--thumbnail-top .elementor-post__text{width:100%}.elementor-posts--thumbnail-top.elementor-posts--align-left .elementor-post__thumbnail__link{margin-right:auto}.elementor-posts--thumbnail-top.elementor-posts--align-right .elementor-post__thumbnail__link{margin-left:auto}.elementor-posts--thumbnail-top.elementor-posts--align-center .elementor-post__thumbnail__link{margin-left:auto;margin-right:auto}.elementor-posts--thumbnail-left .elementor-post,.elementor-posts--thumbnail-right .elementor-post{flex-direction:row}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link,.elementor-posts--thumbnail-right .elementor-post__thumbnail__link{flex-shrink:0;width:25%}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link{margin-right:20px;order:5}.elementor-posts--thumbnail-right .elementor-post__thumbnail__link{margin-left:20px;order:0}.elementor-posts--thumbnail-none .elementor-posts-container .elementor-post__thumbnail__link{display:none}.elementor-posts .elementor-post{display:flex}.elementor-posts .elementor-post__card{background-color:#fff;border:0 solid #69727d;border-radius:3px;display:flex;flex-direction:column;min-height:100%;overflow:hidden;position:relative;transition:all .25s;width:100%}.elementor-posts .elementor-post__card .elementor-post__thumbnail{position:relative;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.elementor-posts .elementor-post__card .elementor-post__thumbnail img{width:calc(100% + 1px)}.elementor-posts .elementor-post__card .elementor-post__text{margin-bottom:0;margin-top:20px;padding:0 30px}.elementor-posts .elementor-post__card .elementor-post__read-more{display:inline-block;margin-bottom:20px}.elementor-posts .elementor-post__card .elementor-post__meta-data{border-top:1px solid #eaeaea;margin-bottom:0;padding:15px 30px}.elementor-posts .elementor-post__card .elementor-post__meta-data span+span:before{margin:0 5px}.elementor-posts .elementor-post__card .elementor-post__title{font-size:21px}.elementor-posts .elementor-post__card .elementor-post__excerpt{line-height:1.7}.elementor-posts .elementor-post__card .elementor-post__excerpt,.elementor-posts .elementor-post__card .elementor-post__title{margin-bottom:25px}.elementor-posts .elementor-post__card .elementor-post__badge,.elementor-posts .elementor-post__card .elementor-post__read-more{text-transform:uppercase}.elementor-posts .elementor-post__badge{background:#69727d;border-radius:999px;color:#fff;font-size:12px;font-weight:400;line-height:1;margin:20px;padding:.6em 1.2em;position:absolute;top:0}.elementor-posts .elementor-post__avatar{height:0;padding:0 30px;pointer-events:none;position:relative;top:-25px;width:100%}.elementor-posts .elementor-post__avatar img{border-radius:50%;pointer-events:all;transform:translateY(-50%);width:60px}.elementor-posts .elementor-posts--skin-cards:not(.elementor-posts-masonry) .elementor-post__meta-data,.elementor-posts--thumbnail-top .elementor-posts--skin-cards:not(.elementor-posts-masonry) .elementor-post__meta-data{margin-top:auto}.elementor-posts--thumbnail-none .elementor-post__card .elementor-post__avatar{height:auto;padding-top:0;position:static}.elementor-posts--thumbnail-none .elementor-post__card .elementor-post__avatar img.avatar{transform:translateY(0);vertical-align:bottom}.elementor-posts--show-avatar .elementor-post__thumbnail__link{margin-bottom:25px}.elementor-posts__hover-gradient .elementor-post__card .elementor-post__thumbnail__link:after{background-image:linear-gradient(0deg,rgba(0,0,0,.35),transparent 75%);background-repeat:no-repeat;bottom:0;content:"";display:block;height:100%;opacity:1;position:absolute;transition:all .3s ease-out;width:100%}.elementor-posts__hover-gradient .elementor-post__card:hover .elementor-post__thumbnail__link:after{opacity:.5}.elementor-posts__hover-zoom-in .elementor-post__card .elementor-post__thumbnail.elementor-fit-height img{height:100%}.elementor-posts__hover-zoom-in .elementor-post__card .elementor-post__thumbnail:not(.elementor-fit-height) img{width:calc(100% + 1px)}.elementor-posts__hover-zoom-in .elementor-post__card:hover .elementor-post__thumbnail.elementor-fit-height img{height:115%}.elementor-posts__hover-zoom-in .elementor-post__card:hover .elementor-post__thumbnail:not(.elementor-fit-height) img{width:115%}.elementor-posts__hover-zoom-out .elementor-post__card .elementor-post__thumbnail.elementor-fit-height img{height:115%}.elementor-posts__hover-zoom-out .elementor-post__card .elementor-post__thumbnail:not(.elementor-fit-height) img{width:115%}.elementor-posts__hover-zoom-out .elementor-post__card:hover .elementor-post__thumbnail.elementor-fit-height img{height:100%}.elementor-posts__hover-zoom-out .elementor-post__card:hover .elementor-post__thumbnail:not(.elementor-fit-height) img{width:calc(100% + 1px)}.elementor-posts__hover-zoom-in .elementor-post__thumbnail img,.elementor-posts__hover-zoom-out .elementor-post__thumbnail img{transition:filter .3s,height 1s cubic-bezier(0,.25,.07,1),width 1s cubic-bezier(0,.25,.07,1)}.elementor-card-shadow-yes .elementor-post__card{box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.elementor-card-shadow-yes .elementor-post__card:hover{box-shadow:0 0 30px 0 rgba(0,0,0,.15)}.elementor-posts--skin-full_content article{flex-direction:column;overflow:hidden}.elementor-posts--skin-full_content article .elementor-post__thumbnail{padding-bottom:0}body.elementor-editor-active .elementor-posts--skin-archive_full_content,body.elementor-editor-active .elementor-posts--skin-full_content{pointer-events:none}body.elementor-editor-active .elementor-posts--skin-archive_full_content .elementor-post__thumbnail__link,body.elementor-editor-active .elementor-posts--skin-full_content .elementor-post__thumbnail__link{display:none}.elementor-posts.elementor-posts--skin-archive_full_content article.elementor-post,body.elementor-editor-active .elementor-posts--show-thumbnail .elementor-post__thumbnail__link{display:block}.elementor-portfolio__filters{display:flex;flex-wrap:wrap;justify-content:center;list-style:none;margin:0;padding:0}.elementor-portfolio__filter{cursor:pointer;margin:0;padding:8px}.elementor-portfolio__filter:focus-visible{outline:1px auto -webkit-focus-ring-color}.elementor-portfolio-item{align-self:flex-start;margin:0;overflow:hidden;transform-style:preserve-3d;transition-property:transform,opacity;transition-timing-function:ease-in-out}.elementor-portfolio-item__title{color:#fff;font-size:18px;line-height:1;margin:0;padding:0}.elementor-portfolio-item__tags__separator:before{content:", "}.elementor-portfolio-item__overlay{background-color:hsla(213,9%,45%,.8);display:flex;flex-direction:column;inset:0;justify-content:center;opacity:0;overflow:hidden;padding:15px;position:absolute;text-align:center;transition:opacity 1s}.elementor-portfolio-item__img img[src=""]{background-color:rgba(0,0,0,.1);height:100%}.elementor-portfolio-item:focus-within .elementor-portfolio-item__overlay,.elementor-portfolio-item:hover .elementor-portfolio-item__overlay{opacity:1;transition:opacity .5s}.elementor-portfolio.elementor-has-item-ratio{transition:height .5s}.elementor-portfolio.elementor-has-item-ratio .elementor-post__thumbnail{background-color:rgba(0,0,0,.1);position:absolute}.elementor-portfolio.elementor-has-item-ratio .elementor-post__thumbnail__link{padding-bottom:56.25%}.elementor ul li.elementor-portfolio__filter{list-style-type:none}.e-con-inner>.elementor-widget-portfolio,.e-con>.elementor-widget-portfolio{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )}.elementor-widget-archive-posts.load-more-align-center .elementor-button-wrapper,.elementor-widget-posts.load-more-align-center .elementor-button-wrapper{text-align:center}.elementor-widget-archive-posts.load-more-align-start .elementor-button-wrapper,.elementor-widget-posts.load-more-align-start .elementor-button-wrapper{text-align:start}.elementor-widget-archive-posts.load-more-align-end .elementor-button-wrapper,.elementor-widget-posts.load-more-align-end .elementor-button-wrapper{text-align:end}.elementor-widget-archive-posts.load-more-align-justify .elementor-button,.elementor-widget-posts.load-more-align-justify .elementor-button{width:100%}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-archive-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-archive-posts.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper,.elementor-widget-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-posts.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-archive-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-archive-posts.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message,.elementor-widget-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-posts.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-archive-posts.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-archive-posts.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-message,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-posts>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper .elementor-button,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative} \ No newline at end of file diff --git a/assets/css/widget-posts.min.css b/assets/css/widget-posts.min.css new file mode 100644 index 00000000..9ccf9f54 --- /dev/null +++ b/assets/css/widget-posts.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@charset "UTF-8";.elementor-widget-archive-posts:after,.elementor-widget-posts:after{display:none}.elementor-post__thumbnail__link{transition:none}.elementor-posts-container.elementor-posts-masonry{align-items:flex-start}.elementor-posts-container:not(.elementor-posts-masonry){align-items:stretch}.elementor-posts-container .elementor-post{margin:0;padding:0}.elementor-posts-container .elementor-post__excerpt{flex-grow:var(--read-more-alignment,0)}.elementor-posts-container .elementor-post__thumbnail{overflow:hidden}.elementor-posts-container .elementor-post__thumbnail img{display:block;max-height:none;max-width:none;transition:filter .3s;width:100%}.elementor-posts-container .elementor-post__thumbnail__link{display:block;position:relative;width:100%}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail{inset:0}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail img{height:auto;left:calc(50% + 1px);position:absolute;top:calc(50% + 1px);transform:scale(1.01) translate(-50%,-50%)}.elementor-posts-container.elementor-has-item-ratio .elementor-post__thumbnail.elementor-fit-height img{height:100%;width:auto}.elementor-posts .elementor-post{flex-direction:column;transition-duration:.25s;transition-property:background,border,box-shadow}.elementor-posts .elementor-post__title{font-size:18px;margin:0}.elementor-posts .elementor-post__excerpt{margin-bottom:10px}.elementor-posts .elementor-post__excerpt p{color:#777;font-size:14px;line-height:1.5em;margin:0}.elementor-posts .elementor-post__text{display:var(--item-display,block);flex-direction:column;flex-grow:1}.elementor-posts .elementor-post__meta-data{color:#adadad;font-size:12px;line-height:1.3em;margin-bottom:13px}.elementor-posts .elementor-post__read-more{align-self:flex-start;font-size:12px;font-weight:700}.elementor-posts .elementor-post__thumbnail{position:relative}.elementor-posts--skin-classic .elementor-post{overflow:hidden}.elementor-posts--align-left .elementor-post{text-align:left}.elementor-posts--align-right .elementor-post{text-align:right}.elementor-posts--align-center .elementor-post{text-align:center}.elementor-posts--thumbnail-top .elementor-post__thumbnail__link{margin-bottom:20px}.elementor-posts--thumbnail-top .elementor-post__text{width:100%}.elementor-posts--thumbnail-top.elementor-posts--align-left .elementor-post__thumbnail__link{margin-right:auto}.elementor-posts--thumbnail-top.elementor-posts--align-right .elementor-post__thumbnail__link{margin-left:auto}.elementor-posts--thumbnail-top.elementor-posts--align-center .elementor-post__thumbnail__link{margin-left:auto;margin-right:auto}.elementor-posts--thumbnail-left .elementor-post,.elementor-posts--thumbnail-right .elementor-post{flex-direction:row}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link,.elementor-posts--thumbnail-right .elementor-post__thumbnail__link{flex-shrink:0;width:25%}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link{margin-right:20px;order:0}.elementor-posts--thumbnail-right .elementor-post__thumbnail__link{margin-left:20px;order:5}.elementor-posts--thumbnail-none .elementor-posts-container .elementor-post__thumbnail__link{display:none}.elementor-posts .elementor-post{display:flex}.elementor-posts .elementor-post__card{background-color:#fff;border:0 solid #69727d;border-radius:3px;display:flex;flex-direction:column;min-height:100%;overflow:hidden;position:relative;transition:all .25s;width:100%}.elementor-posts .elementor-post__card .elementor-post__thumbnail{position:relative;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.elementor-posts .elementor-post__card .elementor-post__thumbnail img{width:calc(100% + 1px)}.elementor-posts .elementor-post__card .elementor-post__text{margin-bottom:0;margin-top:20px;padding:0 30px}.elementor-posts .elementor-post__card .elementor-post__read-more{display:inline-block;margin-bottom:20px}.elementor-posts .elementor-post__card .elementor-post__meta-data{border-top:1px solid #eaeaea;margin-bottom:0;padding:15px 30px}.elementor-posts .elementor-post__card .elementor-post__meta-data span+span:before{margin:0 5px}.elementor-posts .elementor-post__card .elementor-post__title{font-size:21px}.elementor-posts .elementor-post__card .elementor-post__excerpt{line-height:1.7}.elementor-posts .elementor-post__card .elementor-post__excerpt,.elementor-posts .elementor-post__card .elementor-post__title{margin-bottom:25px}.elementor-posts .elementor-post__card .elementor-post__badge,.elementor-posts .elementor-post__card .elementor-post__read-more{text-transform:uppercase}.elementor-posts .elementor-post__badge{background:#69727d;border-radius:999px;color:#fff;font-size:12px;font-weight:400;line-height:1;margin:20px;padding:.6em 1.2em;position:absolute;top:0}.elementor-posts .elementor-post__avatar{height:0;padding:0 30px;pointer-events:none;position:relative;top:-25px;width:100%}.elementor-posts .elementor-post__avatar img{border-radius:50%;pointer-events:all;transform:translateY(-50%);width:60px}.elementor-posts .elementor-posts--skin-cards:not(.elementor-posts-masonry) .elementor-post__meta-data,.elementor-posts--thumbnail-top .elementor-posts--skin-cards:not(.elementor-posts-masonry) .elementor-post__meta-data{margin-top:auto}.elementor-posts--thumbnail-none .elementor-post__card .elementor-post__avatar{height:auto;padding-top:0;position:static}.elementor-posts--thumbnail-none .elementor-post__card .elementor-post__avatar img.avatar{transform:translateY(0);vertical-align:bottom}.elementor-posts--show-avatar .elementor-post__thumbnail__link{margin-bottom:25px}.elementor-posts__hover-gradient .elementor-post__card .elementor-post__thumbnail__link:after{background-image:linear-gradient(0deg,rgba(0,0,0,.35),transparent 75%);background-repeat:no-repeat;bottom:0;content:"";display:block;height:100%;opacity:1;position:absolute;transition:all .3s ease-out;width:100%}.elementor-posts__hover-gradient .elementor-post__card:hover .elementor-post__thumbnail__link:after{opacity:.5}.elementor-posts__hover-zoom-in .elementor-post__card .elementor-post__thumbnail.elementor-fit-height img{height:100%}.elementor-posts__hover-zoom-in .elementor-post__card .elementor-post__thumbnail:not(.elementor-fit-height) img{width:calc(100% + 1px)}.elementor-posts__hover-zoom-in .elementor-post__card:hover .elementor-post__thumbnail.elementor-fit-height img{height:115%}.elementor-posts__hover-zoom-in .elementor-post__card:hover .elementor-post__thumbnail:not(.elementor-fit-height) img{width:115%}.elementor-posts__hover-zoom-out .elementor-post__card .elementor-post__thumbnail.elementor-fit-height img{height:115%}.elementor-posts__hover-zoom-out .elementor-post__card .elementor-post__thumbnail:not(.elementor-fit-height) img{width:115%}.elementor-posts__hover-zoom-out .elementor-post__card:hover .elementor-post__thumbnail.elementor-fit-height img{height:100%}.elementor-posts__hover-zoom-out .elementor-post__card:hover .elementor-post__thumbnail:not(.elementor-fit-height) img{width:calc(100% + 1px)}.elementor-posts__hover-zoom-in .elementor-post__thumbnail img,.elementor-posts__hover-zoom-out .elementor-post__thumbnail img{transition:filter .3s,height 1s cubic-bezier(0,.25,.07,1),width 1s cubic-bezier(0,.25,.07,1)}.elementor-card-shadow-yes .elementor-post__card{box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.elementor-card-shadow-yes .elementor-post__card:hover{box-shadow:0 0 30px 0 rgba(0,0,0,.15)}.elementor-posts--skin-full_content article{flex-direction:column;overflow:hidden}.elementor-posts--skin-full_content article .elementor-post__thumbnail{padding-bottom:0}body.elementor-editor-active .elementor-posts--skin-archive_full_content,body.elementor-editor-active .elementor-posts--skin-full_content{pointer-events:none}body.elementor-editor-active .elementor-posts--skin-archive_full_content .elementor-post__thumbnail__link,body.elementor-editor-active .elementor-posts--skin-full_content .elementor-post__thumbnail__link{display:none}.elementor-posts.elementor-posts--skin-archive_full_content article.elementor-post,body.elementor-editor-active .elementor-posts--show-thumbnail .elementor-post__thumbnail__link{display:block}.elementor-portfolio__filters{display:flex;flex-wrap:wrap;justify-content:center;list-style:none;margin:0;padding:0}.elementor-portfolio__filter{cursor:pointer;margin:0;padding:8px}.elementor-portfolio__filter:focus-visible{outline:1px auto -webkit-focus-ring-color}.elementor-portfolio-item{align-self:flex-start;margin:0;overflow:hidden;transform-style:preserve-3d;transition-property:transform,opacity;transition-timing-function:ease-in-out}.elementor-portfolio-item__title{color:#fff;font-size:18px;line-height:1;margin:0;padding:0}.elementor-portfolio-item__tags__separator:before{content:", "}.elementor-portfolio-item__overlay{background-color:hsla(213,9%,45%,.8);display:flex;flex-direction:column;inset:0;justify-content:center;opacity:0;overflow:hidden;padding:15px;position:absolute;text-align:center;transition:opacity 1s}.elementor-portfolio-item__img img[src=""]{background-color:rgba(0,0,0,.1);height:100%}.elementor-portfolio-item:focus-within .elementor-portfolio-item__overlay,.elementor-portfolio-item:hover .elementor-portfolio-item__overlay{opacity:1;transition:opacity .5s}.elementor-portfolio.elementor-has-item-ratio{transition:height .5s}.elementor-portfolio.elementor-has-item-ratio .elementor-post__thumbnail{background-color:rgba(0,0,0,.1);position:absolute}.elementor-portfolio.elementor-has-item-ratio .elementor-post__thumbnail__link{padding-bottom:56.25%}.elementor ul li.elementor-portfolio__filter{list-style-type:none}.e-con-inner>.elementor-widget-portfolio,.e-con>.elementor-widget-portfolio{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )}.elementor-widget-archive-posts.load-more-align-center .elementor-button-wrapper,.elementor-widget-posts.load-more-align-center .elementor-button-wrapper{text-align:center}.elementor-widget-archive-posts.load-more-align-start .elementor-button-wrapper,.elementor-widget-posts.load-more-align-start .elementor-button-wrapper{text-align:start}.elementor-widget-archive-posts.load-more-align-end .elementor-button-wrapper,.elementor-widget-posts.load-more-align-end .elementor-button-wrapper{text-align:end}.elementor-widget-archive-posts.load-more-align-justify .elementor-button,.elementor-widget-posts.load-more-align-justify .elementor-button{width:100%}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container{cursor:default}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner{margin-top:var(--load-more—spacing,30px)}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container .e-load-more-spinner svg{display:flex}.elementor-widget-archive-posts.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-pagination-loading>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:hidden}.elementor-widget-archive-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-archive-posts.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper,.elementor-widget-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-posts.e-load-more-pagination-end>.elementor-widget-container>.elementor-button-wrapper{display:none}.elementor-widget-archive-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-archive-posts.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message,.elementor-widget-posts.e-load-more-pagination-end:not(:has(>.elementor-widget-container))>.e-load-more-message,.elementor-widget-posts.e-load-more-pagination-end>.elementor-widget-container>.e-load-more-message{display:block}.elementor-widget-archive-posts.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-archive-posts.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-no-spinner:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button-content-wrapper,.elementor-widget-posts.e-load-more-no-spinner>.elementor-widget-container>.elementor-button-wrapper .elementor-button-content-wrapper{visibility:visible}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner{display:flex}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner svg{display:none;margin:0 auto}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner i,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner i,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner i{color:var(--load-more-spinner-color)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-spinner svg,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-spinner svg,.elementor-widget-posts>.elementor-widget-container .e-load-more-spinner svg{fill:var(--load-more-spinner-color);height:1em;width:1em}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-archive-posts>.elementor-widget-container .e-load-more-message,.elementor-widget-posts:not(:has(>.elementor-widget-container)) .e-load-more-message,.elementor-widget-posts>.elementor-widget-container .e-load-more-message{color:var(--load-more-message-color);display:none;margin-top:var(--load-more—spacing,30px);text-align:var(--load-more-message-alignment,center)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper{margin-top:var(--load-more—spacing,30px)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .e-load-more-spinner,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper .e-load-more-spinner{inset-block-start:50%;inset-inline-start:50%;margin:inherit;position:absolute;transform:translate(-50%,-50%)}.elementor-widget-archive-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-archive-posts>.elementor-widget-container>.elementor-button-wrapper .elementor-button,.elementor-widget-posts:not(:has(>.elementor-widget-container))>.elementor-button-wrapper .elementor-button,.elementor-widget-posts>.elementor-widget-container>.elementor-button-wrapper .elementor-button{cursor:pointer;position:relative} \ No newline at end of file diff --git a/assets/css/widget-price-list-rtl.min.css b/assets/css/widget-price-list-rtl.min.css new file mode 100644 index 00000000..74d9994d --- /dev/null +++ b/assets/css/widget-price-list-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-price-list .elementor-price-list{list-style:none;margin:0;padding:0}.elementor-widget-price-list .elementor-price-list li{margin:0}.elementor-price-list li:not(:last-child){margin-bottom:20px}.elementor-price-list .elementor-price-list-image{flex-shrink:0;max-width:50%;padding-inline-end:25px}.elementor-price-list .elementor-price-list-image img{width:100%}.elementor-price-list .elementor-price-list-header,.elementor-price-list .elementor-price-list-item,.elementor-price-list .elementor-price-list-text{display:flex}.elementor-price-list .elementor-price-list-item{align-items:flex-start}.elementor-price-list .elementor-price-list-item .elementor-price-list-text{align-items:flex-start;flex-grow:1;flex-wrap:wrap}.elementor-price-list .elementor-price-list-item .elementor-price-list-header{align-items:center;flex-basis:100%;font-size:19px;font-weight:600;justify-content:space-between;margin-bottom:10px}.elementor-price-list .elementor-price-list-item .elementor-price-list-title{max-width:80%}.elementor-price-list .elementor-price-list-item .elementor-price-list-price{font-weight:600}.elementor-price-list .elementor-price-list-item p.elementor-price-list-description{flex-basis:100%;font-size:14px;margin:0}.elementor-price-list .elementor-price-list-item .elementor-price-list-separator{border-bottom-style:dotted;border-bottom-width:2px;flex-grow:1;height:0;margin-left:10px;margin-right:10px}.e-con-inner>.elementor-widget-price-list,.e-con>.elementor-widget-price-list{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-price-list.min.css b/assets/css/widget-price-list.min.css new file mode 100644 index 00000000..74d9994d --- /dev/null +++ b/assets/css/widget-price-list.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-price-list .elementor-price-list{list-style:none;margin:0;padding:0}.elementor-widget-price-list .elementor-price-list li{margin:0}.elementor-price-list li:not(:last-child){margin-bottom:20px}.elementor-price-list .elementor-price-list-image{flex-shrink:0;max-width:50%;padding-inline-end:25px}.elementor-price-list .elementor-price-list-image img{width:100%}.elementor-price-list .elementor-price-list-header,.elementor-price-list .elementor-price-list-item,.elementor-price-list .elementor-price-list-text{display:flex}.elementor-price-list .elementor-price-list-item{align-items:flex-start}.elementor-price-list .elementor-price-list-item .elementor-price-list-text{align-items:flex-start;flex-grow:1;flex-wrap:wrap}.elementor-price-list .elementor-price-list-item .elementor-price-list-header{align-items:center;flex-basis:100%;font-size:19px;font-weight:600;justify-content:space-between;margin-bottom:10px}.elementor-price-list .elementor-price-list-item .elementor-price-list-title{max-width:80%}.elementor-price-list .elementor-price-list-item .elementor-price-list-price{font-weight:600}.elementor-price-list .elementor-price-list-item p.elementor-price-list-description{flex-basis:100%;font-size:14px;margin:0}.elementor-price-list .elementor-price-list-item .elementor-price-list-separator{border-bottom-style:dotted;border-bottom-width:2px;flex-grow:1;height:0;margin-left:10px;margin-right:10px}.e-con-inner>.elementor-widget-price-list,.e-con>.elementor-widget-price-list{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-price-table-rtl.min.css b/assets/css/widget-price-table-rtl.min.css new file mode 100644 index 00000000..c8cdc2e5 --- /dev/null +++ b/assets/css/widget-price-table-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-price-table{text-align:center}.elementor-price-table .elementor-price-table__header{background:var(--e-price-table-header-background-color,#555);padding:20px 0}.elementor-price-table .elementor-price-table__heading{color:#fff;font-size:24px;font-weight:600;line-height:1.2;margin:0;padding:0}.elementor-price-table .elementor-price-table__subheading{color:#fff;font-size:13px;font-weight:400}.elementor-price-table .elementor-price-table__original-price{align-self:center;font-size:.5em;font-weight:400;line-height:1;margin-inline-end:15px;text-decoration:line-through}.elementor-price-table .elementor-price-table__original-price .elementor-price-table__currency{font-size:1em;margin:0}.elementor-price-table .elementor-price-table__price{align-items:center;color:#555;display:flex;flex-direction:row-reverse;flex-wrap:wrap;font-size:65px;font-weight:800;justify-content:center;padding:40px 0}.elementor-price-table .elementor-price-table__price .elementor-typo-excluded{font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;line-height:normal;text-transform:none}.elementor-price-table .elementor-price-table__after-price{align-items:flex-start;align-self:stretch;display:flex;flex-direction:column;flex-wrap:wrap;text-align:start}.elementor-price-table .elementor-price-table__integer-part{line-height:.8}.elementor-price-table .elementor-price-table__currency,.elementor-price-table .elementor-price-table__fractional-part{font-size:.3em;line-height:1}.elementor-price-table .elementor-price-table__currency{margin-inline-end:3px}.elementor-price-table .elementor-price-table__period{font-size:13px;font-weight:400;width:100%}.elementor-price-table .elementor-price-table__features-list{color:var(--e-price-table-features-list-color);line-height:1;list-style-type:none;margin:0;padding:0}.elementor-price-table .elementor-price-table__features-list li{font-size:14px;line-height:1;margin:0;padding:0}.elementor-price-table .elementor-price-table__features-list li .elementor-price-table__feature-inner{margin-left:15px;margin-right:15px}.elementor-price-table .elementor-price-table__features-list li:not(:first-child):before{border:0 solid hsla(0,0%,48%,.3);content:"";display:block;margin:10px 12.5%}.elementor-price-table .elementor-price-table__features-list i{font-size:1.3em;margin-inline-end:10px}.elementor-price-table .elementor-price-table__features-list svg{margin-inline-end:10px;fill:var(--e-price-table-features-list-color);height:1.3em;width:1.3em}.elementor-price-table .elementor-price-table__features-list svg~*{vertical-align:text-top}.elementor-price-table .elementor-price-table__footer{padding:30px 0}.elementor-price-table .elementor-price-table__additional_info{font-size:13px;line-height:1.4;margin:0}.elementor-widget-price-table .elementor-widget-container,.elementor-widget-price-table:not(:has(.elementor-widget-container)){background-color:#f9fafa;overflow:hidden} \ No newline at end of file diff --git a/assets/css/widget-price-table.min.css b/assets/css/widget-price-table.min.css new file mode 100644 index 00000000..69487415 --- /dev/null +++ b/assets/css/widget-price-table.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-price-table{text-align:center}.elementor-price-table .elementor-price-table__header{background:var(--e-price-table-header-background-color,#555);padding:20px 0}.elementor-price-table .elementor-price-table__heading{color:#fff;font-size:24px;font-weight:600;line-height:1.2;margin:0;padding:0}.elementor-price-table .elementor-price-table__subheading{color:#fff;font-size:13px;font-weight:400}.elementor-price-table .elementor-price-table__original-price{align-self:center;font-size:.5em;font-weight:400;line-height:1;margin-inline-end:15px;text-decoration:line-through}.elementor-price-table .elementor-price-table__original-price .elementor-price-table__currency{font-size:1em;margin:0}.elementor-price-table .elementor-price-table__price{align-items:center;color:#555;display:flex;flex-direction:row;flex-wrap:wrap;font-size:65px;font-weight:800;justify-content:center;padding:40px 0}.elementor-price-table .elementor-price-table__price .elementor-typo-excluded{font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;line-height:normal;text-transform:none}.elementor-price-table .elementor-price-table__after-price{align-items:flex-start;align-self:stretch;display:flex;flex-direction:column;flex-wrap:wrap;text-align:start}.elementor-price-table .elementor-price-table__integer-part{line-height:.8}.elementor-price-table .elementor-price-table__currency,.elementor-price-table .elementor-price-table__fractional-part{font-size:.3em;line-height:1}.elementor-price-table .elementor-price-table__currency{margin-inline-end:3px}.elementor-price-table .elementor-price-table__period{font-size:13px;font-weight:400;width:100%}.elementor-price-table .elementor-price-table__features-list{color:var(--e-price-table-features-list-color);line-height:1;list-style-type:none;margin:0;padding:0}.elementor-price-table .elementor-price-table__features-list li{font-size:14px;line-height:1;margin:0;padding:0}.elementor-price-table .elementor-price-table__features-list li .elementor-price-table__feature-inner{margin-left:15px;margin-right:15px}.elementor-price-table .elementor-price-table__features-list li:not(:first-child):before{border:0 solid hsla(0,0%,48%,.3);content:"";display:block;margin:10px 12.5%}.elementor-price-table .elementor-price-table__features-list i{font-size:1.3em;margin-inline-end:10px}.elementor-price-table .elementor-price-table__features-list svg{margin-inline-end:10px;fill:var(--e-price-table-features-list-color);height:1.3em;width:1.3em}.elementor-price-table .elementor-price-table__features-list svg~*{vertical-align:text-top}.elementor-price-table .elementor-price-table__footer{padding:30px 0}.elementor-price-table .elementor-price-table__additional_info{font-size:13px;line-height:1.4;margin:0}.elementor-widget-price-table .elementor-widget-container,.elementor-widget-price-table:not(:has(.elementor-widget-container)){background-color:#f9fafa;overflow:hidden} \ No newline at end of file diff --git a/assets/css/widget-progress-tracker-rtl.min.css b/assets/css/widget-progress-tracker-rtl.min.css new file mode 100644 index 00000000..f86717fb --- /dev/null +++ b/assets/css/widget-progress-tracker-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-scrolling-tracker{--scrolling-track-default-progress-color:#61ce70;--scrolling-track-default-color:#eee;--scrolling-track-precentage-default-color:$black}.elementor-scrolling-tracker-horizontal{align-items:center;background-color:var(--scrolling-track-default-color);border-color:var(--horizontal-border-color);border-radius:var(--border-radius);border-style:var(--horizontal-border-style);border-width:var(--horizontal-border-top-width,2px) var(--horizontal-border-right-width,2px) var(--horizontal-border-bottom-width,2px) var(--horizontal-border-left-width,2px);direction:var(--direction);display:flex;height:var(--horizontal-height,20px);padding:var(--tracker-padding);width:100%}.elementor-scrolling-tracker-horizontal .current-progress{align-items:center;background-color:var(--scrolling-track-default-progress-color);border-color:var(--horizontal-progress-border-color);border-radius:var(--progress-border-radius);border-style:var(--horizontal-progress-border);border-width:var(--horizontal-progress-border-top-width,2px) var(--horizontal-progress-border-right-width,2px) var(--horizontal-progress-border-bottom-width,2px) var(--horizontal-progress-border-left-width,2px);display:none;height:100%;position:relative}.elementor-scrolling-tracker-horizontal .current-progress .current-progress-percentage{color:var(--percentage-color,var(--scrolling-track-precentage-default-color));direction:var(--text-direction);inset-inline:auto .5em;position:absolute}.elementor-scrolling-tracker-circular{align-items:center;display:flex;height:var(--circular-height,100px);justify-content:center;margin-inline:0 auto;position:relative;width:var(--circular-width,100px)}.elementor-scrolling-tracker-circular .current-progress-percentage{color:var(--percentage-color,var(--scrolling-track-precentage-default-color));position:absolute}.elementor-scrolling-tracker-circular svg{position:absolute}.elementor-scrolling-tracker-circular .current-progress{display:none;transform:rotate(-90deg);transform-origin:50% 50%;stroke:var(--circular-color,var(--scrolling-track-default-progress-color));fill:transparent;stroke-width:var(--circular-progress-width,4px)}.elementor-scrolling-tracker-circular .circle{stroke:var(--circular-background-color,var(--scrolling-track-default-color));fill:transparent;stroke-width:var(--circular-background-width,4px)}.elementor-scrolling-tracker-alignment-left{margin-left:0;margin-right:auto}.elementor-scrolling-tracker-alignment-center{margin-left:auto;margin-right:auto}.elementor-scrolling-tracker-alignment-right{margin-left:auto;margin-right:0}.e-con-inner>.elementor-widget-progress-tracker,.e-con>.elementor-widget-progress-tracker{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-progress-tracker.min.css b/assets/css/widget-progress-tracker.min.css new file mode 100644 index 00000000..f86717fb --- /dev/null +++ b/assets/css/widget-progress-tracker.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-scrolling-tracker{--scrolling-track-default-progress-color:#61ce70;--scrolling-track-default-color:#eee;--scrolling-track-precentage-default-color:$black}.elementor-scrolling-tracker-horizontal{align-items:center;background-color:var(--scrolling-track-default-color);border-color:var(--horizontal-border-color);border-radius:var(--border-radius);border-style:var(--horizontal-border-style);border-width:var(--horizontal-border-top-width,2px) var(--horizontal-border-right-width,2px) var(--horizontal-border-bottom-width,2px) var(--horizontal-border-left-width,2px);direction:var(--direction);display:flex;height:var(--horizontal-height,20px);padding:var(--tracker-padding);width:100%}.elementor-scrolling-tracker-horizontal .current-progress{align-items:center;background-color:var(--scrolling-track-default-progress-color);border-color:var(--horizontal-progress-border-color);border-radius:var(--progress-border-radius);border-style:var(--horizontal-progress-border);border-width:var(--horizontal-progress-border-top-width,2px) var(--horizontal-progress-border-right-width,2px) var(--horizontal-progress-border-bottom-width,2px) var(--horizontal-progress-border-left-width,2px);display:none;height:100%;position:relative}.elementor-scrolling-tracker-horizontal .current-progress .current-progress-percentage{color:var(--percentage-color,var(--scrolling-track-precentage-default-color));direction:var(--text-direction);inset-inline:auto .5em;position:absolute}.elementor-scrolling-tracker-circular{align-items:center;display:flex;height:var(--circular-height,100px);justify-content:center;margin-inline:0 auto;position:relative;width:var(--circular-width,100px)}.elementor-scrolling-tracker-circular .current-progress-percentage{color:var(--percentage-color,var(--scrolling-track-precentage-default-color));position:absolute}.elementor-scrolling-tracker-circular svg{position:absolute}.elementor-scrolling-tracker-circular .current-progress{display:none;transform:rotate(-90deg);transform-origin:50% 50%;stroke:var(--circular-color,var(--scrolling-track-default-progress-color));fill:transparent;stroke-width:var(--circular-progress-width,4px)}.elementor-scrolling-tracker-circular .circle{stroke:var(--circular-background-color,var(--scrolling-track-default-color));fill:transparent;stroke-width:var(--circular-background-width,4px)}.elementor-scrolling-tracker-alignment-left{margin-left:0;margin-right:auto}.elementor-scrolling-tracker-alignment-center{margin-left:auto;margin-right:auto}.elementor-scrolling-tracker-alignment-right{margin-left:auto;margin-right:0}.e-con-inner>.elementor-widget-progress-tracker,.e-con>.elementor-widget-progress-tracker{width:var(--container-widget-width);--flex-grow:var( --container-widget-flex-grow )} \ No newline at end of file diff --git a/assets/css/widget-reviews-rtl.min.css b/assets/css/widget-reviews-rtl.min.css new file mode 100644 index 00000000..4cd634e0 --- /dev/null +++ b/assets/css/widget-reviews-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-reviews .swiper-slide{background-color:#fff;border:1px solid #e1e8ed;border-radius:5px;padding:0}.elementor-widget-reviews .elementor-testimonial__text{font-size:14px;line-height:20px}.elementor-widget-reviews .elementor-testimonial__name{color:#1c2022}.elementor-widget-reviews .elementor-testimonial__title{color:#697882;font-family:inherit;font-size:12.5px;font-weight:400}.elementor-widget-reviews .elementor-testimonial__image{display:flex}.elementor-widget-reviews .elementor-testimonial__image img{height:36px;width:36px}.elementor-widget-reviews .elementor-testimonial__icon{font-size:17px;margin-inline-start:auto}.elementor-widget-reviews .elementor-testimonial__icon .fa+.fa{margin-inline-start:.15em}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon{color:var(--e-testimonial-icon-color)}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-android{--e-testimonial-icon-color:#a4c639}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-apple{--e-testimonial-icon-color:#999}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-behance{--e-testimonial-icon-color:#1769ff}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-bitbucket{--e-testimonial-icon-color:#205081}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-codepen{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-delicious{--e-testimonial-icon-color:#39f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-digg{--e-testimonial-icon-color:#005be2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-dribbble{--e-testimonial-icon-color:#ea4c89}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-envelope{--e-testimonial-icon-color:#ea4335}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-facebook{--e-testimonial-icon-color:#3b5998}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-flickr{--e-testimonial-icon-color:#0063dc}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-foursquare{--e-testimonial-icon-color:#2d5be3}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-github{--e-testimonial-icon-color:#333}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-google-plus{--e-testimonial-icon-color:#dd4b39}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-houzz{--e-testimonial-icon-color:#7ac142}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-instagram{--e-testimonial-icon-color:#262626}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-jsfiddle{--e-testimonial-icon-color:#487aa2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-linkedin{--e-testimonial-icon-color:#0077b5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-medium{--e-testimonial-icon-color:#00ab6b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-meetup{--e-testimonial-icon-color:#ec1c40}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-mixcloud{--e-testimonial-icon-color:#273a4b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-odnoklassniki{--e-testimonial-icon-color:#f4731c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-pinterest{--e-testimonial-icon-color:#bd081c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-product-hunt{--e-testimonial-icon-color:#da552f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-reddit{--e-testimonial-icon-color:#ff4500}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-rss{--e-testimonial-icon-color:#f26522}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-shopping-cart{--e-testimonial-icon-color:#4caf50}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-skype{--e-testimonial-icon-color:#00aff0}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-slideshare{--e-testimonial-icon-color:#0077b5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-snapchat{--e-testimonial-icon-color:#fffc00}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-soundcloud{--e-testimonial-icon-color:#f80}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-spotify{--e-testimonial-icon-color:#2ebd59}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-stack-overflow{--e-testimonial-icon-color:#fe7a15}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-steam{--e-testimonial-icon-color:#00adee}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-stumbleupon{--e-testimonial-icon-color:#eb4924}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-telegram{--e-testimonial-icon-color:#2ca5e0}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-thumb-tack,.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-thumbtack{--e-testimonial-icon-color:#1aa1d8}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-threads{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-tripadvisor{--e-testimonial-icon-color:#589442}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-tumblr{--e-testimonial-icon-color:#35465c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-twitch{--e-testimonial-icon-color:#6441a5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-twitter{--e-testimonial-icon-color:#1da1f2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-vimeo{--e-testimonial-icon-color:#1ab7ea}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-vk{--e-testimonial-icon-color:#45668e}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-weibo{--e-testimonial-icon-color:#dd2430}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-weixin{--e-testimonial-icon-color:#31a918}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-whatsapp{--e-testimonial-icon-color:#25d366}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-wordpress{--e-testimonial-icon-color:#21759b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-x{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-xing{--e-testimonial-icon-color:#026466}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-yelp{--e-testimonial-icon-color:#af0606}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-youtube{--e-testimonial-icon-color:#cd201f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-500px{--e-testimonial-icon-color:#0099e5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon svg{fill:var(--e-testimonial-icon-color)}.elementor-widget-reviews .elementor-testimonial__rating{background-image:linear-gradient(to right,#ffc82c var(--rating),#ccc var(--rating));font-family:eicons}.elementor-widget-reviews .elementor-testimonial__header{display:flex;padding-block:15px 6px}.elementor-widget-reviews .elementor-testimonial__image+cite{margin-inline-start:9px}.elementor-widget-reviews .elementor-testimonial__separator{border-block-end:1px solid #e1e8ed;border-block-start:0 none;height:0;margin:0 auto}.elementor-widget-reviews .elementor-testimonial__content{padding-block:6px 15px}.elementor-widget-reviews .elementor-testimonial__content,.elementor-widget-reviews .elementor-testimonial__header{padding-inline:15px}.elementor-widget-reviews.elementor-review--has-separator .elementor-testimonial__header{border-block-end:1px solid #e1e8ed} \ No newline at end of file diff --git a/assets/css/widget-reviews.min.css b/assets/css/widget-reviews.min.css new file mode 100644 index 00000000..4cd634e0 --- /dev/null +++ b/assets/css/widget-reviews.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-reviews .swiper-slide{background-color:#fff;border:1px solid #e1e8ed;border-radius:5px;padding:0}.elementor-widget-reviews .elementor-testimonial__text{font-size:14px;line-height:20px}.elementor-widget-reviews .elementor-testimonial__name{color:#1c2022}.elementor-widget-reviews .elementor-testimonial__title{color:#697882;font-family:inherit;font-size:12.5px;font-weight:400}.elementor-widget-reviews .elementor-testimonial__image{display:flex}.elementor-widget-reviews .elementor-testimonial__image img{height:36px;width:36px}.elementor-widget-reviews .elementor-testimonial__icon{font-size:17px;margin-inline-start:auto}.elementor-widget-reviews .elementor-testimonial__icon .fa+.fa{margin-inline-start:.15em}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon{color:var(--e-testimonial-icon-color)}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-android{--e-testimonial-icon-color:#a4c639}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-apple{--e-testimonial-icon-color:#999}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-behance{--e-testimonial-icon-color:#1769ff}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-bitbucket{--e-testimonial-icon-color:#205081}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-codepen{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-delicious{--e-testimonial-icon-color:#39f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-digg{--e-testimonial-icon-color:#005be2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-dribbble{--e-testimonial-icon-color:#ea4c89}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-envelope{--e-testimonial-icon-color:#ea4335}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-facebook{--e-testimonial-icon-color:#3b5998}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-flickr{--e-testimonial-icon-color:#0063dc}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-foursquare{--e-testimonial-icon-color:#2d5be3}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-github{--e-testimonial-icon-color:#333}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-google-plus{--e-testimonial-icon-color:#dd4b39}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-houzz{--e-testimonial-icon-color:#7ac142}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-instagram{--e-testimonial-icon-color:#262626}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-jsfiddle{--e-testimonial-icon-color:#487aa2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-linkedin{--e-testimonial-icon-color:#0077b5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-medium{--e-testimonial-icon-color:#00ab6b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-meetup{--e-testimonial-icon-color:#ec1c40}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-mixcloud{--e-testimonial-icon-color:#273a4b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-odnoklassniki{--e-testimonial-icon-color:#f4731c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-pinterest{--e-testimonial-icon-color:#bd081c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-product-hunt{--e-testimonial-icon-color:#da552f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-reddit{--e-testimonial-icon-color:#ff4500}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-rss{--e-testimonial-icon-color:#f26522}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-shopping-cart{--e-testimonial-icon-color:#4caf50}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-skype{--e-testimonial-icon-color:#00aff0}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-slideshare{--e-testimonial-icon-color:#0077b5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-snapchat{--e-testimonial-icon-color:#fffc00}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-soundcloud{--e-testimonial-icon-color:#f80}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-spotify{--e-testimonial-icon-color:#2ebd59}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-stack-overflow{--e-testimonial-icon-color:#fe7a15}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-steam{--e-testimonial-icon-color:#00adee}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-stumbleupon{--e-testimonial-icon-color:#eb4924}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-telegram{--e-testimonial-icon-color:#2ca5e0}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-thumb-tack,.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-thumbtack{--e-testimonial-icon-color:#1aa1d8}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-threads{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-tripadvisor{--e-testimonial-icon-color:#589442}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-tumblr{--e-testimonial-icon-color:#35465c}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-twitch{--e-testimonial-icon-color:#6441a5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-twitter{--e-testimonial-icon-color:#1da1f2}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-vimeo{--e-testimonial-icon-color:#1ab7ea}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-vk{--e-testimonial-icon-color:#45668e}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-weibo{--e-testimonial-icon-color:#dd2430}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-weixin{--e-testimonial-icon-color:#31a918}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-whatsapp{--e-testimonial-icon-color:#25d366}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-wordpress{--e-testimonial-icon-color:#21759b}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-x{--e-testimonial-icon-color:#000}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-xing{--e-testimonial-icon-color:#026466}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-yelp{--e-testimonial-icon-color:#af0606}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-youtube{--e-testimonial-icon-color:#cd201f}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon-500px{--e-testimonial-icon-color:#0099e5}.elementor-widget-reviews .elementor-testimonial__icon.elementor-icon svg{fill:var(--e-testimonial-icon-color)}.elementor-widget-reviews .elementor-testimonial__rating{background-image:linear-gradient(to right,#ffc82c var(--rating),#ccc var(--rating));font-family:eicons}.elementor-widget-reviews .elementor-testimonial__header{display:flex;padding-block:15px 6px}.elementor-widget-reviews .elementor-testimonial__image+cite{margin-inline-start:9px}.elementor-widget-reviews .elementor-testimonial__separator{border-block-end:1px solid #e1e8ed;border-block-start:0 none;height:0;margin:0 auto}.elementor-widget-reviews .elementor-testimonial__content{padding-block:6px 15px}.elementor-widget-reviews .elementor-testimonial__content,.elementor-widget-reviews .elementor-testimonial__header{padding-inline:15px}.elementor-widget-reviews.elementor-review--has-separator .elementor-testimonial__header{border-block-end:1px solid #e1e8ed} \ No newline at end of file diff --git a/assets/css/widget-search-form-rtl.min.css b/assets/css/widget-search-form-rtl.min.css new file mode 100644 index 00000000..9698efc6 --- /dev/null +++ b/assets/css/widget-search-form-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-search-form{display:block;transition:.2s}.elementor-search-form .e-font-icon-svg-container{align-items:center;display:flex;height:100%;justify-content:center;width:100%}.elementor-search-form button,.elementor-search-form input[type=search]{-webkit-appearance:none;-moz-appearance:none;background:none;border:0;display:inline-block;font-size:15px;line-height:1;margin:0;min-width:0;padding:0;vertical-align:middle;white-space:normal}.elementor-search-form button:focus,.elementor-search-form input[type=search]:focus{color:inherit;outline:0}.elementor-search-form button{background-color:#69727d;border-radius:0;color:#fff;font-size:var(--e-search-form-submit-icon-size,16px)}.elementor-search-form__container{border:0 solid transparent;display:flex;min-height:50px;overflow:hidden;transition:.2s}.elementor-search-form__container:not(.elementor-search-form--full-screen){background:#f1f2f3}.elementor-search-form__input{color:#3f444b;flex-basis:100%;transition:color .2s}.elementor-search-form__input::-moz-placeholder{color:inherit;font-family:inherit;opacity:.6}.elementor-search-form__input::placeholder{color:inherit;font-family:inherit;opacity:.6}.elementor-search-form__submit{font-size:var(--e-search-form-submit-icon-size,16px);transition:color .2s,background .2s}.elementor-search-form__submit svg{fill:var(--e-search-form-submit-text-color,#fff);height:var(--e-search-form-submit-icon-size,16px);width:var(--e-search-form-submit-icon-size,16px)}.elementor-search-form .elementor-search-form__submit,.elementor-search-form .elementor-search-form__submit:hover{border:none;border-radius:0;color:var(--e-search-form-submit-text-color,#fff)}.elementor-search-form--button-type-text .elementor-search-form__submit{flex-shrink:0}.elementor-search-form--skin-minimal .elementor-search-form__icon{align-items:center;color:#3f444b;display:flex;justify-content:flex-end;opacity:.6;fill:#3f444b;font-size:var(--e-search-form-icon-size-minimal,15px)}.elementor-search-form--skin-minimal .elementor-search-form__icon svg{height:var(--e-search-form-icon-size-minimal,15px);width:var(--e-search-form-icon-size-minimal,15px)}.elementor-search-form--skin-minimal:focus-within{outline-style:solid;outline-width:2px}.elementor-search-form--skin-full_screen .elementor-search-form input[type=search].elementor-search-form__input{border:solid #fff;border-width:0 0 1px;color:#fff;font-size:50px;line-height:1.5;text-align:center}.elementor-search-form--skin-full_screen .elementor-search-form__toggle{color:var(--e-search-form-toggle-color,#33373d);cursor:pointer;display:inline-block;font-size:var(--e-search-form-toggle-size,33px);vertical-align:middle}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i{background-color:var(--e-search-form-toggle-background-color,rgba(0,0,0,.05));border-color:var(--e-search-form-toggle-color,#33373d);border-radius:var(--e-search-form-toggle-border-radius,3px);border-style:solid;border-width:var(--e-search-form-toggle-border-width,0);display:block;height:var(--e-search-form-toggle-size,33px);position:relative;transition:.2s;width:var(--e-search-form-toggle-size,33px)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container:before,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i:before{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container:before,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i:before{font-size:var(--e-search-form-toggle-icon-size,.55em)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i svg{fill:var(--e-search-form-toggle-color,#33373d);height:var(--e-search-form-toggle-icon-size,.55em);width:var(--e-search-form-toggle-icon-size,.55em)}.elementor-search-form--skin-full_screen .elementor-search-form__container{align-items:center;background-color:rgba(0,0,0,.8);height:100vh;inset:0;padding:0 15%;position:fixed;transition:.3s;z-index:9998}.elementor-search-form--skin-full_screen .elementor-search-form__container:not(.elementor-search-form--full-screen){opacity:0;overflow:hidden;transform:scale(0)}.elementor-search-form--skin-full_screen .elementor-search-form__container:not(.elementor-search-form--full-screen) .dialog-lightbox-close-button{display:none} \ No newline at end of file diff --git a/assets/css/widget-search-form.min.css b/assets/css/widget-search-form.min.css new file mode 100644 index 00000000..9698efc6 --- /dev/null +++ b/assets/css/widget-search-form.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-search-form{display:block;transition:.2s}.elementor-search-form .e-font-icon-svg-container{align-items:center;display:flex;height:100%;justify-content:center;width:100%}.elementor-search-form button,.elementor-search-form input[type=search]{-webkit-appearance:none;-moz-appearance:none;background:none;border:0;display:inline-block;font-size:15px;line-height:1;margin:0;min-width:0;padding:0;vertical-align:middle;white-space:normal}.elementor-search-form button:focus,.elementor-search-form input[type=search]:focus{color:inherit;outline:0}.elementor-search-form button{background-color:#69727d;border-radius:0;color:#fff;font-size:var(--e-search-form-submit-icon-size,16px)}.elementor-search-form__container{border:0 solid transparent;display:flex;min-height:50px;overflow:hidden;transition:.2s}.elementor-search-form__container:not(.elementor-search-form--full-screen){background:#f1f2f3}.elementor-search-form__input{color:#3f444b;flex-basis:100%;transition:color .2s}.elementor-search-form__input::-moz-placeholder{color:inherit;font-family:inherit;opacity:.6}.elementor-search-form__input::placeholder{color:inherit;font-family:inherit;opacity:.6}.elementor-search-form__submit{font-size:var(--e-search-form-submit-icon-size,16px);transition:color .2s,background .2s}.elementor-search-form__submit svg{fill:var(--e-search-form-submit-text-color,#fff);height:var(--e-search-form-submit-icon-size,16px);width:var(--e-search-form-submit-icon-size,16px)}.elementor-search-form .elementor-search-form__submit,.elementor-search-form .elementor-search-form__submit:hover{border:none;border-radius:0;color:var(--e-search-form-submit-text-color,#fff)}.elementor-search-form--button-type-text .elementor-search-form__submit{flex-shrink:0}.elementor-search-form--skin-minimal .elementor-search-form__icon{align-items:center;color:#3f444b;display:flex;justify-content:flex-end;opacity:.6;fill:#3f444b;font-size:var(--e-search-form-icon-size-minimal,15px)}.elementor-search-form--skin-minimal .elementor-search-form__icon svg{height:var(--e-search-form-icon-size-minimal,15px);width:var(--e-search-form-icon-size-minimal,15px)}.elementor-search-form--skin-minimal:focus-within{outline-style:solid;outline-width:2px}.elementor-search-form--skin-full_screen .elementor-search-form input[type=search].elementor-search-form__input{border:solid #fff;border-width:0 0 1px;color:#fff;font-size:50px;line-height:1.5;text-align:center}.elementor-search-form--skin-full_screen .elementor-search-form__toggle{color:var(--e-search-form-toggle-color,#33373d);cursor:pointer;display:inline-block;font-size:var(--e-search-form-toggle-size,33px);vertical-align:middle}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i{background-color:var(--e-search-form-toggle-background-color,rgba(0,0,0,.05));border-color:var(--e-search-form-toggle-color,#33373d);border-radius:var(--e-search-form-toggle-border-radius,3px);border-style:solid;border-width:var(--e-search-form-toggle-border-width,0);display:block;height:var(--e-search-form-toggle-size,33px);position:relative;transition:.2s;width:var(--e-search-form-toggle-size,33px)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container:before,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i:before{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container:before,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i:before{font-size:var(--e-search-form-toggle-icon-size,.55em)}.elementor-search-form--skin-full_screen .elementor-search-form__toggle .e-font-icon-svg-container svg,.elementor-search-form--skin-full_screen .elementor-search-form__toggle i svg{fill:var(--e-search-form-toggle-color,#33373d);height:var(--e-search-form-toggle-icon-size,.55em);width:var(--e-search-form-toggle-icon-size,.55em)}.elementor-search-form--skin-full_screen .elementor-search-form__container{align-items:center;background-color:rgba(0,0,0,.8);height:100vh;inset:0;padding:0 15%;position:fixed;transition:.3s;z-index:9998}.elementor-search-form--skin-full_screen .elementor-search-form__container:not(.elementor-search-form--full-screen){opacity:0;overflow:hidden;transform:scale(0)}.elementor-search-form--skin-full_screen .elementor-search-form__container:not(.elementor-search-form--full-screen) .dialog-lightbox-close-button{display:none} \ No newline at end of file diff --git a/assets/css/widget-search-rtl.min.css b/assets/css/widget-search-rtl.min.css new file mode 100644 index 00000000..0797651d --- /dev/null +++ b/assets/css/widget-search-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-search{--e-search-white:#fff;--e-search-light-grey:#cdcdcd;--e-search-medium-grey:#515962;--e-search-dark-grey:#2d2d2d;--e-search-black:#000;--e-search-dark-red:#c36;--e-search-dark-purple:#336;--e-search-input-color:var(--e-search-medium-grey);--e-search-input-border-color:var(--e-search-light-grey);--e-search-input-border-radius:0;--e-search-input-gap:4px;--e-search-input-padding:16px;--e-search-input-padding-inline-start:16px;--e-search-input-padding-inline-end:16px;--e-search-input-padding-block-start:16px;--e-search-input-padding-block-end:16px;--e-search-input-transition:0.3s;--e-search-placeholder-color:var(--e-search-medium-grey);--e-search-icon-label-color:var(--e-search-medium-grey);--e-search-icon-label-size:24px;--e-search-icon-label-absolute-width:initial;--e-search-icon-clear-color:var(--e-search-light-grey);--e-search-icon-clear-size:12px;--e-search-icon-clear-absolute-width:initial;--e-search-icon-clear-transition:0.3s;--e-search-submit-color:var(--e-search-white);--e-search-submit-background-color:var(--e-search-dark-grey);--e-search-submit-border-color:none;--e-search-submit-border-type:none;--e-search-submit-border-radius:0;--e-search-submit-border-width:0px;--e-search-submit-padding:24px;--e-search-submit-margin-inline-start:8px;--e-search-submit-button-width:initial;--e-search-submit-button-flex-direction:row;--e-search-submit-hover-transition:0.3s;--e-search-pagination-numbers-padding-left:8px;--e-search-pagination-numbers-padding-right:8px;--e-search-icon-submit-color:var(--e-search-white);--e-search-submit-icon-gap:8px;--e-search-submit-icon-margin-inline-start:0px;--e-search-submit-icon-margin-inline-end:var(--e-search-submit-icon-gap);--e-search-icon-submit-size:24px;--e-search-submit-transition:0.3s;--e-search-results-background-color:var(--e-search-white);--e-search-results-border-color:var(--e-search-light-grey);--e-search-results-border-type:solid;--e-search-results-border-width:1px;--e-search-results-border-radius:0px;--e-search-results-padding:16px;--e-search-results-width:100%;--e-search-results-columns:1;--e-search-results-max-height:initial;--e-search-input-and-results-gap:8px;--e-search-results-transition:0.3s;--e-search-loop-item-equal-height:initial;--e-search-results-grid-auto-rows:initial;--e-search-results-inset-inline-start:initial;--e-search-results-inset-inline-end:initial;--e-search-results-transform:initial;--e-search-results-default-gap:16px;--e-search-results-column-gap:var(--e-search-results-default-gap);--e-search-results-row-gap:var(--e-search-results-default-gap);--e-search-pagination-inset-inline-start:initial;--e-search-pagination-inline-end:initial;--e-search-pagination-transform:initial;--e-search-pagination-border-radius:0px;--e-search-pagination-background-color:var(--e-search-black);--e-search-pagination-text-align:center;--e-search-pagination-justify-content:center;--e-search-pagination-color:var(--e-search-dark-red);--e-search-pagination-hover:var(--e-search-dark-purple);--e-search-pagination-current:var(--e-search-black);--e-search-pagination-page-numbers-gap:10px;--e-search-pagination-block-end-spacing:0px;--e-search-pagination-block-start-spacing:0px;--e-search-pagination-vertical-position:column;--e-search-nothing-found-padding-block-start:0;--e-search-nothing-found-padding-block-end:0;--e-search-nothing-found-results-columns:1;--e-search-nothing-found-message-color:var(--e-search-medium-grey);--e-search-nothing-found-message-alignment:center;--e-search-loader-icon-color:var(--e-search-black);--e-search-loader-icon-size:34px}.elementor-widget-search .e-search-form{display:flex}.elementor-widget-search .e-search-label{display:flex;position:relative;z-index:10}.elementor-widget-search .e-search-label>i,.elementor-widget-search .e-search-label>svg{inset-block-start:50%;inset-inline-start:var(--e-search-input-padding-inline-start);position:absolute;transform:translateY(-50%);transition:width 0s,height 0s}.elementor-widget-search .e-search-label>i:is(i),.elementor-widget-search .e-search-label>svg:is(i){color:var(--e-search-icon-label-color);font-size:var(--e-search-icon-label-size)}.elementor-widget-search .e-search-label>i:is(svg),.elementor-widget-search .e-search-label>svg:is(svg){fill:var(--e-search-icon-label-color);height:var(--e-search-icon-label-size);width:auto}.elementor-widget-search .e-search-input-wrapper{display:flex;flex:1;flex-direction:column;position:relative}.elementor-widget-search .e-search-input-wrapper>i,.elementor-widget-search .e-search-input-wrapper>svg{cursor:pointer;inset-block-start:50%;inset-inline-end:var(--e-search-input-padding-inline-end);position:absolute;transform:translateY(-50%);transition:color var(--e-search-icon-clear-transition),fill var(--e-search-icon-clear-transition),width 0s,height 0s}.elementor-widget-search .e-search-input-wrapper>i:is(i),.elementor-widget-search .e-search-input-wrapper>svg:is(i){color:var(--e-search-icon-clear-color);font-size:var(--e-search-icon-clear-size)}.elementor-widget-search .e-search-input-wrapper>i:is(svg),.elementor-widget-search .e-search-input-wrapper>svg:is(svg){fill:var(--e-search-icon-clear-color);height:var(--e-search-icon-clear-size);width:auto}.elementor-widget-search .e-search-input{--e-search-icons-min-height:max(var(--e-search-icon-clear-size),var(--e-search-icon-label-size));border-color:var(--e-search-input-border-color);border-radius:var(--e-search-input-border-radius);color:var(--e-search-input-color);height:100%;min-height:calc(var(--e-search-input-padding-block-end) + var(--e-search-input-padding-block-start) + var(--e-search-icons-min-height));padding-block-end:var(--e-search-input-padding-block-end);padding-block-start:var(--e-search-input-padding-block-start);padding-inline-end:calc(var(--e-search-input-padding-inline-end) + var(--e-search-icon-clear-absolute-width) + var(--e-search-input-gap));padding-inline-start:calc(var(--e-search-input-padding-inline-start) + var(--e-search-icon-label-absolute-width) + var(--e-search-input-gap));transition:padding-inline 0s}.elementor-widget-search .e-search-input::-moz-placeholder{color:var(--e-search-placeholder-color)}.elementor-widget-search .e-search-input::placeholder{color:var(--e-search-placeholder-color)}.elementor-widget-search .e-search-input.no-icon-clear{padding-inline-end:var(--e-search-input-padding-inline-end)}.elementor-widget-search .e-search-input.no-icon-label{padding-inline-start:var(--e-search-input-padding-inline-start)}.elementor-widget-search .e-search-input:focus{outline:none;transition:var(--e-search-input-transition)}.elementor-widget-search .e-search-input::-ms-clear,.elementor-widget-search .e-search-input::-ms-reveal{display:none;height:0;width:0}.elementor-widget-search .e-search-input::-webkit-search-cancel-button,.elementor-widget-search .e-search-input::-webkit-search-decoration,.elementor-widget-search .e-search-input::-webkit-search-results-button,.elementor-widget-search .e-search-input::-webkit-search-results-decoration{display:none}.elementor-widget-search .e-search-results-container{background-color:var(--e-search-results-background-color);border-radius:var(--e-search-results-border-radius);display:flex;height:-moz-fit-content;height:fit-content;inset-block-start:calc(100% + var(--e-search-input-and-results-gap));inset-inline-end:var(--e-search-results-inset-inline-end);inset-inline-start:var(--e-search-results-inset-inline-start);position:absolute;transform:var(--e-search-results-transform);width:var(--e-search-results-width);z-index:2000}.elementor-widget-search .e-search-results-container>div{border:var(--e-search-results-border-type) var(--e-search-results-border-width) var(--e-search-results-border-color);border-radius:var(--e-search-results-border-radius);max-height:var(--e-search-results-max-height);overflow:auto;padding:var(--e-search-results-padding);width:100%}.elementor-widget-search .e-search-results-container>div:empty{display:none}.elementor-widget-search .e-search-results-container>div .e-loop-item .elementor-section-wrap>.e-con,.elementor-widget-search .e-search-results-container>div .e-loop-item>.e-con,.elementor-widget-search .e-search-results-container>div .e-loop-item>.elementor-section,.elementor-widget-search .e-search-results-container>div .e-loop-item>.elementor-section>.elementor-container{height:var(--e-search-loop-item-equal-height)}.elementor-widget-search .e-search-results{display:none}.elementor-widget-search .e-search-results-list{-moz-column-gap:var(--e-search-results-column-gap);column-gap:var(--e-search-results-column-gap);display:grid;grid-auto-rows:var(--e-search-results-grid-auto-rows);grid-template-columns:repeat(var(--e-search-results-columns),1fr);row-gap:var(--e-search-results-row-gap)}.elementor-widget-search .e-search-loader svg{display:flex;width:var(--e-search-loader-icon-size);fill:var(--e-search-loader-icon-color);animation:rotate 4s linear infinite;margin:0 auto;transform:rotate(45deg)}.elementor-widget-search .e-search .e-search-submit{align-items:center;background-color:var(--e-search-submit-background-color);border-color:var(--e-search-submit-border-color);border-radius:var(--e-search-submit-border-radius);border-style:var(--e-search-submit-border-type);border-width:var(--e-search-submit-border-width);color:var(--e-search-submit-color);display:flex;flex-direction:var(--e-search-submit-button-flex-direction);font-size:var(--e-search-form-submit-icon-size);margin-inline-start:var(--e-search-submit-margin-inline-start);padding:var(--e-search-submit-padding);transition:var(--e-search-submit-hover-transition);width:var(--e-search-submit-button-width)}.elementor-widget-search .e-search .e-search-submit:focus{transition:--e-search-submit-transition}.elementor-widget-search .e-search .e-search-submit:focus:not(:focus-visible){outline:none}.elementor-widget-search .e-search .e-search-submit>i,.elementor-widget-search .e-search .e-search-submit>svg{margin-inline-end:var(--e-search-submit-icon-margin-inline-end);margin-inline-start:var(--e-search-submit-icon-margin-inline-start);transition:inherit}.elementor-widget-search .e-search .e-search-submit>i:is(i),.elementor-widget-search .e-search .e-search-submit>svg:is(i){color:var(--e-search-icon-submit-color);font-size:var(--e-search-icon-submit-size)}.elementor-widget-search .e-search .e-search-submit>i:is(svg),.elementor-widget-search .e-search .e-search-submit>svg:is(svg){fill:var(--e-search-icon-submit-color);height:var(--e-search-icon-submit-size);width:auto}.elementor-widget-search .e-search-input-wrapper,.elementor-widget-search .e-search-label *{transition:var(--e-search-input-transition)}.elementor-widget-search .e-search-nothing-found-message{color:var(--e-search-nothing-found-message-color);padding-block-end:var(--e-search-nothing-found-padding-block-end);padding-block-start:var(--e-search-nothing-found-padding-block-start);text-align:var(--e-search-nothing-found-message-alignment)}.elementor-widget-search .hidden{opacity:0;visibility:hidden}.elementor-widget-search .hide-loader .e-search-loader{display:none}.elementor-widget-search .hide-loader .e-search-results{display:flex;flex-direction:var(--e-search-pagination-vertical-position)}.elementor-widget-search .no-results>div{grid-template-columns:var(--e-search-nothing-found-results-columns)}.elementor-widget-search .e-search-results-loader{width:var(--e-search-loader-icon-size);fill:var(--e-search-loader-icon-color);animation:rotate 4s linear infinite;margin:0 auto;transform:rotate(45deg)}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.elementor-widget-search .elementor-pagination{-moz-column-gap:var(--e-search-pagination-page-numbers-gap);column-gap:var(--e-search-pagination-page-numbers-gap);display:flex;justify-content:var(--e-search-pagination-justify-content);padding-block-end:var(--e-search-pagination-block-end-spacing);padding-block-start:var(--e-search-pagination-block-start-spacing)}.elementor-widget-search .elementor-pagination>a{color:var(--e-search-pagination-color)}.elementor-widget-search .elementor-pagination>a:hover{color:var(--e-search-pagination-hover)}.elementor-widget-search .elementor-pagination>.page-numbers.current{color:var(--e-search-pagination-current)}.elementor-widget-search .elementor-pagination>.next,.elementor-widget-search .elementor-pagination>.prev{color:var(--e-search-pagination-color)}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers{display:none}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev{color:var(--e-search-pagination-color);display:initial}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next:hover,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev:hover{color:var(--e-search-pagination-hover)}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next.inactive,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next.inactive:hover,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev.inactive,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev.inactive:hover{color:var(--e-search-pagination-color)} \ No newline at end of file diff --git a/assets/css/widget-search.min.css b/assets/css/widget-search.min.css new file mode 100644 index 00000000..0797651d --- /dev/null +++ b/assets/css/widget-search.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-search{--e-search-white:#fff;--e-search-light-grey:#cdcdcd;--e-search-medium-grey:#515962;--e-search-dark-grey:#2d2d2d;--e-search-black:#000;--e-search-dark-red:#c36;--e-search-dark-purple:#336;--e-search-input-color:var(--e-search-medium-grey);--e-search-input-border-color:var(--e-search-light-grey);--e-search-input-border-radius:0;--e-search-input-gap:4px;--e-search-input-padding:16px;--e-search-input-padding-inline-start:16px;--e-search-input-padding-inline-end:16px;--e-search-input-padding-block-start:16px;--e-search-input-padding-block-end:16px;--e-search-input-transition:0.3s;--e-search-placeholder-color:var(--e-search-medium-grey);--e-search-icon-label-color:var(--e-search-medium-grey);--e-search-icon-label-size:24px;--e-search-icon-label-absolute-width:initial;--e-search-icon-clear-color:var(--e-search-light-grey);--e-search-icon-clear-size:12px;--e-search-icon-clear-absolute-width:initial;--e-search-icon-clear-transition:0.3s;--e-search-submit-color:var(--e-search-white);--e-search-submit-background-color:var(--e-search-dark-grey);--e-search-submit-border-color:none;--e-search-submit-border-type:none;--e-search-submit-border-radius:0;--e-search-submit-border-width:0px;--e-search-submit-padding:24px;--e-search-submit-margin-inline-start:8px;--e-search-submit-button-width:initial;--e-search-submit-button-flex-direction:row;--e-search-submit-hover-transition:0.3s;--e-search-pagination-numbers-padding-left:8px;--e-search-pagination-numbers-padding-right:8px;--e-search-icon-submit-color:var(--e-search-white);--e-search-submit-icon-gap:8px;--e-search-submit-icon-margin-inline-start:0px;--e-search-submit-icon-margin-inline-end:var(--e-search-submit-icon-gap);--e-search-icon-submit-size:24px;--e-search-submit-transition:0.3s;--e-search-results-background-color:var(--e-search-white);--e-search-results-border-color:var(--e-search-light-grey);--e-search-results-border-type:solid;--e-search-results-border-width:1px;--e-search-results-border-radius:0px;--e-search-results-padding:16px;--e-search-results-width:100%;--e-search-results-columns:1;--e-search-results-max-height:initial;--e-search-input-and-results-gap:8px;--e-search-results-transition:0.3s;--e-search-loop-item-equal-height:initial;--e-search-results-grid-auto-rows:initial;--e-search-results-inset-inline-start:initial;--e-search-results-inset-inline-end:initial;--e-search-results-transform:initial;--e-search-results-default-gap:16px;--e-search-results-column-gap:var(--e-search-results-default-gap);--e-search-results-row-gap:var(--e-search-results-default-gap);--e-search-pagination-inset-inline-start:initial;--e-search-pagination-inline-end:initial;--e-search-pagination-transform:initial;--e-search-pagination-border-radius:0px;--e-search-pagination-background-color:var(--e-search-black);--e-search-pagination-text-align:center;--e-search-pagination-justify-content:center;--e-search-pagination-color:var(--e-search-dark-red);--e-search-pagination-hover:var(--e-search-dark-purple);--e-search-pagination-current:var(--e-search-black);--e-search-pagination-page-numbers-gap:10px;--e-search-pagination-block-end-spacing:0px;--e-search-pagination-block-start-spacing:0px;--e-search-pagination-vertical-position:column;--e-search-nothing-found-padding-block-start:0;--e-search-nothing-found-padding-block-end:0;--e-search-nothing-found-results-columns:1;--e-search-nothing-found-message-color:var(--e-search-medium-grey);--e-search-nothing-found-message-alignment:center;--e-search-loader-icon-color:var(--e-search-black);--e-search-loader-icon-size:34px}.elementor-widget-search .e-search-form{display:flex}.elementor-widget-search .e-search-label{display:flex;position:relative;z-index:10}.elementor-widget-search .e-search-label>i,.elementor-widget-search .e-search-label>svg{inset-block-start:50%;inset-inline-start:var(--e-search-input-padding-inline-start);position:absolute;transform:translateY(-50%);transition:width 0s,height 0s}.elementor-widget-search .e-search-label>i:is(i),.elementor-widget-search .e-search-label>svg:is(i){color:var(--e-search-icon-label-color);font-size:var(--e-search-icon-label-size)}.elementor-widget-search .e-search-label>i:is(svg),.elementor-widget-search .e-search-label>svg:is(svg){fill:var(--e-search-icon-label-color);height:var(--e-search-icon-label-size);width:auto}.elementor-widget-search .e-search-input-wrapper{display:flex;flex:1;flex-direction:column;position:relative}.elementor-widget-search .e-search-input-wrapper>i,.elementor-widget-search .e-search-input-wrapper>svg{cursor:pointer;inset-block-start:50%;inset-inline-end:var(--e-search-input-padding-inline-end);position:absolute;transform:translateY(-50%);transition:color var(--e-search-icon-clear-transition),fill var(--e-search-icon-clear-transition),width 0s,height 0s}.elementor-widget-search .e-search-input-wrapper>i:is(i),.elementor-widget-search .e-search-input-wrapper>svg:is(i){color:var(--e-search-icon-clear-color);font-size:var(--e-search-icon-clear-size)}.elementor-widget-search .e-search-input-wrapper>i:is(svg),.elementor-widget-search .e-search-input-wrapper>svg:is(svg){fill:var(--e-search-icon-clear-color);height:var(--e-search-icon-clear-size);width:auto}.elementor-widget-search .e-search-input{--e-search-icons-min-height:max(var(--e-search-icon-clear-size),var(--e-search-icon-label-size));border-color:var(--e-search-input-border-color);border-radius:var(--e-search-input-border-radius);color:var(--e-search-input-color);height:100%;min-height:calc(var(--e-search-input-padding-block-end) + var(--e-search-input-padding-block-start) + var(--e-search-icons-min-height));padding-block-end:var(--e-search-input-padding-block-end);padding-block-start:var(--e-search-input-padding-block-start);padding-inline-end:calc(var(--e-search-input-padding-inline-end) + var(--e-search-icon-clear-absolute-width) + var(--e-search-input-gap));padding-inline-start:calc(var(--e-search-input-padding-inline-start) + var(--e-search-icon-label-absolute-width) + var(--e-search-input-gap));transition:padding-inline 0s}.elementor-widget-search .e-search-input::-moz-placeholder{color:var(--e-search-placeholder-color)}.elementor-widget-search .e-search-input::placeholder{color:var(--e-search-placeholder-color)}.elementor-widget-search .e-search-input.no-icon-clear{padding-inline-end:var(--e-search-input-padding-inline-end)}.elementor-widget-search .e-search-input.no-icon-label{padding-inline-start:var(--e-search-input-padding-inline-start)}.elementor-widget-search .e-search-input:focus{outline:none;transition:var(--e-search-input-transition)}.elementor-widget-search .e-search-input::-ms-clear,.elementor-widget-search .e-search-input::-ms-reveal{display:none;height:0;width:0}.elementor-widget-search .e-search-input::-webkit-search-cancel-button,.elementor-widget-search .e-search-input::-webkit-search-decoration,.elementor-widget-search .e-search-input::-webkit-search-results-button,.elementor-widget-search .e-search-input::-webkit-search-results-decoration{display:none}.elementor-widget-search .e-search-results-container{background-color:var(--e-search-results-background-color);border-radius:var(--e-search-results-border-radius);display:flex;height:-moz-fit-content;height:fit-content;inset-block-start:calc(100% + var(--e-search-input-and-results-gap));inset-inline-end:var(--e-search-results-inset-inline-end);inset-inline-start:var(--e-search-results-inset-inline-start);position:absolute;transform:var(--e-search-results-transform);width:var(--e-search-results-width);z-index:2000}.elementor-widget-search .e-search-results-container>div{border:var(--e-search-results-border-type) var(--e-search-results-border-width) var(--e-search-results-border-color);border-radius:var(--e-search-results-border-radius);max-height:var(--e-search-results-max-height);overflow:auto;padding:var(--e-search-results-padding);width:100%}.elementor-widget-search .e-search-results-container>div:empty{display:none}.elementor-widget-search .e-search-results-container>div .e-loop-item .elementor-section-wrap>.e-con,.elementor-widget-search .e-search-results-container>div .e-loop-item>.e-con,.elementor-widget-search .e-search-results-container>div .e-loop-item>.elementor-section,.elementor-widget-search .e-search-results-container>div .e-loop-item>.elementor-section>.elementor-container{height:var(--e-search-loop-item-equal-height)}.elementor-widget-search .e-search-results{display:none}.elementor-widget-search .e-search-results-list{-moz-column-gap:var(--e-search-results-column-gap);column-gap:var(--e-search-results-column-gap);display:grid;grid-auto-rows:var(--e-search-results-grid-auto-rows);grid-template-columns:repeat(var(--e-search-results-columns),1fr);row-gap:var(--e-search-results-row-gap)}.elementor-widget-search .e-search-loader svg{display:flex;width:var(--e-search-loader-icon-size);fill:var(--e-search-loader-icon-color);animation:rotate 4s linear infinite;margin:0 auto;transform:rotate(45deg)}.elementor-widget-search .e-search .e-search-submit{align-items:center;background-color:var(--e-search-submit-background-color);border-color:var(--e-search-submit-border-color);border-radius:var(--e-search-submit-border-radius);border-style:var(--e-search-submit-border-type);border-width:var(--e-search-submit-border-width);color:var(--e-search-submit-color);display:flex;flex-direction:var(--e-search-submit-button-flex-direction);font-size:var(--e-search-form-submit-icon-size);margin-inline-start:var(--e-search-submit-margin-inline-start);padding:var(--e-search-submit-padding);transition:var(--e-search-submit-hover-transition);width:var(--e-search-submit-button-width)}.elementor-widget-search .e-search .e-search-submit:focus{transition:--e-search-submit-transition}.elementor-widget-search .e-search .e-search-submit:focus:not(:focus-visible){outline:none}.elementor-widget-search .e-search .e-search-submit>i,.elementor-widget-search .e-search .e-search-submit>svg{margin-inline-end:var(--e-search-submit-icon-margin-inline-end);margin-inline-start:var(--e-search-submit-icon-margin-inline-start);transition:inherit}.elementor-widget-search .e-search .e-search-submit>i:is(i),.elementor-widget-search .e-search .e-search-submit>svg:is(i){color:var(--e-search-icon-submit-color);font-size:var(--e-search-icon-submit-size)}.elementor-widget-search .e-search .e-search-submit>i:is(svg),.elementor-widget-search .e-search .e-search-submit>svg:is(svg){fill:var(--e-search-icon-submit-color);height:var(--e-search-icon-submit-size);width:auto}.elementor-widget-search .e-search-input-wrapper,.elementor-widget-search .e-search-label *{transition:var(--e-search-input-transition)}.elementor-widget-search .e-search-nothing-found-message{color:var(--e-search-nothing-found-message-color);padding-block-end:var(--e-search-nothing-found-padding-block-end);padding-block-start:var(--e-search-nothing-found-padding-block-start);text-align:var(--e-search-nothing-found-message-alignment)}.elementor-widget-search .hidden{opacity:0;visibility:hidden}.elementor-widget-search .hide-loader .e-search-loader{display:none}.elementor-widget-search .hide-loader .e-search-results{display:flex;flex-direction:var(--e-search-pagination-vertical-position)}.elementor-widget-search .no-results>div{grid-template-columns:var(--e-search-nothing-found-results-columns)}.elementor-widget-search .e-search-results-loader{width:var(--e-search-loader-icon-size);fill:var(--e-search-loader-icon-color);animation:rotate 4s linear infinite;margin:0 auto;transform:rotate(45deg)}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.elementor-widget-search .elementor-pagination{-moz-column-gap:var(--e-search-pagination-page-numbers-gap);column-gap:var(--e-search-pagination-page-numbers-gap);display:flex;justify-content:var(--e-search-pagination-justify-content);padding-block-end:var(--e-search-pagination-block-end-spacing);padding-block-start:var(--e-search-pagination-block-start-spacing)}.elementor-widget-search .elementor-pagination>a{color:var(--e-search-pagination-color)}.elementor-widget-search .elementor-pagination>a:hover{color:var(--e-search-pagination-hover)}.elementor-widget-search .elementor-pagination>.page-numbers.current{color:var(--e-search-pagination-current)}.elementor-widget-search .elementor-pagination>.next,.elementor-widget-search .elementor-pagination>.prev{color:var(--e-search-pagination-color)}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers{display:none}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev{color:var(--e-search-pagination-color);display:initial}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next:hover,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev:hover{color:var(--e-search-pagination-hover)}.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next.inactive,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.next.inactive:hover,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev.inactive,.elementor-widget-search .hide-pagination-numbers .elementor-pagination>.page-numbers.prev.inactive:hover{color:var(--e-search-pagination-color)} \ No newline at end of file diff --git a/assets/css/widget-share-buttons-rtl.min.css b/assets/css/widget-share-buttons-rtl.min.css new file mode 100644 index 00000000..09b6aaae --- /dev/null +++ b/assets/css/widget-share-buttons-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn{background-color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__text,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__text{color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__text svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__text svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn{border-color:var(--e-share-buttons-primary-color,#ea4335);color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn__icon{background-color:var(--e-share-buttons-primary-color,#ea4335);color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn__icon svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn__icon{color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn__icon svg{fill:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-official .elementor-share-btn:hover{filter:saturate(1.5) brightness(1.2)}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_digg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_digg{background-color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_email,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_email{background-color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_print,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_print{background-color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_facebook,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_facebook{background-color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_google,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_google{background-color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_pocket,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_pocket{background-color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_linkedin,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_linkedin{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_odnoklassniki,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_odnoklassniki{background-color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_pinterest,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_pinterest{background-color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_reddit,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_reddit{background-color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_skype,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_skype{background-color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_slideshare,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_slideshare{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_snapchat,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_snapchat{background-color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_stumbleupon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_stumbleupon{background-color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_mix,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_mix{background-color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_tumblr,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_tumblr{background-color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_twitch,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_twitch{background-color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_telegram,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_telegram{background-color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_threads,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_threads{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_twitter{background-color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_vimeo,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_vimeo{background-color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_vk,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_vk{background-color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_whatsapp,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_whatsapp{background-color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_wordpress,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_wordpress{background-color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_x-twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_x-twitter{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_xing,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_xing{background-color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_digg{color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_digg svg{fill:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_email{color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_email svg{fill:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_print{color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_print svg{fill:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_facebook{color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_facebook svg{fill:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_google{color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_google svg{fill:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pocket{color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pocket svg{fill:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_linkedin{color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_linkedin svg{fill:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_odnoklassniki{color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_odnoklassniki svg{fill:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pinterest{color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pinterest svg{fill:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_reddit{color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_reddit svg{fill:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_skype{color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_skype svg{fill:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_slideshare{color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_slideshare svg{fill:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_snapchat{color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_snapchat svg{fill:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_stumbleupon{color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_stumbleupon svg{fill:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_mix{color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_mix svg{fill:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_tumblr{color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_tumblr svg{fill:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitch{color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitch svg{fill:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_telegram{color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_telegram svg{fill:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_threads{color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_threads svg{fill:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitter{color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitter svg{fill:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vimeo{color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vimeo svg{fill:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vk{color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vk svg{fill:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_whatsapp{color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_whatsapp svg{fill:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_wordpress{color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_wordpress svg{fill:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_x-twitter{color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_x-twitter svg{fill:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_xing{color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_xing svg{fill:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_digg .elementor-share-btn__icon{background-color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_email .elementor-share-btn__icon{background-color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_print .elementor-share-btn__icon{background-color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_facebook .elementor-share-btn__icon{background-color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_google .elementor-share-btn__icon{background-color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_pocket .elementor-share-btn__icon{background-color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_linkedin .elementor-share-btn__icon{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_odnoklassniki .elementor-share-btn__icon{background-color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_pinterest .elementor-share-btn__icon{background-color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_reddit .elementor-share-btn__icon{background-color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_skype .elementor-share-btn__icon{background-color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_slideshare .elementor-share-btn__icon{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_snapchat .elementor-share-btn__icon{background-color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_stumbleupon .elementor-share-btn__icon{background-color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_mix .elementor-share-btn__icon{background-color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_tumblr .elementor-share-btn__icon{background-color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_twitch .elementor-share-btn__icon{background-color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_telegram .elementor-share-btn__icon{background-color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_threads .elementor-share-btn__icon{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_twitter .elementor-share-btn__icon{background-color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_vimeo .elementor-share-btn__icon{background-color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_vk .elementor-share-btn__icon{background-color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_whatsapp .elementor-share-btn__icon{background-color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_wordpress .elementor-share-btn__icon{background-color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_x-twitter .elementor-share-btn__icon{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_xing .elementor-share-btn__icon{background-color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn .elementor-share-btn__icon{color:var(--e-share-buttons-icon-color,#fff)}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn .elementor-share-btn__icon svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn .elementor-share-btn__icon svg{fill:var(--e-share-buttons-icon-color,#fff)}.elementor-share-buttons--skin-boxed .elementor-share-btn__icon,.elementor-share-buttons--skin-framed .elementor-share-btn__icon{margin-inline-start:-.2em}.elementor-share-buttons--skin-boxed .elementor-share-btn,.elementor-share-buttons--skin-framed .elementor-share-btn{border-style:solid}.elementor-share-buttons--skin-gradient .elementor-share-btn__text,.elementor-share-buttons--skin-gradient.elementor-share-buttons--view-icon .elementor-share-btn__icon{background-image:linear-gradient(calc(90deg * var(--direction-multiplier, 1)),rgba(0,0,0,.12),transparent)}.elementor-share-buttons--skin-boxed .elementor-share-btn__text,.elementor-share-buttons--skin-gradient .elementor-share-btn__text,.elementor-share-buttons--skin-minimal .elementor-share-btn__text{padding-inline-start:.9em}.elementor-share-buttons--skin-flat .elementor-share-btn,.elementor-share-buttons--skin-gradient .elementor-share-btn{background-color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--skin-flat .elementor-share-btn__icon,.elementor-share-buttons--skin-flat .elementor-share-btn__text,.elementor-share-buttons--skin-gradient .elementor-share-btn__icon,.elementor-share-buttons--skin-gradient .elementor-share-btn__text{color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--skin-flat .elementor-share-btn__icon svg,.elementor-share-buttons--skin-flat .elementor-share-btn__text svg,.elementor-share-buttons--skin-gradient .elementor-share-btn__icon svg,.elementor-share-buttons--skin-gradient .elementor-share-btn__text svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--skin-minimal.elementor-share-buttons--shape-rounded .elementor-share-btn__icon{border-radius:.5em}.elementor-share-buttons--skin-minimal.elementor-share-buttons--shape-circle .elementor-share-btn__icon{border-radius:99.9em}.elementor-share-buttons--view-text .elementor-share-btn__text{padding-inline-start:1em}.elementor-share-buttons--view-icon .elementor-share-btn,.elementor-share-buttons--view-text .elementor-share-btn{justify-content:center}.elementor-share-buttons--view-icon .elementor-share-btn__icon,.elementor-share-buttons--view-icon .elementor-share-btn__text,.elementor-share-buttons--view-text .elementor-share-btn__icon,.elementor-share-buttons--view-text .elementor-share-btn__text{flex-grow:1;justify-content:center}.elementor-share-buttons--shape-rounded .elementor-share-btn{border-radius:.5em}.elementor-share-buttons--shape-circle .elementor-share-btn{border-radius:99.9em}.elementor-share-btn{align-items:center;cursor:pointer;display:flex;font-size:10px;height:4.5em;justify-content:flex-start;overflow:hidden;transition-duration:.2s;transition-property:filter,background-color,border-color}.elementor-share-btn__icon,.elementor-share-btn__text{transition-duration:.2s;transition-property:color,background-color}.elementor-share-btn__icon{align-items:center;align-self:stretch;display:flex;justify-content:center;position:relative;width:4.5em}.elementor-share-btn__icon i{font-size:var(--e-share-buttons-icon-size,1.7em)}.elementor-share-btn__icon svg{height:var(--e-share-buttons-icon-size,1.7em);width:var(--e-share-buttons-icon-size,1.7em)}.elementor-share-btn__text{align-items:center;align-self:stretch;display:flex;flex-grow:1;font-size:1.5em;font-weight:100;padding-inline-end:1em}.elementor-share-btn__title{flex-shrink:0;font-weight:700}.elementor-widget-share-buttons{text-align:var(--alignment,inherit);-moz-text-align-last:var(--alignment,inherit);text-align-last:var(--alignment,inherit)}.elementor-widget-share-buttons.elementor-grid-0 .elementor-widget-container,.elementor-widget-share-buttons.elementor-grid-0:not(:has(.elementor-widget-container)){font-size:0} \ No newline at end of file diff --git a/assets/css/widget-share-buttons.min.css b/assets/css/widget-share-buttons.min.css new file mode 100644 index 00000000..09b6aaae --- /dev/null +++ b/assets/css/widget-share-buttons.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn{background-color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__text,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__text{color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-flat .elementor-share-btn__text svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-gradient .elementor-share-btn__text svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn{border-color:var(--e-share-buttons-primary-color,#ea4335);color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn__icon,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn__icon{background-color:var(--e-share-buttons-primary-color,#ea4335);color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-boxed .elementor-share-btn__icon svg,.elementor-share-buttons--color-custom.elementor-share-buttons--skin-minimal .elementor-share-btn__icon svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn__icon{color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-custom.elementor-share-buttons--skin-framed .elementor-share-btn__icon svg{fill:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--color-official .elementor-share-btn:hover{filter:saturate(1.5) brightness(1.2)}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_digg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_digg{background-color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_email,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_email{background-color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_print,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_print{background-color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_facebook,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_facebook{background-color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_google,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_google{background-color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_pocket,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_pocket{background-color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_linkedin,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_linkedin{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_odnoklassniki,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_odnoklassniki{background-color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_pinterest,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_pinterest{background-color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_reddit,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_reddit{background-color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_skype,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_skype{background-color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_slideshare,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_slideshare{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_snapchat,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_snapchat{background-color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_stumbleupon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_stumbleupon{background-color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_mix,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_mix{background-color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_tumblr,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_tumblr{background-color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_twitch,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_twitch{background-color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_telegram,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_telegram{background-color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_threads,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_threads{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_twitter{background-color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_vimeo,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_vimeo{background-color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_vk,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_vk{background-color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_whatsapp,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_whatsapp{background-color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_wordpress,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_wordpress{background-color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_x-twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_x-twitter{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-flat .elementor-share-btn_xing,.elementor-share-buttons--color-official.elementor-share-buttons--skin-gradient .elementor-share-btn_xing{background-color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_digg{color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_digg svg{fill:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_email{color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_email svg{fill:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_print{color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_print svg{fill:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_facebook{color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_facebook svg{fill:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_google{color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_google svg{fill:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pocket{color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pocket svg{fill:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_linkedin{color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_linkedin svg{fill:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_odnoklassniki{color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_odnoklassniki svg{fill:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pinterest{color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_pinterest svg{fill:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_reddit{color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_reddit svg{fill:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_skype{color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_skype svg{fill:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_slideshare{color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_slideshare svg{fill:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_snapchat{color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_snapchat svg{fill:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_stumbleupon{color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_stumbleupon svg{fill:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_mix{color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_mix svg{fill:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_tumblr{color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_tumblr svg{fill:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitch{color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitch svg{fill:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_telegram{color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_telegram svg{fill:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_threads{color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_threads svg{fill:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitter{color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_twitter svg{fill:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vimeo{color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vimeo svg{fill:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vk{color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_vk svg{fill:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_whatsapp{color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_whatsapp svg{fill:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_wordpress{color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_wordpress svg{fill:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_x-twitter{color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_x-twitter svg{fill:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_xing{color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-framed .elementor-share-btn_xing svg{fill:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_digg .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_digg .elementor-share-btn__icon{background-color:#005be2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_email .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_email .elementor-share-btn__icon{background-color:#ea4335}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_print .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_print .elementor-share-btn__icon{background-color:#aaa}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_facebook .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_facebook .elementor-share-btn__icon{background-color:#3b5998}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_google .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_google .elementor-share-btn__icon{background-color:#dd4b39}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pocket .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_pocket .elementor-share-btn__icon{background-color:#ef3f56}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_linkedin .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_linkedin .elementor-share-btn__icon{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_odnoklassniki .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_odnoklassniki .elementor-share-btn__icon{background-color:#f4731c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_pinterest .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_pinterest .elementor-share-btn__icon{background-color:#bd081c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_reddit .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_reddit .elementor-share-btn__icon{background-color:#ff4500}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_skype .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_skype .elementor-share-btn__icon{background-color:#00aff0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_slideshare .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_slideshare .elementor-share-btn__icon{background-color:#0077b5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_snapchat .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_snapchat .elementor-share-btn__icon{background-color:#fffc00}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_stumbleupon .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_stumbleupon .elementor-share-btn__icon{background-color:#eb4924}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_mix .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_mix .elementor-share-btn__icon{background-color:#f3782b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_tumblr .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_tumblr .elementor-share-btn__icon{background-color:#35465c}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitch .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_twitch .elementor-share-btn__icon{background-color:#6441a5}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_telegram .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_telegram .elementor-share-btn__icon{background-color:#2ca5e0}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_threads .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_threads .elementor-share-btn__icon{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_twitter .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_twitter .elementor-share-btn__icon{background-color:#1da1f2}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vimeo .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_vimeo .elementor-share-btn__icon{background-color:#1ab7ea}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_vk .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_vk .elementor-share-btn__icon{background-color:#45668e}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_whatsapp .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_whatsapp .elementor-share-btn__icon{background-color:#25d366}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_wordpress .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_wordpress .elementor-share-btn__icon{background-color:#21759b}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_x-twitter .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_x-twitter .elementor-share-btn__icon{background-color:#000}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn_xing .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn_xing .elementor-share-btn__icon{background-color:#026466}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn .elementor-share-btn__icon,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn .elementor-share-btn__icon{color:var(--e-share-buttons-icon-color,#fff)}.elementor-share-buttons--color-official.elementor-share-buttons--skin-boxed .elementor-share-btn .elementor-share-btn__icon svg,.elementor-share-buttons--color-official.elementor-share-buttons--skin-minimal .elementor-share-btn .elementor-share-btn__icon svg{fill:var(--e-share-buttons-icon-color,#fff)}.elementor-share-buttons--skin-boxed .elementor-share-btn__icon,.elementor-share-buttons--skin-framed .elementor-share-btn__icon{margin-inline-start:-.2em}.elementor-share-buttons--skin-boxed .elementor-share-btn,.elementor-share-buttons--skin-framed .elementor-share-btn{border-style:solid}.elementor-share-buttons--skin-gradient .elementor-share-btn__text,.elementor-share-buttons--skin-gradient.elementor-share-buttons--view-icon .elementor-share-btn__icon{background-image:linear-gradient(calc(90deg * var(--direction-multiplier, 1)),rgba(0,0,0,.12),transparent)}.elementor-share-buttons--skin-boxed .elementor-share-btn__text,.elementor-share-buttons--skin-gradient .elementor-share-btn__text,.elementor-share-buttons--skin-minimal .elementor-share-btn__text{padding-inline-start:.9em}.elementor-share-buttons--skin-flat .elementor-share-btn,.elementor-share-buttons--skin-gradient .elementor-share-btn{background-color:var(--e-share-buttons-primary-color,#ea4335)}.elementor-share-buttons--skin-flat .elementor-share-btn__icon,.elementor-share-buttons--skin-flat .elementor-share-btn__text,.elementor-share-buttons--skin-gradient .elementor-share-btn__icon,.elementor-share-buttons--skin-gradient .elementor-share-btn__text{color:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--skin-flat .elementor-share-btn__icon svg,.elementor-share-buttons--skin-flat .elementor-share-btn__text svg,.elementor-share-buttons--skin-gradient .elementor-share-btn__icon svg,.elementor-share-buttons--skin-gradient .elementor-share-btn__text svg{fill:var(--e-share-buttons-secondary-color,#fff)}.elementor-share-buttons--skin-minimal.elementor-share-buttons--shape-rounded .elementor-share-btn__icon{border-radius:.5em}.elementor-share-buttons--skin-minimal.elementor-share-buttons--shape-circle .elementor-share-btn__icon{border-radius:99.9em}.elementor-share-buttons--view-text .elementor-share-btn__text{padding-inline-start:1em}.elementor-share-buttons--view-icon .elementor-share-btn,.elementor-share-buttons--view-text .elementor-share-btn{justify-content:center}.elementor-share-buttons--view-icon .elementor-share-btn__icon,.elementor-share-buttons--view-icon .elementor-share-btn__text,.elementor-share-buttons--view-text .elementor-share-btn__icon,.elementor-share-buttons--view-text .elementor-share-btn__text{flex-grow:1;justify-content:center}.elementor-share-buttons--shape-rounded .elementor-share-btn{border-radius:.5em}.elementor-share-buttons--shape-circle .elementor-share-btn{border-radius:99.9em}.elementor-share-btn{align-items:center;cursor:pointer;display:flex;font-size:10px;height:4.5em;justify-content:flex-start;overflow:hidden;transition-duration:.2s;transition-property:filter,background-color,border-color}.elementor-share-btn__icon,.elementor-share-btn__text{transition-duration:.2s;transition-property:color,background-color}.elementor-share-btn__icon{align-items:center;align-self:stretch;display:flex;justify-content:center;position:relative;width:4.5em}.elementor-share-btn__icon i{font-size:var(--e-share-buttons-icon-size,1.7em)}.elementor-share-btn__icon svg{height:var(--e-share-buttons-icon-size,1.7em);width:var(--e-share-buttons-icon-size,1.7em)}.elementor-share-btn__text{align-items:center;align-self:stretch;display:flex;flex-grow:1;font-size:1.5em;font-weight:100;padding-inline-end:1em}.elementor-share-btn__title{flex-shrink:0;font-weight:700}.elementor-widget-share-buttons{text-align:var(--alignment,inherit);-moz-text-align-last:var(--alignment,inherit);text-align-last:var(--alignment,inherit)}.elementor-widget-share-buttons.elementor-grid-0 .elementor-widget-container,.elementor-widget-share-buttons.elementor-grid-0:not(:has(.elementor-widget-container)){font-size:0} \ No newline at end of file diff --git a/assets/css/widget-sitemap-rtl.min.css b/assets/css/widget-sitemap-rtl.min.css new file mode 100644 index 00000000..633d35d8 --- /dev/null +++ b/assets/css/widget-sitemap-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-sitemap-wrap{display:flex;flex-flow:row wrap} \ No newline at end of file diff --git a/assets/css/widget-sitemap.min.css b/assets/css/widget-sitemap.min.css new file mode 100644 index 00000000..633d35d8 --- /dev/null +++ b/assets/css/widget-sitemap.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-sitemap-wrap{display:flex;flex-flow:row wrap} \ No newline at end of file diff --git a/assets/css/widget-slides-rtl.min.css b/assets/css/widget-slides-rtl.min.css new file mode 100644 index 00000000..ffdfb342 --- /dev/null +++ b/assets/css/widget-slides-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-slides .swiper-slide-bg{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%}.elementor-slides .swiper-slide-inner{background-position:50%;background-repeat:no-repeat;inset:0;margin:auto;padding:50px;position:absolute}.elementor-slides .swiper-slide-inner,.elementor-slides .swiper-slide-inner:hover{color:#fff;display:flex}.elementor-slides .swiper-slide-inner .elementor-background-overlay{inset:0;position:absolute;z-index:0}.elementor-slides .swiper-slide-inner .elementor-slide-content{position:relative;width:100%;z-index:1}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:35px;font-weight:700;line-height:1}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:17px;line-height:1.4}.elementor-slides .swiper-slide-inner .elementor-slide-description:not(:last-child),.elementor-slides .swiper-slide-inner .elementor-slide-heading:not(:last-child){margin-bottom:30px}.elementor-slides .swiper-slide-inner .elementor-slide-button{background:transparent;border:2px solid #fff;color:#fff;display:inline-block}.elementor-slides .swiper-slide-inner .elementor-slide-button,.elementor-slides .swiper-slide-inner .elementor-slide-button:hover{background:transparent;color:inherit;text-decoration:none}.elementor--v-position-top .swiper-slide-inner{align-items:flex-start}.elementor--v-position-bottom .swiper-slide-inner{align-items:flex-end}.elementor--v-position-middle .swiper-slide-inner{align-items:center}.elementor--h-position-left .swiper-slide-inner{justify-content:flex-end}.elementor--h-position-right .swiper-slide-inner{justify-content:flex-start}.elementor--h-position-center .swiper-slide-inner{justify-content:center}body.rtl .elementor-widget-slides .elementor-swiper-button-next{left:10px;right:auto}body.rtl .elementor-widget-slides .elementor-swiper-button-prev{left:auto;right:10px}.elementor-slides-wrapper div:not(.swiper-slide)>.swiper-slide-inner{display:none}@media (max-width:767px){.elementor-slides .swiper-slide-inner{padding:30px}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:23px;line-height:1;margin-bottom:15px}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:13px;line-height:1.4;margin-bottom:15px}} \ No newline at end of file diff --git a/assets/css/widget-slides.min.css b/assets/css/widget-slides.min.css new file mode 100644 index 00000000..b35afcbd --- /dev/null +++ b/assets/css/widget-slides.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-slides .swiper-slide-bg{background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100%;min-width:100%}.elementor-slides .swiper-slide-inner{background-position:50%;background-repeat:no-repeat;inset:0;margin:auto;padding:50px;position:absolute}.elementor-slides .swiper-slide-inner,.elementor-slides .swiper-slide-inner:hover{color:#fff;display:flex}.elementor-slides .swiper-slide-inner .elementor-background-overlay{inset:0;position:absolute;z-index:0}.elementor-slides .swiper-slide-inner .elementor-slide-content{position:relative;width:100%;z-index:1}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:35px;font-weight:700;line-height:1}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:17px;line-height:1.4}.elementor-slides .swiper-slide-inner .elementor-slide-description:not(:last-child),.elementor-slides .swiper-slide-inner .elementor-slide-heading:not(:last-child){margin-bottom:30px}.elementor-slides .swiper-slide-inner .elementor-slide-button{background:transparent;border:2px solid #fff;color:#fff;display:inline-block}.elementor-slides .swiper-slide-inner .elementor-slide-button,.elementor-slides .swiper-slide-inner .elementor-slide-button:hover{background:transparent;color:inherit;text-decoration:none}.elementor--v-position-top .swiper-slide-inner{align-items:flex-start}.elementor--v-position-bottom .swiper-slide-inner{align-items:flex-end}.elementor--v-position-middle .swiper-slide-inner{align-items:center}.elementor--h-position-left .swiper-slide-inner{justify-content:flex-start}.elementor--h-position-right .swiper-slide-inner{justify-content:flex-end}.elementor--h-position-center .swiper-slide-inner{justify-content:center}body.rtl .elementor-widget-slides .elementor-swiper-button-next{left:10px;right:auto}body.rtl .elementor-widget-slides .elementor-swiper-button-prev{left:auto;right:10px}.elementor-slides-wrapper div:not(.swiper-slide)>.swiper-slide-inner{display:none}@media (max-width:767px){.elementor-slides .swiper-slide-inner{padding:30px}.elementor-slides .swiper-slide-inner .elementor-slide-heading{font-size:23px;line-height:1;margin-bottom:15px}.elementor-slides .swiper-slide-inner .elementor-slide-description{font-size:13px;line-height:1.4;margin-bottom:15px}} \ No newline at end of file diff --git a/assets/css/widget-social-rtl.min.css b/assets/css/widget-social-rtl.min.css new file mode 100644 index 00000000..aed0c444 --- /dev/null +++ b/assets/css/widget-social-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-facebook-widget.fb_iframe_widget,.elementor-facebook-widget.fb_iframe_widget span{width:100%!important}.elementor-facebook-widget.fb_iframe_widget iframe{position:relative;width:100%!important}.elementor-facebook-widget.fb-like{height:1px}.elementor-widget-facebook-comments iframe{width:100%!important} \ No newline at end of file diff --git a/assets/css/widget-social.min.css b/assets/css/widget-social.min.css new file mode 100644 index 00000000..aed0c444 --- /dev/null +++ b/assets/css/widget-social.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-facebook-widget.fb_iframe_widget,.elementor-facebook-widget.fb_iframe_widget span{width:100%!important}.elementor-facebook-widget.fb_iframe_widget iframe{position:relative;width:100%!important}.elementor-facebook-widget.fb-like{height:1px}.elementor-widget-facebook-comments iframe{width:100%!important} \ No newline at end of file diff --git a/assets/css/widget-table-of-contents-rtl.min.css b/assets/css/widget-table-of-contents-rtl.min.css new file mode 100644 index 00000000..0497cf21 --- /dev/null +++ b/assets/css/widget-table-of-contents-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-table-of-contents .elementor-toc__header-title{color:var(--header-color)}.elementor-widget-table-of-contents.elementor-toc--collapsed .elementor-toc__toggle-button--collapse,.elementor-widget-table-of-contents:not(.elementor-toc--collapsed) .elementor-toc__toggle-button--expand{display:none}.elementor-widget-table-of-contents .elementor-widget-container,.elementor-widget-table-of-contents:not(:has(.elementor-widget-container)){background-color:var(--box-background-color);border:var(--box-border-width,1px) solid var(--box-border-color,#9da5ae);border-radius:var(--box-border-radius,3px);min-height:var(--box-min-height);overflow:hidden;transition:min-height .4s}.elementor-toc__header{align-items:center;background-color:var(--header-background-color);border-bottom:var(--separator-width,1px) solid var(--box-border-color,#9da5ae);display:flex;justify-content:flex-end;padding:var(--box-padding,20px)}.elementor-toc__header-title{color:var(--header-color);flex-grow:1;font-size:18px;margin:0}.elementor-toc__toggle-button{cursor:pointer;display:inline-flex}.elementor-toc__toggle-button i{color:var(--toggle-button-color)}.elementor-toc__toggle-button svg{height:1em;width:1em;fill:var(--toggle-button-color)}.elementor-toc__spinner-container{text-align:center}.elementor-toc__spinner{font-size:2em}.elementor-toc__spinner.e-font-icon-svg{height:1em;width:1em}.elementor-toc__body{max-height:var(--toc-body-max-height);overflow-y:auto;padding:var(--box-padding,20px)}.elementor-toc__body::-webkit-scrollbar{width:7px}.elementor-toc__body::-webkit-scrollbar-thumb{background-color:#babfc5;border-radius:10px}.elementor-toc__list-wrapper{list-style:none;padding:0}.elementor-toc__list-item{margin-bottom:.5em}.elementor-toc__list-item.elementor-item-active{font-weight:700}.elementor-toc__list-item .elementor-toc__list-wrapper{margin-top:.5em;margin-inline-start:var(--nested-list-indent,1em)}.elementor-toc__list-item-text{transition-duration:var(--item-text-transition-duration)}.elementor-toc__list-item-text:hover{color:var(--item-text-hover-color);-webkit-text-decoration:var(--item-text-hover-decoration);text-decoration:var(--item-text-hover-decoration)}.elementor-toc__list-item-text.elementor-item-active{color:var(--item-text-active-color);-webkit-text-decoration:var(--item-text-active-decoration);text-decoration:var(--item-text-active-decoration)}.elementor-toc__list-item-text-wrapper{align-items:center;display:flex}.elementor-toc__list-item-text-wrapper i,.elementor-toc__list-item-text-wrapper:before{color:var(--marker-color);margin-inline-end:8px}.elementor-toc__list-item-text-wrapper svg{margin-inline-end:8px;fill:var(--marker-color);height:var(--marker-size,.5em);width:var(--marker-size,.5em)}.elementor-toc__list-item-text-wrapper i{font-size:var(--marker-size,.5em)}.elementor-toc__list-item-text-wrapper:before{font-size:var(--marker-size,1em)}.elementor-toc--content-ellipsis .elementor-toc__list-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.elementor-toc__list-items--collapsible>.elementor-toc__list-wrapper>.elementor-toc__list-item>.elementor-toc__list-wrapper{display:none}.elementor-toc__heading-anchor{position:absolute}.elementor-toc__body .elementor-toc__list-item-text{color:var(--item-text-color);-webkit-text-decoration:var(--item-text-decoration);text-decoration:var(--item-text-decoration);transition-duration:var(--item-text-transition-duration)}.elementor-toc__body .elementor-toc__list-item-text:hover{color:var(--item-text-hover-color);-webkit-text-decoration:var(--item-text-hover-decoration);text-decoration:var(--item-text-hover-decoration)}.elementor-toc__body .elementor-toc__list-item-text.elementor-item-active{color:var(--item-text-active-color);-webkit-text-decoration:var(--item-text-active-decoration);text-decoration:var(--item-text-active-decoration)}ol.elementor-toc__list-wrapper{counter-reset:item}ol.elementor-toc__list-wrapper .elementor-toc__list-item{counter-increment:item}ol.elementor-toc__list-wrapper .elementor-toc__list-item-text-wrapper:before{content:counters(item,".") ". "} \ No newline at end of file diff --git a/assets/css/widget-table-of-contents.min.css b/assets/css/widget-table-of-contents.min.css new file mode 100644 index 00000000..0497cf21 --- /dev/null +++ b/assets/css/widget-table-of-contents.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-table-of-contents .elementor-toc__header-title{color:var(--header-color)}.elementor-widget-table-of-contents.elementor-toc--collapsed .elementor-toc__toggle-button--collapse,.elementor-widget-table-of-contents:not(.elementor-toc--collapsed) .elementor-toc__toggle-button--expand{display:none}.elementor-widget-table-of-contents .elementor-widget-container,.elementor-widget-table-of-contents:not(:has(.elementor-widget-container)){background-color:var(--box-background-color);border:var(--box-border-width,1px) solid var(--box-border-color,#9da5ae);border-radius:var(--box-border-radius,3px);min-height:var(--box-min-height);overflow:hidden;transition:min-height .4s}.elementor-toc__header{align-items:center;background-color:var(--header-background-color);border-bottom:var(--separator-width,1px) solid var(--box-border-color,#9da5ae);display:flex;justify-content:flex-end;padding:var(--box-padding,20px)}.elementor-toc__header-title{color:var(--header-color);flex-grow:1;font-size:18px;margin:0}.elementor-toc__toggle-button{cursor:pointer;display:inline-flex}.elementor-toc__toggle-button i{color:var(--toggle-button-color)}.elementor-toc__toggle-button svg{height:1em;width:1em;fill:var(--toggle-button-color)}.elementor-toc__spinner-container{text-align:center}.elementor-toc__spinner{font-size:2em}.elementor-toc__spinner.e-font-icon-svg{height:1em;width:1em}.elementor-toc__body{max-height:var(--toc-body-max-height);overflow-y:auto;padding:var(--box-padding,20px)}.elementor-toc__body::-webkit-scrollbar{width:7px}.elementor-toc__body::-webkit-scrollbar-thumb{background-color:#babfc5;border-radius:10px}.elementor-toc__list-wrapper{list-style:none;padding:0}.elementor-toc__list-item{margin-bottom:.5em}.elementor-toc__list-item.elementor-item-active{font-weight:700}.elementor-toc__list-item .elementor-toc__list-wrapper{margin-top:.5em;margin-inline-start:var(--nested-list-indent,1em)}.elementor-toc__list-item-text{transition-duration:var(--item-text-transition-duration)}.elementor-toc__list-item-text:hover{color:var(--item-text-hover-color);-webkit-text-decoration:var(--item-text-hover-decoration);text-decoration:var(--item-text-hover-decoration)}.elementor-toc__list-item-text.elementor-item-active{color:var(--item-text-active-color);-webkit-text-decoration:var(--item-text-active-decoration);text-decoration:var(--item-text-active-decoration)}.elementor-toc__list-item-text-wrapper{align-items:center;display:flex}.elementor-toc__list-item-text-wrapper i,.elementor-toc__list-item-text-wrapper:before{color:var(--marker-color);margin-inline-end:8px}.elementor-toc__list-item-text-wrapper svg{margin-inline-end:8px;fill:var(--marker-color);height:var(--marker-size,.5em);width:var(--marker-size,.5em)}.elementor-toc__list-item-text-wrapper i{font-size:var(--marker-size,.5em)}.elementor-toc__list-item-text-wrapper:before{font-size:var(--marker-size,1em)}.elementor-toc--content-ellipsis .elementor-toc__list-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.elementor-toc__list-items--collapsible>.elementor-toc__list-wrapper>.elementor-toc__list-item>.elementor-toc__list-wrapper{display:none}.elementor-toc__heading-anchor{position:absolute}.elementor-toc__body .elementor-toc__list-item-text{color:var(--item-text-color);-webkit-text-decoration:var(--item-text-decoration);text-decoration:var(--item-text-decoration);transition-duration:var(--item-text-transition-duration)}.elementor-toc__body .elementor-toc__list-item-text:hover{color:var(--item-text-hover-color);-webkit-text-decoration:var(--item-text-hover-decoration);text-decoration:var(--item-text-hover-decoration)}.elementor-toc__body .elementor-toc__list-item-text.elementor-item-active{color:var(--item-text-active-color);-webkit-text-decoration:var(--item-text-active-decoration);text-decoration:var(--item-text-active-decoration)}ol.elementor-toc__list-wrapper{counter-reset:item}ol.elementor-toc__list-wrapper .elementor-toc__list-item{counter-increment:item}ol.elementor-toc__list-wrapper .elementor-toc__list-item-text-wrapper:before{content:counters(item,".") ". "} \ No newline at end of file diff --git a/assets/css/widget-testimonial-carousel-rtl.min.css b/assets/css/widget-testimonial-carousel-rtl.min.css new file mode 100644 index 00000000..e8f9296c --- /dev/null +++ b/assets/css/widget-testimonial-carousel-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-testimonial__image{flex-shrink:0}.elementor-testimonial__image img{border-radius:999px;box-sizing:content-box;-o-object-fit:cover;object-fit:cover}.elementor-testimonial__footer,.elementor-testimonial__header{display:flex}.elementor-testimonial__footer cite,.elementor-testimonial__header cite{display:flex;flex-direction:column;font-size:14px;font-style:normal;line-height:1.5}.elementor-testimonial__name{font-weight:700}.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{align-items:center}.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline-start:20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__footer{flex-direction:row}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__footer{flex-direction:row-reverse}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{margin-top:25px}.elementor-testimonial--layout-image_above .elementor-testimonial{display:flex;flex-direction:column-reverse}.elementor-testimonial--layout-image_above .elementor-testimonial__footer{margin-bottom:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer{flex-wrap:wrap;margin-top:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial cite,.elementor-testimonial--layout-image_stacked .elementor-testimonial__image{margin-top:15px;width:100%}.elementor-testimonial--layout-image_left .elementor-testimonial,.elementor-testimonial--layout-image_right .elementor-testimonial{align-items:stretch;display:flex}.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--layout-image_right .elementor-testimonial__footer{flex-direction:column;flex-shrink:0;text-align:center}.elementor-testimonial--layout-image_left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_right .elementor-testimonial__image+cite{margin-top:15px}.elementor-testimonial--layout-image_left.elementor-testimonial--align-center .elementor-testimonial__footer,.elementor-testimonial--layout-image_right.elementor-testimonial--align-center .elementor-testimonial__footer{justify-content:flex-start}.elementor-testimonial--layout-image_left .elementor-testimonial{flex-direction:row}.elementor-testimonial--layout-image_left .elementor-testimonial__footer{padding-inline-end:20px}.elementor-testimonial--layout-image_right .elementor-testimonial{flex-direction:row-reverse}.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-inline-start:20px}.elementor-testimonial--align-right .elementor-testimonial{text-align:right}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--align-left .elementor-testimonial{text-align:left}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--align-center .elementor-testimonial{text-align:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--skin-default.elementor-testimonial--layout-image_above .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_left .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_right .elementor-testimonial__cite{display:flex;flex-direction:column;margin-top:25px;width:100%}.elementor-testimonial--skin-bubble .elementor-testimonial__content{background-color:#f9fafa;padding:20px;position:relative}.elementor-testimonial--skin-bubble .elementor-testimonial__content:after{background-color:#f9fafa;border-width:0;box-sizing:content-box;content:"";display:block;height:14px;inset-inline-start:calc(20px + 50px / 2);position:absolute;transform:scaleX(.75) rotate(45deg);width:14px}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above .elementor-testimonial__content:after{bottom:calc(100% - 7px);transform:scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked .elementor-testimonial__content:after{top:calc(100% - 7px)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-center .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-left .elementor-testimonial__content:after{left:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-right .elementor-testimonial__content:after{right:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after{left:-8px;transform:scaleY(.75) rotate(135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{right:-8px;transform:scaleY(.75) rotate(-45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{top:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-top:20px}@media (min-width:-1){.elementor-testimonial--widescreen-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--widescreen-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--widescreen-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:-1){.elementor-testimonial--laptop-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--laptop-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--laptop-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--tablet_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:1024px){.elementor-testimonial--tablet-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:-1){.elementor-testimonial--mobile_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:767px){.elementor-testimonial--mobile-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}.elementor-widget-testimonial-carousel .swiper-slide{padding:20px}.elementor-widget-testimonial-carousel .elementor-testimonial__text{font-size:1.3em;font-style:italic;line-height:1.5}.elementor-widget-testimonial-carousel .elementor-testimonial__image img{height:50px;width:50px} \ No newline at end of file diff --git a/assets/css/widget-testimonial-carousel.min.css b/assets/css/widget-testimonial-carousel.min.css new file mode 100644 index 00000000..f1286549 --- /dev/null +++ b/assets/css/widget-testimonial-carousel.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-testimonial__image{flex-shrink:0}.elementor-testimonial__image img{border-radius:999px;box-sizing:content-box;-o-object-fit:cover;object-fit:cover}.elementor-testimonial__footer,.elementor-testimonial__header{display:flex}.elementor-testimonial__footer cite,.elementor-testimonial__header cite{display:flex;flex-direction:column;font-size:14px;font-style:normal;line-height:1.5}.elementor-testimonial__name{font-weight:700}.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{align-items:center}.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline-start:20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__footer{flex-direction:row-reverse}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__footer,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__footer{flex-direction:row}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{margin-top:25px}.elementor-testimonial--layout-image_above .elementor-testimonial{display:flex;flex-direction:column-reverse}.elementor-testimonial--layout-image_above .elementor-testimonial__footer{margin-bottom:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer{flex-wrap:wrap;margin-top:25px}.elementor-testimonial--layout-image_stacked .elementor-testimonial cite,.elementor-testimonial--layout-image_stacked .elementor-testimonial__image{margin-top:15px;width:100%}.elementor-testimonial--layout-image_left .elementor-testimonial,.elementor-testimonial--layout-image_right .elementor-testimonial{align-items:stretch;display:flex}.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--layout-image_right .elementor-testimonial__footer{flex-direction:column;flex-shrink:0;text-align:center}.elementor-testimonial--layout-image_left .elementor-testimonial__image+cite,.elementor-testimonial--layout-image_right .elementor-testimonial__image+cite{margin-top:15px}.elementor-testimonial--layout-image_left.elementor-testimonial--align-center .elementor-testimonial__footer,.elementor-testimonial--layout-image_right.elementor-testimonial--align-center .elementor-testimonial__footer{justify-content:flex-start}.elementor-testimonial--layout-image_left .elementor-testimonial{flex-direction:row-reverse}.elementor-testimonial--layout-image_left .elementor-testimonial__footer{padding-inline-end:20px}.elementor-testimonial--layout-image_right .elementor-testimonial{flex-direction:row}.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-inline-start:20px}.elementor-testimonial--align-right .elementor-testimonial{text-align:right}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--align-left .elementor-testimonial{text-align:left}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--align-center .elementor-testimonial{text-align:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--skin-default.elementor-testimonial--layout-image_above .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_left .elementor-testimonial__cite,.elementor-testimonial--skin-default.elementor-testimonial--layout-image_right .elementor-testimonial__cite{display:flex;flex-direction:column;margin-top:25px;width:100%}.elementor-testimonial--skin-bubble .elementor-testimonial__content{background-color:#f9fafa;padding:20px;position:relative}.elementor-testimonial--skin-bubble .elementor-testimonial__content:after{background-color:#f9fafa;border-width:0;box-sizing:content-box;content:"";display:block;height:14px;inset-inline-start:calc(20px + 50px / 2);position:absolute;transform:scaleX(.75) rotate(45deg);width:14px}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above .elementor-testimonial__content:after{bottom:calc(100% - 7px);transform:scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(-135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked .elementor-testimonial__content:after{top:calc(100% - 7px)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-center .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-center .elementor-testimonial__content:after{left:50%;transform:translateX(-50%) scaleX(.75) rotate(45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-left .elementor-testimonial__content:after{left:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-right .elementor-testimonial__content:after{right:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after{left:-8px;transform:scaleY(.75) rotate(135deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{right:-8px;transform:scaleY(.75) rotate(-45deg)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__content:after,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__content:after{top:calc(20px + 50px / 2)}.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_left .elementor-testimonial__footer,.elementor-testimonial--skin-bubble.elementor-testimonial--layout-image_right .elementor-testimonial__footer{padding-top:20px}@media (min-width:-1){.elementor-testimonial--widescreen-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--widescreen-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--widescreen-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--widescreen-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--widescreen-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:-1){.elementor-testimonial--laptop-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--laptop-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--laptop-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--laptop-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--laptop-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}.elementor-testimonial--tablet_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:1024px){.elementor-testimonial--tablet-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--tablet-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--tablet-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--tablet-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--tablet-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:-1){.elementor-testimonial--mobile_extra-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile_extra-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile_extra-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile_extra-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile_extra-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}@media (max-width:767px){.elementor-testimonial--mobile-align-right .elementor-testimonial{text-align:right}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row-reverse;justify-content:end}.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-right.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:0 20px}.elementor-testimonial--mobile-align-left .elementor-testimonial{text-align:left}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{flex-direction:row;justify-content:start}.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_above .elementor-testimonial__image+cite,.elementor-testimonial--mobile-align-left.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{margin-inline:20px 0}.elementor-testimonial--mobile-align-center .elementor-testimonial{text-align:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_above .elementor-testimonial__footer,.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__footer{justify-content:center}.elementor-testimonial--mobile-align-center.elementor-testimonial--layout-image_inline .elementor-testimonial__image+cite{text-align:start}}.elementor-widget-testimonial-carousel .swiper-slide{padding:20px}.elementor-widget-testimonial-carousel .elementor-testimonial__text{font-size:1.3em;font-style:italic;line-height:1.5}.elementor-widget-testimonial-carousel .elementor-testimonial__image img{height:50px;width:50px} \ No newline at end of file diff --git a/assets/css/widget-video-playlist-rtl.min.css b/assets/css/widget-video-playlist-rtl.min.css new file mode 100644 index 00000000..2cb01cec --- /dev/null +++ b/assets/css/widget-video-playlist-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-tabs-inner-tabs{font-size:16px;text-align:start}.e-tabs-inner-tabs .e-tab-content{padding-top:32px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:flex;overflow:hidden;position:relative;z-index:1}.e-tabs-inner-tabs .e-inner-tabs-wrapper :after{background-color:var(--inner-tabs-border-color,#d5d8dc);bottom:0;content:"";height:var(--inner-tabs-border-height,1px);position:absolute;width:100%;z-index:-1}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title{box-sizing:content-box;font-weight:700;height:38px;line-height:38px;min-width:140px}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a{color:#3f444b;display:block;padding:0 36px;text-align:center}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active{border-color:#0c0d0e #0c0d0e transparent;border-bottom:1px solid #0c0d0e;border-left-width:0;border-right-width:0;border-top-width:0}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active a{color:#0c0d0e}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{display:none;padding:20px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text{color:#1f2124}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.e-inner-tab-active{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons{display:none;margin-top:24px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons button{background:transparent;border:none;display:none;font-weight:500;line-height:24px;padding:0;text-decoration:underline}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible .e-inner-tab-text{overflow:hidden}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button.show-button,.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible.show-inner-tab-buttons .e-inner-tab-buttons{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.show-full-height div.e-inner-tab-text{height:auto}@media (max-width:767px){.e-tabs-inner-tabs>.e-tab-content:first-child{padding-top:24px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper{border:solid #d5d8dc;border-width:1px 1px 0}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{border:solid #d5d8dc;border-width:0 0 1px;cursor:pointer;display:block;font-size:16px;font-weight:700;height:38px;line-height:38px;overflow:hidden;padding:0 10px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{border:solid #d5d8dc;border-width:0 0 1px;padding:20px}}.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:row}@media (max-width:767px){.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:column-reverse}}.elementor-widget-video-playlist .e-tabs{display:flex;flex-direction:column}.elementor-widget-video-playlist .e-tabs-main-area{display:flex;flex-direction:row-reverse;height:434px}.elementor-widget-video-playlist .e-tabs-wrapper{display:flex;flex-direction:column;height:100%;width:33%}.elementor-widget-video-playlist .e-tabs-header{background-color:var(--e-a-bg-default);border-bottom:1px solid #d5d8dc;display:flex;flex:0 0 auto;justify-content:space-between;min-height:56px;padding:0 16px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-header-right-side{display:inline-flex;flex-shrink:0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-title{font-family:Roboto,Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;-webkit-hyphens:auto;hyphens:auto;margin:auto 0;overflow-wrap:anywhere;padding:10px 0;text-overflow:ellipsis}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{align-self:flex-start;flex-shrink:0;font-size:14px;font-weight:400;line-height:20px;padding:18px 0 0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{cursor:pointer;display:none;margin:auto 0 auto 8px;padding:0 4px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button.e-font-icon-svg{height:1em;width:1em}.elementor-widget-video-playlist .e-tabs-header .rotate-up{transform:rotate(-180deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-header .rotate-down{transform:rotate(0deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-items-wrapper{background-color:var(--e-a-bg-default);height:100%;overflow:hidden;position:relative}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{height:100%;overflow:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-section-title{border-color:#d5d8dc;border-width:0;box-sizing:content-box;font-size:14px;height:36px;line-height:36px;margin:0;overflow:hidden;padding:0 16px;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title{background-clip:padding-box;background-color:var(--e-a-bg-default);border-color:#d5d8dc;border-width:0 0 1px;box-sizing:content-box;cursor:pointer;display:flex;font-size:14px;height:55px;line-height:55px;outline:none;padding:0 16px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i{color:#fff;font-size:var(--playlist-item-icon-size,16px);text-shadow:0 0 3px #000}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{color:#fff;text-shadow:0 0 3px #000;fill:#fff;height:var(--playlist-item-icon-size,16px);width:var(--playlist-item-icon-size,16px)}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg path{fill:#fff}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover{background-color:#f1f2f3;border-color:#d5d8dc}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active .e-tab-title-text,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover .e-tab-title-text{font-size:14px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-play,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched{display:inline-flex}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail{background-color:#d5d8dc;flex-shrink:0;height:42px;margin:auto 0;position:relative;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail img{height:42px;-o-object-fit:fill;object-fit:fill;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail svg{bottom:4px;font-weight:900;position:absolute;right:4px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text{flex-grow:1;font-size:14px;margin:auto 8px;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text button{background:none;border:none;border-radius:0;padding:0;text-align:start;transition-duration:unset;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{margin:auto 0;vertical-align:middle}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-duration{font-size:14px;margin:auto 0}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-play{display:none}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-watched{display:block}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-top{background:linear-gradient(0deg,transparent,#fff);display:none;height:98px;pointer-events:none;position:absolute;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-bottom{background:linear-gradient(180deg,transparent,#fff);bottom:0;display:none;height:98px;pointer-events:none;position:absolute;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper.bottom-shadow .shadow-bottom,.elementor-widget-video-playlist .e-tabs-items-wrapper.top-shadow .shadow-top{display:block}.elementor-widget-video-playlist .e-tabs-content-wrapper{flex-grow:1;height:100%;position:relative}.elementor-widget-video-playlist .e-tabs-content-wrapper .elementor-custom-embed-image-overlay{background-position:50%;background-size:cover;cursor:pointer;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-mobile-title{display:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content{background-color:#000;display:none;height:100%;outline:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content>div{height:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content iframe{display:flex;height:100%;max-height:100%!important}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content video{background-color:#000;height:100%}.elementor-widget-video-playlist .e-tabs-inner-tabs .e-tab-content{display:none;outline:none}@media (max-width:767px){.elementor-widget-video-playlist .e-tabs-main-area{flex-direction:column-reverse;height:auto}.elementor-widget-video-playlist .e-tabs-main-area .e-tabs-content-wrapper{border:none;height:38%}.elementor-widget-video-playlist .e-tabs-wrapper{height:62%;width:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{max-height:248px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items .e-tab-title{border:none}.elementor-widget-video-playlist .e-tabs-header{min-height:48px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{display:inline-flex}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{margin:0 6px;padding:14px 0 0}.elementor-widget-video-playlist .e-tab-content{border:none;display:flex;padding:0}} \ No newline at end of file diff --git a/assets/css/widget-video-playlist.min.css b/assets/css/widget-video-playlist.min.css new file mode 100644 index 00000000..2cb01cec --- /dev/null +++ b/assets/css/widget-video-playlist.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-tabs-inner-tabs{font-size:16px;text-align:start}.e-tabs-inner-tabs .e-tab-content{padding-top:32px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:flex;overflow:hidden;position:relative;z-index:1}.e-tabs-inner-tabs .e-inner-tabs-wrapper :after{background-color:var(--inner-tabs-border-color,#d5d8dc);bottom:0;content:"";height:var(--inner-tabs-border-height,1px);position:absolute;width:100%;z-index:-1}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title{box-sizing:content-box;font-weight:700;height:38px;line-height:38px;min-width:140px}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a{color:#3f444b;display:block;padding:0 36px;text-align:center}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active{border-color:#0c0d0e #0c0d0e transparent;border-bottom:1px solid #0c0d0e;border-left-width:0;border-right-width:0;border-top-width:0}.e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active a{color:#0c0d0e}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{display:none;padding:20px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text{color:#1f2124}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.e-inner-tab-active{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons{display:none;margin-top:24px}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-buttons button{background:transparent;border:none;display:none;font-weight:500;line-height:24px;padding:0;text-decoration:underline}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible .e-inner-tab-text{overflow:hidden}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible button.show-button,.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.collapsible.show-inner-tab-buttons .e-inner-tab-buttons{display:block}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content.show-full-height div.e-inner-tab-text{height:auto}@media (max-width:767px){.e-tabs-inner-tabs>.e-tab-content:first-child{padding-top:24px}.e-tabs-inner-tabs .e-inner-tabs-wrapper{display:none}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper{border:solid #d5d8dc;border-width:1px 1px 0}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-tab-mobile-title{border:solid #d5d8dc;border-width:0 0 1px;cursor:pointer;display:block;font-size:16px;font-weight:700;height:38px;line-height:38px;overflow:hidden;padding:0 10px;text-align:center;text-overflow:ellipsis;white-space:nowrap}.e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content{border:solid #d5d8dc;border-width:0 0 1px;padding:20px}}.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:row}@media (max-width:767px){.elementor-widget-video-playlist.elementor-layout-end .e-tabs-main-area{flex-direction:column-reverse}}.elementor-widget-video-playlist .e-tabs{display:flex;flex-direction:column}.elementor-widget-video-playlist .e-tabs-main-area{display:flex;flex-direction:row-reverse;height:434px}.elementor-widget-video-playlist .e-tabs-wrapper{display:flex;flex-direction:column;height:100%;width:33%}.elementor-widget-video-playlist .e-tabs-header{background-color:var(--e-a-bg-default);border-bottom:1px solid #d5d8dc;display:flex;flex:0 0 auto;justify-content:space-between;min-height:56px;padding:0 16px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-header-right-side{display:inline-flex;flex-shrink:0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-title{font-family:Roboto,Arial,Helvetica,sans-serif;font-size:16px;font-weight:700;-webkit-hyphens:auto;hyphens:auto;margin:auto 0;overflow-wrap:anywhere;padding:10px 0;text-overflow:ellipsis}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{align-self:flex-start;flex-shrink:0;font-size:14px;font-weight:400;line-height:20px;padding:18px 0 0}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{cursor:pointer;display:none;margin:auto 0 auto 8px;padding:0 4px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button.e-font-icon-svg{height:1em;width:1em}.elementor-widget-video-playlist .e-tabs-header .rotate-up{transform:rotate(-180deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-header .rotate-down{transform:rotate(0deg);transition:.3s}.elementor-widget-video-playlist .e-tabs-items-wrapper{background-color:var(--e-a-bg-default);height:100%;overflow:hidden;position:relative}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{height:100%;overflow:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-section-title{border-color:#d5d8dc;border-width:0;box-sizing:content-box;font-size:14px;height:36px;line-height:36px;margin:0;overflow:hidden;padding:0 16px;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title{background-clip:padding-box;background-color:var(--e-a-bg-default);border-color:#d5d8dc;border-width:0 0 1px;box-sizing:content-box;cursor:pointer;display:flex;font-size:14px;height:55px;line-height:55px;outline:none;padding:0 16px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i{color:#fff;font-size:var(--playlist-item-icon-size,16px);text-shadow:0 0 3px #000}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{color:#fff;text-shadow:0 0 3px #000;fill:#fff;height:var(--playlist-item-icon-size,16px);width:var(--playlist-item-icon-size,16px)}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg path{fill:#fff}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover{background-color:#f1f2f3;border-color:#d5d8dc}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.e-active .e-tab-title-text,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title:hover .e-tab-title-text{font-size:14px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-play,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched{display:inline-flex}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail{background-color:#d5d8dc;flex-shrink:0;height:42px;margin:auto 0;position:relative;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail img{height:42px;-o-object-fit:fill;object-fit:fill;width:75px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-thumbnail svg{bottom:4px;font-weight:900;position:absolute;right:4px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text{flex-grow:1;font-size:14px;margin:auto 8px;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-title-text button{background:none;border:none;border-radius:0;padding:0;text-align:start;transition-duration:unset;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title i,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title svg{margin:auto 0;vertical-align:middle}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .e-tab-duration{font-size:14px;margin:auto 0}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title .icon-watched,.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-play{display:none}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tab-title.watched-video .icon-watched{display:block}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-top{background:linear-gradient(0deg,transparent,#fff);display:none;height:98px;pointer-events:none;position:absolute;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper .shadow-bottom{background:linear-gradient(180deg,transparent,#fff);bottom:0;display:none;height:98px;pointer-events:none;position:absolute;width:100%}.elementor-widget-video-playlist .e-tabs-items-wrapper.bottom-shadow .shadow-bottom,.elementor-widget-video-playlist .e-tabs-items-wrapper.top-shadow .shadow-top{display:block}.elementor-widget-video-playlist .e-tabs-content-wrapper{flex-grow:1;height:100%;position:relative}.elementor-widget-video-playlist .e-tabs-content-wrapper .elementor-custom-embed-image-overlay{background-position:50%;background-size:cover;cursor:pointer;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-mobile-title{display:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content{background-color:#000;display:none;height:100%;outline:none}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content>div{height:100%}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content iframe{display:flex;height:100%;max-height:100%!important}.elementor-widget-video-playlist .e-tabs-content-wrapper .e-tab-content video{background-color:#000;height:100%}.elementor-widget-video-playlist .e-tabs-inner-tabs .e-tab-content{display:none;outline:none}@media (max-width:767px){.elementor-widget-video-playlist .e-tabs-main-area{flex-direction:column-reverse;height:auto}.elementor-widget-video-playlist .e-tabs-main-area .e-tabs-content-wrapper{border:none;height:38%}.elementor-widget-video-playlist .e-tabs-wrapper{height:62%;width:auto}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items{max-height:248px}.elementor-widget-video-playlist .e-tabs-items-wrapper .e-tabs-items .e-tab-title{border:none}.elementor-widget-video-playlist .e-tabs-header{min-height:48px}.elementor-widget-video-playlist .e-tabs-header .e-tabs-toggle-videos-display-button{display:inline-flex}.elementor-widget-video-playlist .e-tabs-header .e-tabs-videos-count{margin:0 6px;padding:14px 0 0}.elementor-widget-video-playlist .e-tab-content{border:none;display:flex;padding:0}} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-cart-rtl.min.css b/assets/css/widget-woocommerce-cart-rtl.min.css new file mode 100644 index 00000000..9ead6642 --- /dev/null +++ b/assets/css/widget-woocommerce-cart-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-cart.e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart table tbody tr:hover>td,.elementor-widget-woocommerce-cart table tbody tr:hover>th{background-color:inherit}.elementor-widget-woocommerce-cart .e-clear{height:0;overflow:hidden;width:0}.elementor-widget-woocommerce-cart .e-cart-section{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;margin:var(--sections-margin,0 0 30px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-cart .e-cart-section--no-coupon{margin:var(--sections-margin,0 0 0 0)}@media (min-width:1024px){.elementor-widget-woocommerce-cart .e-cart-section:last-child{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-cart .e-cart-content{color:var(--sections-descriptions-color,#69727d);font-size:15px;font-weight:400;letter-spacing:0;line-height:23px}.elementor-widget-woocommerce-cart .e-cart__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:59% auto;grid-column-gap:var(--sections-margin,30px);grid-row-gap:var(--sections-margin,30px)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .e-cart__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-cart .e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart .select2-container{margin-bottom:4px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,initial);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-inline:1rem}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-cart .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-cart .woocommerce{font-family:Roboto,sans-serif}.elementor-widget-woocommerce-cart .woocommerce button.button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem);width:var(--forms-buttons-width,auto)}.elementor-widget-woocommerce-cart .woocommerce button.button:hover{border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]{color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]:hover{background-color:var(--forms-buttons-hover-background-color,#fff);border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li input{vertical-align:middle}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form{margin-top:var(--sections-descriptions-spacing,15px)}.elementor-widget-woocommerce-cart .woocommerce .woocommerce-shipping-destination{color:var(--sections-descriptions-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tbody th,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tbody th{display:none}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td{text-align:start!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before{margin-bottom:10px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td{text-align:end!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td:before{content:attr(data-title);float:inline-start;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{text-align:var(--totals-title-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td{padding-bottom:var(--totals-rows-gap-bottom,9px);padding-top:var(--totals-rows-gap-top,12px)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td .woocommerce-Price-amount,.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td:before{color:var(--totals-color,#69727d);font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table tr.order-total td{border-top-color:var(--totals-divider-color,#69727d);border-top-width:var(--totals-divider-weight,0)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .form-row{margin-bottom:var(--forms-rows-gap,6px)}.elementor-widget-woocommerce-cart .woocommerce .product-name a{color:var(--product-link-normal-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .product-name a:hover{color:var(--product-link-hover-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .form-row{margin:0;padding:3px 0}.elementor-widget-woocommerce-cart .woocommerce .input-text,.elementor-widget-woocommerce-cart .woocommerce select{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,3px);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-cart .woocommerce .input-text::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text::placeholder,.elementor-widget-woocommerce-cart .woocommerce select::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus,.elementor-widget-woocommerce-cart .woocommerce select:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,transparent);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::-moz-placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text.qty{background-color:transparent;border-color:var(--order-summary-quantity-border-color,#d5d8dc);border-radius:3px;border-style:solid;border-width:var(--order-summary-quantity-border-weight,1px);color:var(--order-summary-color,#000);font-size:14px;max-height:28px;min-height:28px;padding:1px 2px;text-align:start}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;padding-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button{background-color:#5bc0de;border-radius:var(--checkout-button-border-radius,3px);color:var(--checkout-button-normal-text-color,#fff);font-size:15px;margin-bottom:0;min-height:auto;padding:var(--checkout-button-padding,15px 1em);text-align:center;width:var(--checkout-button-width,auto)}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button:hover{background-color:#5bc0de;border-color:var(--checkout-button-hover-border-color,#5bc0de);color:var(--checkout-button-hover-text-color,#fff);transition-duration:var(--checkout-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .remove{background:transparent;color:var(--order-summary-remove-icon-normal-color,#000)!important;width:auto}.elementor-widget-woocommerce-cart .woocommerce .remove:hover{background:transparent;color:var(--order-summary-remove-icon-hover-color,#5bc0de)!important}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals{float:none;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals td{padding-inline-start:0}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals .woocommerce-shipping-totals td{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:inline-end;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .form-row{padding:0}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:flex}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{flex:2;padding-inline-end:30px}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{padding-inline-end:0}}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{flex:1}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{text-align:var(--apply-coupon-button-alignment,center)}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:block}.elementor-widget-woocommerce-cart .woocommerce .coupon{margin:var(--sections-margin,0)}.elementor-widget-woocommerce-cart .woocommerce .coupon #coupon_code{margin-inline-end:0;margin-bottom:15px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:none;width:var(--apply-coupon-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .button{float:inline-start;font-size:14px;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions{display:table-cell;text-align:var(--update-cart-button-alignment,start)!important}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{display:inline-block!important;float:none;width:var(--update-cart-button-width,auto)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{width:var(--update-cart-button-width,100%)!important}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form p:last-of-type{text-align:var(--update-shipping-button-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{float:none;width:var(--update-shipping-button-width,auto)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{width:var(--update-shipping-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table th,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .actions{padding:16px 0 0}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .product-remove a{display:inline-block}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart tbody tr:last-child{display:var(--update-cart-automatically-display,table-row)}.elementor-widget-woocommerce-cart .woocommerce table.cart{margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce table.cart img{display:block;height:auto;width:55px}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-bottom:var(--order-summary-rows-gap-bottom,20px);padding-top:var(--order-summary-rows-gap-top,20px);padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce table.cart td span{color:var(--order-summary-color,#000);font-size:14px;font-weight:400}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top:var(--order-summary-items-divider-weight,1px) solid var(--order-summary-items-divider-color,#d5d8dc)}@media (max-width:768px){.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top-width:0}}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove{padding-inline:0}@media (min-width:767px){.elementor-widget-woocommerce-cart .woocommerce table.cart tbody tr:first-child td{border-top:none}}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.cart.product-remove{position:relative}.elementor-widget-woocommerce-cart .woocommerce table.cart.product-name{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{border-top-color:var(--order-summary-items-divider-color,#d5d8dc);border-top-width:var(--order-summary-items-divider-weight,1px)}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}}@media (max-width:768px){.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}}@media (max-width:767px){.elementor-widget-woocommerce-cart .woocommerce table.cart{padding:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{padding:16px 28px}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions{padding:0}}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward){color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward):hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce .cart th,.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{font-size:14px;font-weight:700;margin-top:0;padding-bottom:8px;padding-top:0;padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{color:var(--sections-title-color,#000);margin-bottom:var(--sections-title-spacing,1rem)}.elementor-widget-woocommerce-cart .woocommerce .cart th{color:var(--order-summary-title-color,#000);padding-bottom:var(--order-summary-title-spacing,8px)}.elementor-widget-woocommerce-cart .woocommerce .cart td:before{color:var(--order-summary-title-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-button:after{display:none}.elementor-widget-woocommerce-cart .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table_responsive tr:nth-child(2n) td,.elementor-widget-woocommerce-cart .woocommerce-page table.shop_table_responsive tr:nth-child(2n) td{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .shop_table_responsive td{padding-inline-start:0}}.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce #shipping_method input,.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form button[name=calc_shipping]{pointer-events:none}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-cart.min.css b/assets/css/widget-woocommerce-cart.min.css new file mode 100644 index 00000000..9ead6642 --- /dev/null +++ b/assets/css/widget-woocommerce-cart.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-cart.e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart table tbody tr:hover>td,.elementor-widget-woocommerce-cart table tbody tr:hover>th{background-color:inherit}.elementor-widget-woocommerce-cart .e-clear{height:0;overflow:hidden;width:0}.elementor-widget-woocommerce-cart .e-cart-section{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;margin:var(--sections-margin,0 0 30px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-cart .e-cart-section--no-coupon{margin:var(--sections-margin,0 0 0 0)}@media (min-width:1024px){.elementor-widget-woocommerce-cart .e-cart-section:last-child{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-cart .e-cart-content{color:var(--sections-descriptions-color,#69727d);font-size:15px;font-weight:400;letter-spacing:0;line-height:23px}.elementor-widget-woocommerce-cart .e-cart__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:59% auto;grid-column-gap:var(--sections-margin,30px);grid-row-gap:var(--sections-margin,30px)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .e-cart__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-cart .e-cart-layout-one-column .e-cart__container{grid-template-columns:auto}.elementor-widget-woocommerce-cart .select2-container{margin-bottom:4px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,initial);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-inline:1rem}.elementor-widget-woocommerce-cart .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-cart .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-cart .woocommerce{font-family:Roboto,sans-serif}.elementor-widget-woocommerce-cart .woocommerce button.button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem);width:var(--forms-buttons-width,auto)}.elementor-widget-woocommerce-cart .woocommerce button.button:hover{border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]{color:var(--forms-buttons-normal-text-color,#69727d);padding:var(--forms-buttons-padding,.88rem 2rem)}.elementor-widget-woocommerce-cart .woocommerce button.button.disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled:hover,.elementor-widget-woocommerce-cart .woocommerce button.button:disabled[disabled]:hover{background-color:var(--forms-buttons-hover-background-color,#fff);border-color:var(--forms-buttons-hover-border-color,#5bc0de);color:var(--forms-buttons-hover-text-color,#69727d);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce #shipping_method li input{vertical-align:middle}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form{margin-top:var(--sections-descriptions-spacing,15px)}.elementor-widget-woocommerce-cart .woocommerce .woocommerce-shipping-destination{color:var(--sections-descriptions-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tbody th,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tbody th{display:none}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td{text-align:start!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr.woocommerce-shipping-totals td:before{margin-bottom:10px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td{text-align:end!important}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table_responsive tr td:before,.elementor-widget-woocommerce-cart .woocommerce-page .cart_totals table.shop_table_responsive tr td:before{content:attr(data-title);float:inline-start;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{text-align:var(--totals-title-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td{padding-bottom:var(--totals-rows-gap-bottom,9px);padding-top:var(--totals-rows-gap-top,12px)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td .woocommerce-Price-amount,.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table td:before{color:var(--totals-color,#69727d);font-weight:700}.elementor-widget-woocommerce-cart .woocommerce .cart_totals table.shop_table tr.order-total td{border-top-color:var(--totals-divider-color,#69727d);border-top-width:var(--totals-divider-weight,0)}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .form-row{margin-bottom:var(--forms-rows-gap,6px)}.elementor-widget-woocommerce-cart .woocommerce .product-name a{color:var(--product-link-normal-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .product-name a:hover{color:var(--product-link-hover-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .form-row{margin:0;padding:3px 0}.elementor-widget-woocommerce-cart .woocommerce .input-text,.elementor-widget-woocommerce-cart .woocommerce select{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,3px);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-cart .woocommerce .input-text::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text::placeholder,.elementor-widget-woocommerce-cart .woocommerce select::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus,.elementor-widget-woocommerce-cart .woocommerce select:focus{background-color:#f9fafa;border-color:var(--forms-fields-focus-border-color,transparent);color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::-moz-placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::-moz-placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text:focus::placeholder,.elementor-widget-woocommerce-cart .woocommerce select:focus::placeholder{color:var(--forms-fields-focus-color,#69727d)}.elementor-widget-woocommerce-cart .woocommerce .input-text.qty{background-color:transparent;border-color:var(--order-summary-quantity-border-color,#d5d8dc);border-radius:3px;border-style:solid;border-width:var(--order-summary-quantity-border-weight,1px);color:var(--order-summary-color,#000);font-size:14px;max-height:28px;min-height:28px;padding:1px 2px;text-align:start}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;padding-bottom:0}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button{background-color:#5bc0de;border-radius:var(--checkout-button-border-radius,3px);color:var(--checkout-button-normal-text-color,#fff);font-size:15px;margin-bottom:0;min-height:auto;padding:var(--checkout-button-padding,15px 1em);text-align:center;width:var(--checkout-button-width,auto)}.elementor-widget-woocommerce-cart .woocommerce .wc-proceed-to-checkout .checkout-button:hover{background-color:#5bc0de;border-color:var(--checkout-button-hover-border-color,#5bc0de);color:var(--checkout-button-hover-text-color,#fff);transition-duration:var(--checkout-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-cart .woocommerce .remove{background:transparent;color:var(--order-summary-remove-icon-normal-color,#000)!important;width:auto}.elementor-widget-woocommerce-cart .woocommerce .remove:hover{background:transparent;color:var(--order-summary-remove-icon-hover-color,#5bc0de)!important}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals{float:none;width:100%}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals td{padding-inline-start:0}.elementor-widget-woocommerce-cart .woocommerce .cart-collaterals .cart_totals .woocommerce-shipping-totals td{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:inline-end;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .form-row{padding:0}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:flex}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{flex:2;padding-inline-end:30px}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-start{padding-inline-end:0}}.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{flex:1}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce .coupon-col-end{text-align:var(--apply-coupon-button-alignment,center)}.elementor-widget-woocommerce-cart .woocommerce .coupon-col{display:block}.elementor-widget-woocommerce-cart .woocommerce .coupon{margin:var(--sections-margin,0)}.elementor-widget-woocommerce-cart .woocommerce .coupon #coupon_code{margin-inline-end:0;margin-bottom:15px;width:100%}.elementor-widget-woocommerce-cart .woocommerce .coupon .button{float:none;width:var(--apply-coupon-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .button{float:inline-start;font-size:14px;font-weight:700}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions{display:table-cell;text-align:var(--update-cart-button-alignment,start)!important}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{display:inline-block!important;float:none;width:var(--update-cart-button-width,auto)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart .actions .button{width:var(--update-cart-button-width,100%)!important}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form p:last-of-type{text-align:var(--update-shipping-button-alignment,start)}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{float:none;width:var(--update-shipping-button-width,auto)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table .shipping-calculator-form .button{width:var(--update-shipping-button-width,100%)}}.elementor-widget-woocommerce-cart .woocommerce table.shop_table td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table th,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr{border:0 solid}.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-cart .woocommerce table.shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .actions{padding:16px 0 0}.elementor-widget-woocommerce-cart .woocommerce table.shop_table .product-remove a{display:inline-block}.elementor-widget-woocommerce-cart .woocommerce table.shop_table.cart tbody tr:last-child{display:var(--update-cart-automatically-display,table-row)}.elementor-widget-woocommerce-cart .woocommerce table.cart{margin-bottom:0}.elementor-widget-woocommerce-cart .woocommerce table.cart img{display:block;height:auto;width:55px}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-bottom:var(--order-summary-rows-gap-bottom,20px);padding-top:var(--order-summary-rows-gap-top,20px);padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce table.cart td span{color:var(--order-summary-color,#000);font-size:14px;font-weight:400}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top:var(--order-summary-items-divider-weight,1px) solid var(--order-summary-items-divider-color,#d5d8dc)}@media (max-width:768px){.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-price,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-quantity,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-subtotal,.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-thumbnail{border-top-width:0}}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-remove{padding-inline:0}@media (min-width:767px){.elementor-widget-woocommerce-cart .woocommerce table.cart tbody tr:first-child td{border-top:none}}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.cart.product-remove{position:relative}.elementor-widget-woocommerce-cart .woocommerce table.cart.product-name{padding-inline-end:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{border-top-color:var(--order-summary-items-divider-color,#d5d8dc);border-top-width:var(--order-summary-items-divider-weight,1px)}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}}@media (max-width:768px){.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}}@media (max-width:767px){.elementor-widget-woocommerce-cart .woocommerce table.cart{padding:0}.elementor-widget-woocommerce-cart .woocommerce table.cart tr{padding:16px 28px}.elementor-widget-woocommerce-cart .woocommerce table.cart tr:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td{padding-inline:0}.elementor-widget-woocommerce-cart .woocommerce table.cart td.product-name,.elementor-widget-woocommerce-cart .woocommerce table.cart td:first-child{border-top:none}.elementor-widget-woocommerce-cart .woocommerce table.cart td.actions{padding:0}}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward){color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce a:not(.add_to_cart_button):not(.restore-item):not(.wc-backward):not(.wc-forward):hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-cart .woocommerce .cart th,.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{font-size:14px;font-weight:700;margin-top:0;padding-bottom:8px;padding-top:0;padding-inline:0 20px}.elementor-widget-woocommerce-cart .woocommerce .cart_totals h2{color:var(--sections-title-color,#000);margin-bottom:var(--sections-title-spacing,1rem)}.elementor-widget-woocommerce-cart .woocommerce .cart th{color:var(--order-summary-title-color,#000);padding-bottom:var(--order-summary-title-spacing,8px)}.elementor-widget-woocommerce-cart .woocommerce .cart td:before{color:var(--order-summary-title-color,#000)}.elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-button:after{display:none}.elementor-widget-woocommerce-cart .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000)}@media (max-width:1024px){.elementor-widget-woocommerce-cart .woocommerce table.shop_table_responsive tr:nth-child(2n) td,.elementor-widget-woocommerce-cart .woocommerce-page table.shop_table_responsive tr:nth-child(2n) td{background-color:transparent}.elementor-widget-woocommerce-cart .woocommerce .cart_totals .shop_table_responsive td{padding-inline-start:0}}.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce #shipping_method input,.e-preview--show-hidden-elements .elementor-widget-woocommerce-cart .woocommerce .shipping-calculator-form button[name=calc_shipping]{pointer-events:none}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-categories-rtl.min.css b/assets/css/widget-woocommerce-categories-rtl.min.css new file mode 100644 index 00000000..4cd6a561 --- /dev/null +++ b/assets/css/widget-woocommerce-categories-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.product .count{background-color:inherit} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-categories.min.css b/assets/css/widget-woocommerce-categories.min.css new file mode 100644 index 00000000..4cd6a561 --- /dev/null +++ b/assets/css/widget-woocommerce-categories.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.product .count{background-color:inherit} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-checkout-page-rtl.min.css b/assets/css/widget-woocommerce-checkout-page-rtl.min.css new file mode 100644 index 00000000..548a06d4 --- /dev/null +++ b/assets/css/widget-woocommerce-checkout-page-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-checkout-page{background-color:transparent;color:#69727d;font-family:Roboto,sans-serif;font-size:14px;line-height:21px}.elementor-widget-woocommerce-checkout-page.e-checkout-layout-one-column .e-checkout__container{grid-template-columns:auto}.elementor-widget-woocommerce-checkout-page ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page table tbody tr:hover>td,.elementor-widget-woocommerce-checkout-page table tbody tr:hover>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .e-description{color:var(--sections-descriptions-color,#69727d);font-size:14px;font-weight:400;padding-bottom:var(--sections-descriptions-spacing,0)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section{margin-bottom:24px}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section .e-checkout-secondary-title{text-align:var(--login-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-nudge{margin-bottom:15px;margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor{margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-box{margin-top:24px}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor-description{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .e-login-wrap{align-items:center;display:flex}.elementor-widget-woocommerce-checkout-page .e-login-wrap-start{flex:75%}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{flex:20%;text-align:end}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-login-wrap{display:block}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{margin-top:15px;text-align:var(--login-button-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end label.e-login-label{display:none}}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap{display:flex;justify-content:space-between;margin-top:6px}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:12px;margin-bottom:0}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:11px}}.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:90%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:var(--coupon-button-width,auto)}}.elementor-widget-woocommerce-checkout-page .e-checkout__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:56% auto;grid-column-gap:var(--sections-margin,24px);grid-row-gap:var(--sections-margin,24px)}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-checkout__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-checkout-page .e-checkout-secondary-title{color:var(--sections-secondary-title-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-checkout-page .e-woocommerce-coupon-nudge{text-align:var(--coupon-title-alignment,start)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address{margin-top:13px;padding-inline-start:var(--shipping-heading-padding-start,30px)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address span{font-weight:400}.elementor-widget-woocommerce-checkout-page a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row{margin-left:var(--forms-columns-gap-margin,0);margin-right:var(--forms-columns-gap-margin,0);padding-left:var(--forms-columns-gap-padding,0);padding-right:var(--forms-columns-gap-padding,0)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;font-weight:400;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea:focus{background-color:#f9fafa;border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_phone_field input{direction:inherit}.elementor-widget-woocommerce-checkout-page .woocommerce .create-account,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row{margin-bottom:0!important}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li input,.elementor-widget-woocommerce-checkout-page .woocommerce .input-radio{vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__label-for-checkbox span{color:var(--sections-checkboxes-color,#69727d);position:relative;top:2px}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li label,.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{display:inline}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#6f6f6f);padding:1rem}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button:hover{color:var(--forms-buttons-hover-text-color,#6f6f6f);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-right:1%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-bottom:15px;margin-right:0;width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-info{background-color:transparent;border-top-color:transparent;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-privacy-policy-text p{font-size:12px;font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login-toggle .woocommerce-info{font-weight:400;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout__order_review,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-section,.elementor-widget-woocommerce-checkout-page .woocommerce .shipping_address,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment{background:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;display:block;margin:var(--sections-margin,0 0 24px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{display:var(--additional-information-display,none)}@media (min-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout-message,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment .payment_box,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text{color:var(--sections-messages-color,#69727d);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text p{margin-top:25px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-1{margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-2{padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce #order_review_heading{text-align:var(--order-review-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table{border:0;font-size:14px;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead tr th{padding-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td{color:#000}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td .product-quantity{font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot th{color:#69727d}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr{border:0;padding-bottom:15px;padding-left:0;padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total tr{padding-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td{border-bottom:var(--order-summary-items-divider-weight,0) solid var(--order-summary-items-divider-color,#69727d);color:var(--order-summary-items-color,#000);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-name{max-width:150px;padding-inline-end:40px}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-total{vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table th{padding-bottom:var(--order-summary-rows-gap-bottom,15px);padding-top:var(--order-summary-rows-gap-top,15px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot th,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table thead th{color:var(--order-summary-totals-color,#69727d);vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total th{border-top:var(--order-summary-totals-divider-weight,0) solid var(--order-summary-totals-divider-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-totals td{max-width:70px}.elementor-widget-woocommerce-checkout-page .woocommerce h3{color:var(--sections-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--sections-title-spacing,30px);margin-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row>span{color:#69727d;font-size:14px;font-weight:400;margin-bottom:3px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:48%}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row .input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields h3{text-align:var(--billing-details-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row{margin-bottom:var(--forms-rows-gap,5px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row:last-child{margin-bottom:15px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout.login{background:#fff;border-top-width:0;color:#69727d;margin-bottom:0;margin-top:-8px;position:relative;z-index:999}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-form-coupon-toggle{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:85%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:var(--login-button-width,35%)}}.elementor-widget-woocommerce-checkout-page .woocommerce-additional-fields h3{text-align:var(--additional-fields-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-fields .shipping_address{margin-bottom:var(--sections-margin,20px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment{margin-top:24px;padding:15px 25px 25px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods{border-bottom:none;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li{line-height:21px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{font-size:12px;padding-inline-start:15px}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{float:none;font-size:11px;padding-left:10px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label img{width:55px}}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .place-order{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;margin-bottom:0;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order{background-color:#5bc0de;border-radius:var(--purchase-button-border-radius,3px);color:var(--purchase-button-normal-text-color,#fff);float:none;min-height:auto;padding:var(--purchase-button-padding,1em 1em);width:var(--purchase-button-width,auto)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order:hover{background-color:#5bc0de;border-color:var(--purchase-button-hover-border-color,#5bc0de);color:var(--purchase-button-hover-text-color,#fff);transition-duration:var(--purchase-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .woocommerce-info:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-2{float:none;width:auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{align-items:center;display:grid;grid-template-columns:auto auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:end}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{display:block}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:var(--coupon-button-alignment,start)}}.elementor-widget-woocommerce-checkout-page .woocommerce #account_password_field{margin-bottom:10px}.elementor-widget-woocommerce-checkout-page .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000);font-size:14px;font-style:normal;letter-spacing:normal;line-height:21px;text-decoration:none;text-transform:none}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-checkout-page.min.css b/assets/css/widget-woocommerce-checkout-page.min.css new file mode 100644 index 00000000..548a06d4 --- /dev/null +++ b/assets/css/widget-woocommerce-checkout-page.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{color:#69727d}.elementor-widget-woocommerce-checkout-page{background-color:transparent;color:#69727d;font-family:Roboto,sans-serif;font-size:14px;line-height:21px}.elementor-widget-woocommerce-checkout-page.e-checkout-layout-one-column .e-checkout__container{grid-template-columns:auto}.elementor-widget-woocommerce-checkout-page ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-checkout-page table tbody tr:hover>td,.elementor-widget-woocommerce-checkout-page table tbody tr:hover>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single:focus{background-color:#f9fafa;border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-checkout-page .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-checkout-page .select2-container--open .select2-dropdown--below{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .e-description{color:var(--sections-descriptions-color,#69727d);font-size:14px;font-weight:400;padding-bottom:var(--sections-descriptions-spacing,0)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section{margin-bottom:24px}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-section .e-checkout-secondary-title{text-align:var(--login-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-woocommerce-login-nudge{margin-bottom:15px;margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor{margin-top:var(--sections-secondary-title-spacing,24px)}.elementor-widget-woocommerce-checkout-page .e-coupon-box{margin-top:24px}.elementor-widget-woocommerce-checkout-page .e-coupon-anchor-description{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .e-login-wrap{align-items:center;display:flex}.elementor-widget-woocommerce-checkout-page .e-login-wrap-start{flex:75%}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{flex:20%;text-align:end}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-login-wrap{display:block}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end{margin-top:15px;text-align:var(--login-button-alignment,start)}.elementor-widget-woocommerce-checkout-page .e-login-wrap-end label.e-login-label{display:none}}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap{display:flex;justify-content:space-between;margin-top:6px}.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:12px;margin-bottom:0}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-login-actions-wrap-end .lost_password{font-size:11px}}.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:90%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-apply-coupon{width:var(--coupon-button-width,auto)}}.elementor-widget-woocommerce-checkout-page .e-checkout__container{align-items:stretch;display:grid;flex-wrap:wrap;grid-template-columns:56% auto;grid-column-gap:var(--sections-margin,24px);grid-row-gap:var(--sections-margin,24px)}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .e-checkout__container{grid-template-columns:repeat(1,1fr)}}.elementor-widget-woocommerce-checkout-page .e-checkout-secondary-title{color:var(--sections-secondary-title-color,#69727d);margin-bottom:0}.elementor-widget-woocommerce-checkout-page .e-woocommerce-coupon-nudge{text-align:var(--coupon-title-alignment,start)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address{margin-top:13px;padding-inline-start:var(--shipping-heading-padding-start,30px)}.elementor-widget-woocommerce-checkout-page #ship-to-different-address span{font-weight:400}.elementor-widget-woocommerce-checkout-page a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row{margin-left:var(--forms-columns-gap-margin,0);margin-right:var(--forms-columns-gap-margin,0);padding-left:var(--forms-columns-gap-padding,0);padding-right:var(--forms-columns-gap-padding,0)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row label,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,3px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea{background-color:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;font-weight:400;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row textarea:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row select:focus,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor .form-row textarea:focus{background-color:#f9fafa;border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_address_1_field,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box #billing_phone_field input,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-anchor #billing_phone_field input{direction:inherit}.elementor-widget-woocommerce-checkout-page .woocommerce .create-account,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box .form-row{margin-bottom:0!important}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li input,.elementor-widget-woocommerce-checkout-page .woocommerce .input-radio{vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-form__label-for-checkbox span{color:var(--sections-checkboxes-color,#69727d);position:relative;top:2px}.elementor-widget-woocommerce-checkout-page .woocommerce #shipping_method li label,.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{color:var(--sections-radio-buttons-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce .wc_payment_method label{display:inline}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button{background-color:var(--e-a-bg-default);border-color:var(--forms-buttons-border-color,#5bc0de);border-radius:var(--forms-buttons-border-radius,3px);border-style:var(--forms-buttons-border-type,solid);border-width:2px;color:var(--forms-buttons-normal-text-color,#6f6f6f);padding:1rem}.elementor-widget-woocommerce-checkout-page .woocommerce button.woocommerce-button:hover{color:var(--forms-buttons-hover-text-color,#6f6f6f);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-right:1%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce #coupon_code{margin-bottom:15px;margin-right:0;width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-info{background-color:transparent;border-top-color:transparent;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-privacy-policy-text p{font-size:12px;font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login-toggle .woocommerce-info{font-weight:400;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout__order_review,.elementor-widget-woocommerce-checkout-page .woocommerce .e-coupon-box,.elementor-widget-woocommerce-checkout-page .woocommerce .e-woocommerce-login-section,.elementor-widget-woocommerce-checkout-page .woocommerce .shipping_address,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment{background:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;display:block;margin:var(--sections-margin,0 0 24px 0);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{display:var(--additional-information-display,none)}@media (min-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-additional-fields{margin:var(--sections-margin,0)}}.elementor-widget-woocommerce-checkout-page .woocommerce .e-checkout-message,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout #payment .payment_box,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text{color:var(--sections-messages-color,#69727d);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-privacy-policy-text p{margin-top:25px}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-1{margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce #customer_details .col2-set .col-2{padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce #order_review_heading{text-align:var(--order-review-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table{border:0;font-size:14px;margin-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table thead tr th{padding-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td{color:#000}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tbody td .product-quantity{font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tfoot th{color:#69727d}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr{border:0;padding-bottom:15px;padding-left:0;padding-top:15px}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total th,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table .order-total tr{padding-bottom:0}.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>td,.elementor-widget-woocommerce-checkout-page .woocommerce .shop_table tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td{border-bottom:var(--order-summary-items-divider-weight,0) solid var(--order-summary-items-divider-color,#69727d);color:var(--order-summary-items-color,#000);font-weight:400}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-name{max-width:150px;padding-inline-end:40px}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .cart_item td.product-total{vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table th{padding-bottom:var(--order-summary-rows-gap-bottom,15px);padding-top:var(--order-summary-rows-gap-top,15px)}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table tfoot th,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table thead th{color:var(--order-summary-totals-color,#69727d);vertical-align:top}.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total td,.elementor-widget-woocommerce-checkout-page .woocommerce .woocommerce-checkout-review-order-table .order-total th{border-top:var(--order-summary-totals-divider-weight,0) solid var(--order-summary-totals-divider-color,#69727d)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-totals td{max-width:70px}.elementor-widget-woocommerce-checkout-page .woocommerce h3{color:var(--sections-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--sections-title-spacing,30px);margin-top:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row>span{color:#69727d;font-size:14px;font-weight:400;margin-bottom:3px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:48%}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row .input-checkbox{margin:0 5px 0 0;vertical-align:middle}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields h3{text-align:var(--billing-details-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row{margin-bottom:var(--forms-rows-gap,5px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-account-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-billing-fields .form-row:last-child,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .woocommerce-shipping-fields .form-row:last-child{margin-bottom:15px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout.login{background:#fff;border-top-width:0;color:#69727d;margin-bottom:0;margin-top:-8px;position:relative;z-index:999}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-first,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .form-row-last{width:100%}}.elementor-widget-woocommerce-checkout-page .woocommerce-form-coupon-toggle{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:85%}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-form-login__submit{width:var(--login-button-width,35%)}}.elementor-widget-woocommerce-checkout-page .woocommerce-additional-fields h3{text-align:var(--additional-fields-title-alignment,start)}.elementor-widget-woocommerce-checkout-page .woocommerce-shipping-fields .shipping_address{margin-bottom:var(--sections-margin,20px)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment{margin-top:24px;padding:15px 25px 25px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods{border-bottom:none;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box{background-color:#f9fafa}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods .payment_box:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li{line-height:21px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{font-size:12px;padding-inline-start:15px}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label a{float:none;font-size:11px;padding-left:10px}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .payment_methods li label img{width:55px}}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .place-order{align-items:var(--place-order-title-alignment,stretch);display:flex;flex-direction:column;flex-wrap:wrap;margin-bottom:0;padding:0}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order{background-color:#5bc0de;border-radius:var(--purchase-button-border-radius,3px);color:var(--purchase-button-normal-text-color,#fff);float:none;min-height:auto;padding:var(--purchase-button-padding,1em 1em);width:var(--purchase-button-width,auto)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment #place_order:hover{background-color:#5bc0de;border-color:var(--purchase-button-hover-border-color,#5bc0de);color:var(--purchase-button-hover-text-color,#fff);transition-duration:var(--purchase-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout #payment .woocommerce-info:before{display:none}.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-1,.elementor-widget-woocommerce-checkout-page .woocommerce-checkout .col2-set .col-2{float:none;width:auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{align-items:center;display:grid;grid-template-columns:auto auto}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:end}@media (max-width:1024px){.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid{display:block}.elementor-widget-woocommerce-checkout-page .woocommerce .coupon-container-grid .coupon-col-2{text-align:var(--coupon-button-alignment,start)}}.elementor-widget-woocommerce-checkout-page .woocommerce #account_password_field{margin-bottom:10px}.elementor-widget-woocommerce-checkout-page .woocommerce .product-name .variation{color:var(--order-summary-variations-color,#000);font-size:14px;font-style:normal;letter-spacing:normal;line-height:21px;text-decoration:none;text-transform:none}.e-sticky-right-column--active{position:sticky;top:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-menu-cart-rtl.min.css b/assets/css/widget-woocommerce-menu-cart-rtl.min.css new file mode 100644 index 00000000..ee52c7cd --- /dev/null +++ b/assets/css/widget-woocommerce-menu-cart-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-menu-cart__wrapper{text-align:var(--main-alignment,start)}.elementor-menu-cart__toggle_wrapper{display:inline-block;position:relative}.elementor-menu-cart__toggle{display:inline-block}.elementor-menu-cart__toggle .elementor-button{align-items:center;background-color:var(--toggle-button-background-color,transparent);border-color:var(--toggle-button-border-color,#69727d);border-radius:var(--toggle-button-border-radius,0);border-style:var(--toggle-button-border-type,solid);border-width:var(--toggle-button-border-width,1px);color:var(--toggle-button-text-color,#69727d);display:inline-flex;flex-direction:row;gap:.3em;padding:var(--toggle-icon-padding,12px 24px)}.elementor-menu-cart__toggle .elementor-button:hover{background-color:var(--toggle-button-hover-background-color,transparent);border-color:var(--toggle-button-hover-border-color,#69727d);color:var(--toggle-button-hover-text-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover .elementor-button-icon{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover svg{fill:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button svg{fill:var(--toggle-button-icon-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon{position:relative;transition:color .1s}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon,.elementor-menu-cart__toggle .elementor-button-icon{color:var(--toggle-button-icon-color,#69727d);font-size:var(--toggle-icon-size,inherit)}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon:hover{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon,.elementor-menu-cart__toggle .elementor-button-text{flex-grow:unset;order:unset}.elementor-menu-cart--items-indicator-bubble .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{background-color:var(--items-indicator-background-color,#d9534f);border-radius:100%;color:var(--items-indicator-text-color,#fff);display:block;font-size:10px;height:1.6em;inset-inline-end:-.7em;line-height:1.5em;min-width:1.6em;position:absolute;text-align:center;top:-.7em}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon{align-items:center;display:flex}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon i,.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon svg{line-height:unset}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:inline-block;font-weight:400}.elementor-menu-cart--items-indicator-none .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:none}.elementor-menu-cart__container{background-color:rgba(0,0,0,.25);height:100%;left:0;overflow:hidden;position:fixed;text-align:start;top:0;transform:scale(1);transition:background-color .4s,transform 0s;width:100vw;z-index:9998}.elementor-menu-cart__main{align-items:stretch;background-color:var(--cart-background-color,#fff);border-color:var(--cart-border-color,initial);border-radius:var(--cart-border-radius,0);border-style:var(--cart-border-style,none);bottom:0;box-shadow:0 0 20px rgba(0,0,0,.2);display:flex;flex-direction:column;font-size:14px;left:var(--side-cart-alignment-left,0);margin-top:var(--mini-cart-spacing,0);max-width:100%;min-height:200px;padding:var(--cart-padding,20px 30px);position:fixed;right:var(--side-cart-alignment-right,auto);top:0;transform:translateX(0);transition:.3s;width:350px}.elementor-menu-cart__main .widget_shopping_cart_content{display:flex;flex-direction:column;height:100%}.elementor-menu-cart__main .widget_shopping_cart_content .woocommerce-mini-cart__empty-message{color:var(--empty-message-color,inherit);text-align:var(--empty-message-alignment,start)}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{background-color:transparent;transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container .dialog-lightbox-close-button{display:none}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;overflow:hidden;transform:var(--side-cart-alignment-transform,translateX(calc(100% * var(--direction-multiplier, 1))))}.elementor-menu-cart__close-button{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;height:var(--cart-close-icon-size,25px);line-height:1;margin:0 0 20px;position:relative;transition:.3s;width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button:after,.elementor-menu-cart__close-button:before{background:var(--cart-close-button-color,#69727d);border-radius:1px;content:"";height:3px;left:0;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:100%}.elementor-menu-cart__close-button:hover:after,.elementor-menu-cart__close-button:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button:before{transform:rotate(45deg)}.elementor-menu-cart__close-button:after{transform:rotate(-45deg)}.elementor-menu-cart__close-button-custom{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;line-height:1;margin:0 0 20px;position:relative;transition:.3s}.elementor-menu-cart__close-button-custom:hover:after,.elementor-menu-cart__close-button-custom:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon{color:var(--cart-close-button-color,#69727d);font-size:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon:hover{color:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom svg{fill:var(--cart-close-button-color,#69727d);height:var(--cart-close-icon-size,25px);width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom svg:hover{fill:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__products{max-height:calc(100vh - 250px);overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.elementor-menu-cart__product{border-bottom-color:var(--divider-color,#d5d8dc);border-bottom-style:var(--divider-style,solid);border-width:0 0 var(--divider-width,1px);display:grid;grid-template-columns:28% auto;grid-template-rows:var(--price-quantity-position--grid-template-rows,auto auto);position:relative}.elementor-menu-cart__product .variation{color:var(--product-variations-color,#1f2124);display:grid;grid-template-columns:max-content auto;margin:10px 0}.elementor-menu-cart__product .variation dt{grid-column-start:1}.elementor-menu-cart__product .variation dd{grid-column-start:2;margin-inline-start:5px}.elementor-menu-cart__product .variation dd p{margin-bottom:0}.elementor-menu-cart__product-image{grid-row-end:3;grid-row-start:1;width:100%}.elementor-menu-cart__product-image a,.elementor-menu-cart__product-image img{display:block}.elementor-menu-cart__product-name{grid-column-end:3;grid-column-start:2;margin:0}.elementor-menu-cart__product-name a{transition:.3s}.elementor-menu-cart__product-price{align-self:var(--price-quantity-position--align-self,end);color:var(--product-price-color,#d5d8dc);font-weight:300;grid-column-end:3;grid-column-start:2}.elementor-menu-cart__product-name,.elementor-menu-cart__product-price{font-size:14px;padding-inline-start:20px}.elementor-menu-cart__product-remove{border:1px solid var(--remove-item-button-color,#d5d8dc);border-radius:var(--remove-item-button-size,22px);bottom:20px;color:#69727d;height:var(--remove-item-button-size,22px);inset-inline-end:0;overflow:hidden;position:absolute;text-align:center;transition:.3s;width:var(--remove-item-button-size,22px)}.elementor-menu-cart__product-remove:hover{border:1px solid var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:hover:after,.elementor-menu-cart__product-remove:hover:before{background:var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:after,.elementor-menu-cart__product-remove:before{background:var(--remove-item-button-color,#d5d8dc);content:"";height:1px;left:25%;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:50%;z-index:1}.elementor-menu-cart__product-remove:before{transform:rotate(45deg)}.elementor-menu-cart__product-remove:after{transform:rotate(-45deg)}.elementor-menu-cart__product-remove>a{display:block;height:100%;opacity:0;overflow:hidden;position:absolute;width:100%;z-index:2}.elementor-menu-cart__product-remove>a.remove_from_cart_button{display:var(--remove-from-cart-button,block)}.elementor-menu-cart__product-remove>a.elementor_remove_from_cart_button{display:var(--elementor-remove-from-cart-button,none)}.elementor-menu-cart__product:last-child{border:none}.elementor-menu-cart__footer-buttons,.elementor-menu-cart__product:not(:first-of-type),.elementor-menu-cart__subtotal{padding-top:var(--product-divider-gap,20px)}.elementor-menu-cart__product{padding-inline-end:30px}.elementor-menu-cart__product,.elementor-menu-cart__subtotal{padding-bottom:var(--product-divider-gap,20px)}.elementor-menu-cart__subtotal{border-color:var(--subtotal-divider-color,#d5d8dc);border-style:var(--subtotal-divider-style,solid);border-width:var(--subtotal-divider-top-width,1px) var(--subtotal-divider-right-width,1px) var(--subtotal-divider-bottom-width,1px) var(--subtotal-divider-left-width,1px);color:var(--menu-cart-subtotal-color,inherit);font-size:20px;font-weight:600;text-align:var(--menu-cart-subtotal-text-align,center)}.elementor-menu-cart__footer-buttons{display:var(--cart-footer-buttons-alignment-display,grid);font-size:20px;grid-template-columns:var(--cart-footer-layout,1fr 1fr);margin-top:var(--cart-buttons-position-margin,0);text-align:var(--cart-footer-buttons-alignment-text-align,center);grid-column-gap:var(--space-between-buttons,10px);grid-row-gap:var(--space-between-buttons,10px)}.elementor-menu-cart__footer-buttons .elementor-button{border-radius:var(--cart-footer-buttons-border-radius,0);display:inline-block;height:-moz-fit-content;height:fit-content}.elementor-menu-cart__footer-buttons .elementor-button--view-cart{background-color:var(--view-cart-button-background-color,#69727d);color:var(--view-cart-button-text-color,#fff);display:var(--view-cart-button-display,inline-block);padding:var(--view-cart-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover{background-color:var(--view-cart-button-hover-background-color,#69727d);color:var(--view-cart-button-hover-text-color,#fff)}.elementor-menu-cart__footer-buttons .elementor-button--checkout{background-color:var(--checkout-button-background-color,#69727d);color:var(--checkout-button-text-color,#fff);display:var(--checkout-button-display,inline-block);padding:var(--checkout-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--checkout:hover{background-color:var(--checkout-button-hover-background-color,#69727d);color:var(--checkout-button-hover-text-color,#fff)}@media (max-width:767px){.elementor-menu-cart__footer-buttons .elementor-button{padding-left:10px;padding-right:10px}}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--empty-indicator-hide .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter="0"],.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-subtotal-yes) .elementor-menu-cart__toggle .elementor-button-text{display:none}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product{grid-template-columns:25% auto;padding-left:0;padding-right:0}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product-remove{display:none}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__product-remove{bottom:auto;top:0}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__products .cart_item:not(:first-of-type) .elementor-menu-cart__product-remove{bottom:auto;top:20px}.elementor-widget-woocommerce-menu-cart.remove-item-position--middle .elementor-menu-cart__product-remove{bottom:50%;transform:translateY(50%)}.elementor-widget-woocommerce-menu-cart.remove-item-position--bottom .elementor-menu-cart__product-remove{bottom:20px;top:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{background:none;bottom:auto;height:auto;min-width:330px;overflow:visible;position:absolute;top:100%;inset-inline:0 auto;transform:scale(1);transition:background-color .4s,transform 0s;width:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__main{height:auto;inset:auto;overflow:visible;position:relative;transform:translateY(0);transition:.3s;width:auto}@media (max-width:767px){.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{min-width:300px}}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;transform:translateY(-10px)}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown{opacity:1}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown .elementor-menu-cart__container{z-index:9999}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-dropdown .elementor-menu-cart__container{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-menu-cart.min.css b/assets/css/widget-woocommerce-menu-cart.min.css new file mode 100644 index 00000000..14985eab --- /dev/null +++ b/assets/css/widget-woocommerce-menu-cart.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-menu-cart__wrapper{text-align:var(--main-alignment,start)}.elementor-menu-cart__toggle_wrapper{display:inline-block;position:relative}.elementor-menu-cart__toggle{display:inline-block}.elementor-menu-cart__toggle .elementor-button{align-items:center;background-color:var(--toggle-button-background-color,transparent);border-color:var(--toggle-button-border-color,#69727d);border-radius:var(--toggle-button-border-radius,0);border-style:var(--toggle-button-border-type,solid);border-width:var(--toggle-button-border-width,1px);color:var(--toggle-button-text-color,#69727d);display:inline-flex;flex-direction:row;gap:.3em;padding:var(--toggle-icon-padding,12px 24px)}.elementor-menu-cart__toggle .elementor-button:hover{background-color:var(--toggle-button-hover-background-color,transparent);border-color:var(--toggle-button-hover-border-color,#69727d);color:var(--toggle-button-hover-text-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover .elementor-button-icon{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button:hover svg{fill:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button svg{fill:var(--toggle-button-icon-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon{position:relative;transition:color .1s}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon,.elementor-menu-cart__toggle .elementor-button-icon{color:var(--toggle-button-icon-color,#69727d);font-size:var(--toggle-icon-size,inherit)}.elementor-menu-cart__toggle .e-toggle-cart-custom-icon:hover{color:var(--toggle-button-icon-hover-color,#69727d)}.elementor-menu-cart__toggle .elementor-button-icon,.elementor-menu-cart__toggle .elementor-button-text{flex-grow:unset;order:unset}.elementor-menu-cart--items-indicator-bubble .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{background-color:var(--items-indicator-background-color,#d9534f);border-radius:100%;color:var(--items-indicator-text-color,#fff);display:block;font-size:10px;height:1.6em;inset-inline-end:-.7em;line-height:1.5em;min-width:1.6em;position:absolute;text-align:center;top:-.7em}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon{align-items:center;display:flex}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon i,.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon svg{line-height:unset}.elementor-menu-cart--items-indicator-plain .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:inline-block;font-weight:400}.elementor-menu-cart--items-indicator-none .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]{display:none}.elementor-menu-cart__container{background-color:rgba(0,0,0,.25);height:100%;left:0;overflow:hidden;position:fixed;text-align:start;top:0;transform:scale(1);transition:background-color .4s,transform 0s;width:100vw;z-index:9998}.elementor-menu-cart__main{align-items:stretch;background-color:var(--cart-background-color,#fff);border-color:var(--cart-border-color,initial);border-radius:var(--cart-border-radius,0);border-style:var(--cart-border-style,none);bottom:0;box-shadow:0 0 20px rgba(0,0,0,.2);display:flex;flex-direction:column;font-size:14px;left:var(--side-cart-alignment-left,auto);margin-top:var(--mini-cart-spacing,0);max-width:100%;min-height:200px;padding:var(--cart-padding,20px 30px);position:fixed;right:var(--side-cart-alignment-right,0);top:0;transform:translateX(0);transition:.3s;width:350px}.elementor-menu-cart__main .widget_shopping_cart_content{display:flex;flex-direction:column;height:100%}.elementor-menu-cart__main .widget_shopping_cart_content .woocommerce-mini-cart__empty-message{color:var(--empty-message-color,inherit);text-align:var(--empty-message-alignment,start)}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{background-color:transparent;transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container .dialog-lightbox-close-button{display:none}body.elementor-default .elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;overflow:hidden;transform:var(--side-cart-alignment-transform,translateX(calc(100% * var(--direction-multiplier, 1))))}.elementor-menu-cart__close-button{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;height:var(--cart-close-icon-size,25px);line-height:1;margin:0 0 20px;position:relative;transition:.3s;width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button:after,.elementor-menu-cart__close-button:before{background:var(--cart-close-button-color,#69727d);border-radius:1px;content:"";height:3px;left:0;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:100%}.elementor-menu-cart__close-button:hover:after,.elementor-menu-cart__close-button:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button:before{transform:rotate(45deg)}.elementor-menu-cart__close-button:after{transform:rotate(-45deg)}.elementor-menu-cart__close-button-custom{align-self:flex-end;cursor:pointer;display:inline-block;font-family:eicons;font-size:20px;line-height:1;margin:0 0 20px;position:relative;transition:.3s}.elementor-menu-cart__close-button-custom:hover:after,.elementor-menu-cart__close-button-custom:hover:before{background:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon{color:var(--cart-close-button-color,#69727d);font-size:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom .e-close-cart-custom-icon:hover{color:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__close-button-custom svg{fill:var(--cart-close-button-color,#69727d);height:var(--cart-close-icon-size,25px);width:var(--cart-close-icon-size,25px)}.elementor-menu-cart__close-button-custom svg:hover{fill:var(--cart-close-button-hover-color,#69727d)}.elementor-menu-cart__products{max-height:calc(100vh - 250px);overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.elementor-menu-cart__product{border-bottom-color:var(--divider-color,#d5d8dc);border-bottom-style:var(--divider-style,solid);border-width:0 0 var(--divider-width,1px);display:grid;grid-template-columns:28% auto;grid-template-rows:var(--price-quantity-position--grid-template-rows,auto auto);position:relative}.elementor-menu-cart__product .variation{color:var(--product-variations-color,#1f2124);display:grid;grid-template-columns:max-content auto;margin:10px 0}.elementor-menu-cart__product .variation dt{grid-column-start:1}.elementor-menu-cart__product .variation dd{grid-column-start:2;margin-inline-start:5px}.elementor-menu-cart__product .variation dd p{margin-bottom:0}.elementor-menu-cart__product-image{grid-row-end:3;grid-row-start:1;width:100%}.elementor-menu-cart__product-image a,.elementor-menu-cart__product-image img{display:block}.elementor-menu-cart__product-name{grid-column-end:3;grid-column-start:2;margin:0}.elementor-menu-cart__product-name a{transition:.3s}.elementor-menu-cart__product-price{align-self:var(--price-quantity-position--align-self,end);color:var(--product-price-color,#d5d8dc);font-weight:300;grid-column-end:3;grid-column-start:2}.elementor-menu-cart__product-name,.elementor-menu-cart__product-price{font-size:14px;padding-inline-start:20px}.elementor-menu-cart__product-remove{border:1px solid var(--remove-item-button-color,#d5d8dc);border-radius:var(--remove-item-button-size,22px);bottom:20px;color:#69727d;height:var(--remove-item-button-size,22px);inset-inline-end:0;overflow:hidden;position:absolute;text-align:center;transition:.3s;width:var(--remove-item-button-size,22px)}.elementor-menu-cart__product-remove:hover{border:1px solid var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:hover:after,.elementor-menu-cart__product-remove:hover:before{background:var(--remove-item-button-hover-color,#d5d8dc)}.elementor-menu-cart__product-remove:after,.elementor-menu-cart__product-remove:before{background:var(--remove-item-button-color,#d5d8dc);content:"";height:1px;left:25%;margin-top:-1px;position:absolute;top:50%;transition:.3s;width:50%;z-index:1}.elementor-menu-cart__product-remove:before{transform:rotate(45deg)}.elementor-menu-cart__product-remove:after{transform:rotate(-45deg)}.elementor-menu-cart__product-remove>a{display:block;height:100%;opacity:0;overflow:hidden;position:absolute;width:100%;z-index:2}.elementor-menu-cart__product-remove>a.remove_from_cart_button{display:var(--remove-from-cart-button,block)}.elementor-menu-cart__product-remove>a.elementor_remove_from_cart_button{display:var(--elementor-remove-from-cart-button,none)}.elementor-menu-cart__product:last-child{border:none}.elementor-menu-cart__footer-buttons,.elementor-menu-cart__product:not(:first-of-type),.elementor-menu-cart__subtotal{padding-top:var(--product-divider-gap,20px)}.elementor-menu-cart__product{padding-inline-end:30px}.elementor-menu-cart__product,.elementor-menu-cart__subtotal{padding-bottom:var(--product-divider-gap,20px)}.elementor-menu-cart__subtotal{border-color:var(--subtotal-divider-color,#d5d8dc);border-style:var(--subtotal-divider-style,solid);border-width:var(--subtotal-divider-top-width,1px) var(--subtotal-divider-right-width,1px) var(--subtotal-divider-bottom-width,1px) var(--subtotal-divider-left-width,1px);color:var(--menu-cart-subtotal-color,inherit);font-size:20px;font-weight:600;text-align:var(--menu-cart-subtotal-text-align,center)}.elementor-menu-cart__footer-buttons{display:var(--cart-footer-buttons-alignment-display,grid);font-size:20px;grid-template-columns:var(--cart-footer-layout,1fr 1fr);margin-top:var(--cart-buttons-position-margin,0);text-align:var(--cart-footer-buttons-alignment-text-align,center);grid-column-gap:var(--space-between-buttons,10px);grid-row-gap:var(--space-between-buttons,10px)}.elementor-menu-cart__footer-buttons .elementor-button{border-radius:var(--cart-footer-buttons-border-radius,0);display:inline-block;height:-moz-fit-content;height:fit-content}.elementor-menu-cart__footer-buttons .elementor-button--view-cart{background-color:var(--view-cart-button-background-color,#69727d);color:var(--view-cart-button-text-color,#fff);display:var(--view-cart-button-display,inline-block);padding:var(--view-cart-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover{background-color:var(--view-cart-button-hover-background-color,#69727d);color:var(--view-cart-button-hover-text-color,#fff)}.elementor-menu-cart__footer-buttons .elementor-button--checkout{background-color:var(--checkout-button-background-color,#69727d);color:var(--checkout-button-text-color,#fff);display:var(--checkout-button-display,inline-block);padding:var(--checkout-button-padding,15px)}.elementor-menu-cart__footer-buttons .elementor-button--checkout:hover{background-color:var(--checkout-button-hover-background-color,#69727d);color:var(--checkout-button-hover-text-color,#fff)}@media (max-width:767px){.elementor-menu-cart__footer-buttons .elementor-button{padding-left:10px;padding-right:10px}}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--empty-indicator-hide .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter="0"],.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-subtotal-yes) .elementor-menu-cart__toggle .elementor-button-text{display:none}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product{grid-template-columns:25% auto;padding-left:0;padding-right:0}.elementor-widget-woocommerce-menu-cart:not(.elementor-menu-cart--show-remove-button-yes) .elementor-menu-cart__product-remove{display:none}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__product-remove{bottom:auto;top:0}.elementor-widget-woocommerce-menu-cart.remove-item-position--top .elementor-menu-cart__products .cart_item:not(:first-of-type) .elementor-menu-cart__product-remove{bottom:auto;top:20px}.elementor-widget-woocommerce-menu-cart.remove-item-position--middle .elementor-menu-cart__product-remove{bottom:50%;transform:translateY(50%)}.elementor-widget-woocommerce-menu-cart.remove-item-position--bottom .elementor-menu-cart__product-remove{bottom:20px;top:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{background:none;bottom:auto;height:auto;min-width:330px;overflow:visible;position:absolute;top:100%;inset-inline:0 auto;transform:scale(1);transition:background-color .4s,transform 0s;width:auto}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__main{height:auto;inset:auto;overflow:visible;position:relative;transform:translateY(0);transition:.3s;width:auto}@media (max-width:767px){.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container{min-width:300px}}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__container{transform:scale(0);transition:background-color .4s,transform 0s .4s}body.elementor-default .elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-mini-cart:not(.elementor-menu-cart--shown) .elementor-menu-cart__main{opacity:0;transform:translateY(-10px)}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown{opacity:1}.elementor-edit-area-active .elementor-widget-woocommerce-menu-cart.elementor-widget.elementor-loading.elementor-menu-cart--shown .elementor-menu-cart__container{z-index:9999}.elementor-widget-woocommerce-menu-cart.elementor-menu-cart--cart-type-dropdown .elementor-menu-cart__container{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-my-account-rtl.min.css b/assets/css/widget-woocommerce-my-account-rtl.min.css new file mode 100644 index 00000000..709962bd --- /dev/null +++ b/assets/css/widget-woocommerce-my-account-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:var(--forms-fields-normal-color,#69727d);font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account{color:#69727d;font-family:Roboto,sans-serif}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{float:inline-end;padding:0;padding-inline-start:var(--tab-content-spacing,6%);width:75%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .shop_table{border:none;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{background-color:var(--sections-background-color,#fff)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content{border:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content-wrapper{border:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details{margin-bottom:40px}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-table--order-downloads{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button:hover{color:var(--tables-button-hover-text-color,#69727d);transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment .payment_methods{border-bottom:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d4d4d4);padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content>div>p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default{background-color:var(--forms-fields-normal-background-color,#f9fafa);border-radius:var(--forms-fields-border-radius,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single{background-color:var(--forms-fields-normal-background-color,#f9fafa);border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px;margin:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single:focus{background-color:var(--forms-fields-focus-background-color,#f9fafa);border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--open .select2-dropdown--below{background-color:var(--forms-fields-normal-background-color,#f9fafa)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-message{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce address{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button.alt:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button:hover{background-color:initial}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce em{color:var(--login-messages-color,#69727d);font-size:12px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row{margin-bottom:var(--forms-rows-gap,6px);margin-left:var(--forms-columns-gap-margin-left,0);margin-right:var(--forms-columns-gap-margin-right,0);padding-left:var(--forms-columns-gap-padding-left,0);padding-right:var(--forms-columns-gap-padding-right,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-privacy-policy-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-privacy-policy-text{color:var(--login-messages-color,#69727d);font-size:12px;margin-bottom:15px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:not([class]),.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register p:not([class]){color:var(--login-messages-color,#69727d);font-size:12px;margin-top:10px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-LostPassword,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-LostPassword{font-size:12px;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:50%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-first,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-last{width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);font-size:14px;padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:nth-child(3){margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__input-checkbox{vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__label-for-checkbox span{color:var(--checkboxes-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tr{border:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h2,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h3{color:var(--typography-section-titles-color,#000);font-weight:400;margin-bottom:var(--section-title-spacing,45px);margin-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .wc-item-meta,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong.wc-item-meta-label{color:var(--variations-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .product-quantity{color:var(--tables-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-order-downloads{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content h2:first-of-type{margin-top:30px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content mark{background-color:transparent;color:var(--general-text-color,#000);font-weight:700}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child th{border-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child th{border-top:0;padding-bottom:var(--tables-titles-spacing,9px);padding-inline-start:0;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>th{background-color:transparent;color:var(--tables-items-color,#69727d);padding-bottom:var(--order-summary-rows-gap-bottom,9px);padding-inline-start:0;padding-top:var(--order-summary-rows-gap-top,9px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table th{border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th span{color:var(--tables-title-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot th{color:var(--tables-title-color,#000);padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-purchase-note td{border-top:none;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);margin-bottom:0;margin-top:0;padding:var(--tables-button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .title h3,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .title h3{float:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address address,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses address{padding:var(--sections-padding,45px 30px 16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .edit,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .edit{float:inline-start;margin-inline-start:var(--edit-link-margin-start,30px);margin-top:var(--edit-link-margin-top,10px);position:absolute}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .u-columns{margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset{border:none;margin-inline-start:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset legend,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset legend{color:var(--general-text-color,#000);font-weight:700;padding:20px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);margin-top:20px;padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination{padding:16px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-OrderUpdates{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:inline-start;width:25%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul{padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li{display:inline-block;list-style-type:none;width:var(--tab-width,100%)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{background-color:var(--tabs-divider-color,#69727d);content:"";display:block;height:var(--tabs-divider-weight,0);position:relative;top:calc(var(--tabs-spacing, 2px) / 2);width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.is-active a{background:#f1f2f3;border-color:var(--tabs-active-border-color,transparent);color:var(--tabs-active-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{background:#f9fafa;border-color:var(--tabs-border-color,transparent);border-radius:var(--tabs-border-radius,0);border-style:var(--tabs-border-type,solid);border-width:0;color:var(--tabs-normal-color,#69727d);display:block;font-size:14px;font-style:normal;font-weight:700;padding:var(--tabs-padding,12px 20px);text-align:var(--tabs-alignment,start)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover{border-color:var(--tabs-hover-border-color,transparent);color:var(--tabs-hover-color,#5bc0de)}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{padding:var(--tabs-padding,10px)}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout:after{display:none}.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .shop_table td{line-height:unset;vertical-align:top}.elementor-widget-woocommerce-my-account .woocommerce-MyAccount-paymentMethods .woocommerce-PaymentMethod--actions{text-align:end}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio{vertical-align:middle}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio+label{color:var(--payment-methods-radio-buttons-color,#69727d)}.e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li{margin:calc(var(--tabs-spacing, 2px) / 2) 0}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--dashboard{margin-top:0}.e-my-account-tabs-vertical .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:none;width:100%}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{float:none;padding:var(--tab-content-spacing,50px) 0 0 0;width:100%}@media (max-width:1024px){.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.e-my-account-tabs-horizontal .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:flex;justify-content:var(--tabs-container-justify-content,space-between);list-style:none;margin:0;padding:0}@media (max-width:767px){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:block}}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{border-inline-end-color:var(--tabs-divider-color,#69727d);border-inline-end-style:solid;border-inline-end-width:var(--tabs-divider-weight,0);display:inline-block;margin:0;padding:0 calc(var(--tabs-spacing, 2px) / 2) 0 calc(var(--tabs-spacing, 2px) / 2);width:var(--tab-width,100%)}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:first-of-type{padding-inline-start:0}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:last-of-type{border-inline-end-width:0;padding-inline-end:0}@media (max-width:767px){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block;margin:calc(var(--tabs-spacing, 2px) / 2) 0;width:100%}}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-number a,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-number a{pointer-events:none}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button{opacity:.3;pointer-events:none}.elementor-editor-active .elementor-widget-woocommerce-my-account .woocommerce-MyAccount-content:not(:first-of-type){display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-my-account.min.css b/assets/css/widget-woocommerce-my-account.min.css new file mode 100644 index 00000000..709962bd --- /dev/null +++ b/assets/css/widget-woocommerce-my-account.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.e-woo-select2-wrapper .select2-results__option{color:var(--forms-fields-normal-color,#69727d);font-family:Roboto,sans-serif;font-size:14px}.e-woo-select2-wrapper .select2-results__option:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account{color:#69727d;font-family:Roboto,sans-serif}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{float:inline-end;padding:0;padding-inline-start:var(--tab-content-spacing,6%);width:75%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .shop_table,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .shop_table{border:none;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{background-color:var(--sections-background-color,#fff)}.elementor-widget-woocommerce-my-account .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper{padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content{border:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__edit-address .woocommerce-MyAccount-content-wrapper,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-MyAccount-content-wrapper{border:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details{margin-bottom:40px}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .order_details,.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .woocommerce-table--order-downloads{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px 3px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button:hover{color:var(--tables-button-hover-text-color,#69727d);transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__payment-methods .woocommerce input[type=text]:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment .payment_methods{border-bottom:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d4d4d4);padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab__add-payment-method #add_payment_method #payment #place_order:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content>div>p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default{background-color:var(--forms-fields-normal-background-color,#f9fafa);border-radius:var(--forms-fields-border-radius,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single{background-color:var(--forms-fields-normal-background-color,#f9fafa);border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);height:45px;margin:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single:focus{background-color:var(--forms-fields-focus-background-color,#f9fafa);border-color:initial;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__placeholder{color:var(--forms-fields-normal-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--forms-fields-normal-color,#69727d);line-height:45px;padding-left:1rem;padding-right:1rem}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__arrow{height:45px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--open .select2-dropdown--below{background-color:var(--forms-fields-normal-background-color,#f9fafa)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::-moz-placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce ::placeholder{color:var(--forms-fields-normal-color,inherit);font-family:inherit;opacity:.6}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-message{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce address{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a{color:var(--links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a:hover{color:var(--links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button.alt:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce a.button:hover{background-color:initial}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce em{color:var(--login-messages-color,#69727d);font-size:12px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row{margin-bottom:var(--forms-rows-gap,6px);margin-left:var(--forms-columns-gap-margin-left,0);margin-right:var(--forms-columns-gap-margin-right,0);padding-left:var(--forms-columns-gap-padding-left,0);padding-right:var(--forms-columns-gap-padding-right,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row label{color:var(--forms-labels-color,#69727d);margin-bottom:var(--forms-label-spacing,0)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select{background:#f9fafa;border:none;border-radius:var(--forms-fields-border-radius,0);color:var(--forms-fields-normal-color,#69727d);font-size:14px;padding:var(--forms-fields-padding,16px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus{border-color:#69727d;color:var(--forms-fields-focus-color,#69727d);transition-duration:var(--forms-fields-focus-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce #billing_address_1_field{margin-bottom:5px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-privacy-policy-text,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-privacy-policy-text{color:var(--login-messages-color,#69727d);font-size:12px;margin-bottom:15px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:not([class]),.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register p:not([class]){color:var(--login-messages-color,#69727d);font-size:12px;margin-top:10px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .woocommerce-LostPassword,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .woocommerce-LostPassword{font-size:12px;margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:50%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-first,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .form-row-last{width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:var(--sections-border-top-width,1px) var(--sections-border-right-width,1px) var(--sections-border-bottom-width,1px) var(--sections-border-left-width,1px);font-size:14px;padding:var(--sections-padding,16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login p:nth-child(3){margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__input-checkbox{vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-form__label-for-checkbox span{color:var(--checkboxes-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tr{border:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h2,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce h3{color:var(--typography-section-titles-color,#000);font-weight:400;margin-bottom:var(--section-title-spacing,45px);margin-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .wc-item-meta,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce strong.wc-item-meta-label{color:var(--variations-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .product-quantity{color:var(--tables-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-order-downloads{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content p:last-of-type{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content h2:first-of-type{margin-top:30px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content mark{background-color:transparent;color:var(--general-text-color,#000);font-weight:700}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce caption+thead tr:first-child th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce colgroup+thead tr:first-child th{border-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce thead:first-child tr:first-child th{border-top:0;padding-bottom:var(--tables-titles-spacing,9px);padding-inline-start:0;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(2n)>th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody>tr:nth-child(odd)>th{background-color:transparent;color:var(--tables-items-color,#69727d);padding-bottom:var(--order-summary-rows-gap-bottom,9px);padding-inline-start:0;padding-top:var(--order-summary-rows-gap-top,9px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce tbody .woocommerce-orders-table__cell.woocommerce-orders-table__cell-order-number>a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table{font-size:14px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table th{border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table thead tr th span{color:var(--tables-title-color,#000)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot td,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details tfoot th{color:var(--tables-title-color,#000);padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a{color:var(--tables-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .download-product a:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-name a:hover{color:var(--tables-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order_details .product-purchase-note td{border-top:none;padding-top:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);margin-bottom:0;margin-top:0;padding:var(--tables-button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .title h3,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .title h3{float:none}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address address,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses address{padding:var(--sections-padding,45px 30px 16px 30px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Address .edit,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-Addresses .edit{float:inline-start;margin-inline-start:var(--edit-link-margin-start,30px);margin-top:var(--edit-link-margin-top,10px);position:absolute}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .u-columns{margin-top:20px}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset{border:none;margin-inline-start:0;padding:0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm fieldset legend,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields fieldset legend{color:var(--general-text-color,#000);font-weight:700;padding:20px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button{background:#5bc0de;border:none;border-radius:var(--forms-buttons-border-radius,3px);color:var(--forms-buttons-normal-text-color,#fff);margin-top:20px;padding:var(--forms-buttons-padding,12px 32px)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover,.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover{color:var(--forms-buttons-hover-text-color,#fff);transition-duration:var(--forms-buttons-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination{padding:16px 0}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button{background:transparent;border-color:var(--tables-buttons-border-color,#5bc0de);border-radius:var(--tables-button-border-radius,3px);border-style:var(--tables-buttons-border-type,solid);border-width:2px;color:var(--tables-button-normal-text-color,#69727d);padding:var(--tables-button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button:hover{transition-duration:var(--tables-button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-my-account .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-OrderUpdates{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:inline-start;width:25%}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{width:100%}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul{padding-inline-start:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li{display:inline-block;list-style-type:none;width:var(--tab-width,100%)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{background-color:var(--tabs-divider-color,#69727d);content:"";display:block;height:var(--tabs-divider-weight,0);position:relative;top:calc(var(--tabs-spacing, 2px) / 2);width:100%}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.is-active a{background:#f1f2f3;border-color:var(--tabs-active-border-color,transparent);color:var(--tabs-active-color,#5bc0de)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{background:#f9fafa;border-color:var(--tabs-border-color,transparent);border-radius:var(--tabs-border-radius,0);border-style:var(--tabs-border-type,solid);border-width:0;color:var(--tabs-normal-color,#69727d);display:block;font-size:14px;font-style:normal;font-weight:700;padding:var(--tabs-padding,12px 20px);text-align:var(--tabs-alignment,start)}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover{border-color:var(--tabs-hover-border-color,transparent);color:var(--tabs-hover-color,#5bc0de)}@media (max-width:1024px){.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a{padding:var(--tabs-padding,10px)}}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout{margin-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout:after{display:none}.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-my-account .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-my-account .e-my-account-tab__view-order .shop_table td{line-height:unset;vertical-align:top}.elementor-widget-woocommerce-my-account .woocommerce-MyAccount-paymentMethods .woocommerce-PaymentMethod--actions{text-align:end}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio{vertical-align:middle}.elementor-widget-woocommerce-my-account .woocommerce-PaymentMethod .input-radio+label{color:var(--payment-methods-radio-buttons-color,#69727d)}.e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li{margin:calc(var(--tabs-spacing, 2px) / 2) 0}.e-my-account-tabs-vertical .woocommerce-MyAccount-navigation li.woocommerce-MyAccount-navigation-link--dashboard{margin-top:0}.e-my-account-tabs-vertical .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation{float:none;width:100%}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:after{display:none}.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{float:none;padding:var(--tab-content-spacing,50px) 0 0 0;width:100%}@media (max-width:1024px){.e-my-account-tabs-horizontal .e-my-account-tab .woocommerce .woocommerce-MyAccount-content{padding:var(--tab-content-spacing,6%) 0 0 0;width:100%}}.e-my-account-tabs-horizontal .woocommerce-MyAccount-navigation{display:none}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation{display:block}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:flex;justify-content:var(--tabs-container-justify-content,space-between);list-style:none;margin:0;padding:0}@media (max-width:767px){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul{display:block}}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{border-inline-end-color:var(--tabs-divider-color,#69727d);border-inline-end-style:solid;border-inline-end-width:var(--tabs-divider-weight,0);display:inline-block;margin:0;padding:0 calc(var(--tabs-spacing, 2px) / 2) 0 calc(var(--tabs-spacing, 2px) / 2);width:var(--tab-width,100%)}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:first-of-type{padding-inline-start:0}.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li:last-of-type{border-inline-end-width:0;padding-inline-end:0}@media (max-width:767px){.e-my-account-tabs-horizontal .e-wc-account-tabs-nav .woocommerce-MyAccount-navigation ul li{display:inline-block;margin:calc(var(--tabs-spacing, 2px) / 2) 0;width:100%}}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-number a,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-number a{pointer-events:none}.elementor-editor-active tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button,.elementor-editor-preview tr:not(:first-child) .woocommerce-orders-table__cell-order-actions .button{opacity:.3;pointer-events:none}.elementor-editor-active .elementor-widget-woocommerce-my-account .woocommerce-MyAccount-content:not(:first-of-type){display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-notices-rtl.min.css b/assets/css/widget-woocommerce-notices-rtl.min.css new file mode 100644 index 00000000..fa409ff1 --- /dev/null +++ b/assets/css/widget-woocommerce-notices-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-notices .e-woocommerce-notices-wrapper.e-woocommerce-notices-wrapper-loading *{display:none}.elementor-widget-woocommerce-notices .woocommerce .is-error,.elementor-widget-woocommerce-notices .woocommerce .is-info,.elementor-widget-woocommerce-notices .woocommerce .is-success,.elementor-widget-woocommerce-notices .woocommerce-error,.elementor-widget-woocommerce-notices .woocommerce-info,.elementor-widget-woocommerce-notices .woocommerce-message,.elementor-widget-woocommerce-notices .woocommerce-notices-wrapper{display:block}.e-preview--show-hidden-elements:not(.elementor-editor-active) .elementor-widget-woocommerce-notices .e-notices-demo-notice{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-notices.min.css b/assets/css/widget-woocommerce-notices.min.css new file mode 100644 index 00000000..fa409ff1 --- /dev/null +++ b/assets/css/widget-woocommerce-notices.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-notices .e-woocommerce-notices-wrapper.e-woocommerce-notices-wrapper-loading *{display:none}.elementor-widget-woocommerce-notices .woocommerce .is-error,.elementor-widget-woocommerce-notices .woocommerce .is-info,.elementor-widget-woocommerce-notices .woocommerce .is-success,.elementor-widget-woocommerce-notices .woocommerce-error,.elementor-widget-woocommerce-notices .woocommerce-info,.elementor-widget-woocommerce-notices .woocommerce-message,.elementor-widget-woocommerce-notices .woocommerce-notices-wrapper{display:block}.e-preview--show-hidden-elements:not(.elementor-editor-active) .elementor-widget-woocommerce-notices .e-notices-demo-notice{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-add-to-cart-rtl.min.css b/assets/css/widget-woocommerce-product-add-to-cart-rtl.min.css new file mode 100644 index 00000000..38b8639a --- /dev/null +++ b/assets/css/widget-woocommerce-product-add-to-cart-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart{margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart:not(.grouped_form):not(.variations_form){display:flex;flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart button:where(:not(:first-child)){margin-block-start:0;margin-inline-start:var(--button-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container{display:flex;flex-wrap:wrap;gap:var(--view-cart-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container>*{display:flex;flex-basis:auto;margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;vertical-align:top}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity input{height:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart:not(.grouped_form):not(.variations_form),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart:not(.grouped_form):not(.variations_form){display:block}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{display:flex}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button:where(:not(:first-child)){margin-block-start:var(--button-spacing,10px);margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder{flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder button{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart button{flex-basis:100%}@media (min-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:1024px){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:767px){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart button{flex-basis:100%}}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .quantity{display:none!important}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart button:where(:not(:first-child)){margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart button:where(:not(:first-child)){margin-block-start:0}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart input.qty.disabled{pointer-events:none}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart .button{text-align:center}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) .added_to_cart{align-items:center;display:flex;margin:0;padding:0}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;text-align:center;vertical-align:top;width:3.631em}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-info button.button.alt.elementor-button{background-color:#5bc0de}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-success button.button.alt.elementor-button{background-color:#5cb85c}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-warning button.button.alt.elementor-button{background-color:#f0ad4e}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-danger button.button.alt.elementor-button{background-color:#d9534f}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-add-to-cart.min.css b/assets/css/widget-woocommerce-product-add-to-cart.min.css new file mode 100644 index 00000000..67358023 --- /dev/null +++ b/assets/css/widget-woocommerce-product-add-to-cart.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart{margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart:not(.grouped_form):not(.variations_form){display:flex;flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) form.cart button:where(:not(:first-child)){margin-block-start:0;margin-inline-start:var(--button-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container{display:flex;flex-wrap:wrap;gap:var(--view-cart-spacing,10px)}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .e-loop-add-to-cart-form-container>*{display:flex;flex-basis:auto;margin:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;vertical-align:top}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity input{height:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto form.cart:not(.grouped_form):not(.variations_form),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked form.cart:not(.grouped_form):not(.variations_form){display:block}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{display:flex}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-loop-add-to-cart-form-container>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder{flex-wrap:wrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder>*{flex-basis:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-stacked .e-atc-qty-button-holder button:where(:not(:first-child)){margin-block-start:var(--button-spacing,10px);margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder{flex-wrap:nowrap}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--layout-auto .e-atc-qty-button-holder button{vertical-align:middle}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart--align-justify form.cart button{flex-basis:100%}@media (min-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-widescreen--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-laptop--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:1024px){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-tablet--align-justify form.cart button{flex-basis:100%}}@media (max-width:-1){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile_extra--align-justify form.cart button{flex-basis:100%}}@media (max-width:767px){:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left .e-loop-add-to-cart-form-container{justify-content:flex-start;text-align:left}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right .e-loop-add-to-cart-form-container{justify-content:flex-end;text-align:right}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]){text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart.variations_form .woocommerce-variation-add-to-cart,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center:not([class*="--layout-stacked"]):not([class*="--layout-auto"]) form.cart:not(.grouped_form):not(.variations_form){justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-auto"] .e-atc-qty-button-holder,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center[class*="--layout-stacked"] .e-atc-qty-button-holder{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center .e-loop-add-to-cart-form-container{justify-content:center;text-align:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart div.quantity,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart div.quantity{margin-inline-end:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-center form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-left form.cart button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-right form.cart button{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify:not([class*="--layout-stacked"]):not([class*="--layout-auto"]):not([class*=-product-add-to-cart]) .elementor-button{width:100%}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container>*{flex-basis:100%;justify-content:center}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify .e-loop-add-to-cart-form-container a.added_to_cart{flex-basis:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart div.quantity{margin-inline-end:auto}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart .button,:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart,.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-add-to-cart-mobile--align-justify form.cart button{flex-basis:100%}}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .quantity{display:none!important}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes) form.cart button:where(:not(:first-child)){margin-inline-start:0}:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart .button:where(:not(:first-child)),:is(.elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .elementor-widget-woocommerce-product-add-to-cart):not(.e-add-to-cart--show-quantity-yes)[class*="--layout-stacked"] form.cart button:where(:not(:first-child)){margin-block-start:0}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart input.qty.disabled{pointer-events:none}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) form.cart .button{text-align:center}:is(.e-loop-item .elementor-widget-woocommerce-product-add-to-cart,.woocommerce div.product .e-loop-item .elementor-widget-woocommerce-product-add-to-cart) .added_to_cart{align-items:center;display:flex;margin:0;padding:0}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity{vertical-align:middle}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart) .quantity .qty{margin-inline-end:0;text-align:center;vertical-align:top;width:3.631em}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-info button.button.alt.elementor-button{background-color:#5bc0de}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-success button.button.alt.elementor-button{background-color:#5cb85c}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-warning button.button.alt.elementor-button{background-color:#f0ad4e}:is(.elementor-widget-wc-add-to-cart,.woocommerce div.product .elementor-widget-wc-add-to-cart).elementor-button-danger button.button.alt.elementor-button{background-color:#d9534f}.woocommerce div.product.elementor form.cart div.product-addon{flex-basis:100%;flex-shrink:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-additional-information-rtl.min.css b/assets/css/widget-woocommerce-product-additional-information-rtl.min.css new file mode 100644 index 00000000..d33cea4f --- /dev/null +++ b/assets/css/widget-woocommerce-product-additional-information-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-product-additional-information:not(.elementor-show-heading-yes) h2{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-additional-information.min.css b/assets/css/widget-woocommerce-product-additional-information.min.css new file mode 100644 index 00000000..d33cea4f --- /dev/null +++ b/assets/css/widget-woocommerce-product-additional-information.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-product-additional-information:not(.elementor-show-heading-yes) h2{display:none} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-data-tabs-rtl.min.css b/assets/css/widget-woocommerce-product-data-tabs-rtl.min.css new file mode 100644 index 00000000..d2c354ea --- /dev/null +++ b/assets/css/widget-woocommerce-product-data-tabs-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce div.product.elementor ul.tabs:before{border-bottom:0;bottom:auto;content:none;left:auto;position:static;width:auto;z-index:auto}.woocommerce div.product.elementor ul.tabs{margin:0}.woocommerce div.product.elementor ul.tabs li{padding:0}.woocommerce div.product.elementor ul.tabs li a{line-height:1;padding:.8em 1.2em}.woocommerce div.product.elementor ul.tabs li:after,.woocommerce div.product.elementor ul.tabs li:before{border:0;bottom:auto;box-sizing:border-box;content:none;height:auto;position:static;width:auto}.woocommerce div.product.elementor .woocommerce-tabs .panel{border-radius:0;border-width:0;border-top:1px solid #d3ced2;box-shadow:none;margin:-1px 0 0;padding:20px} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-data-tabs.min.css b/assets/css/widget-woocommerce-product-data-tabs.min.css new file mode 100644 index 00000000..d2c354ea --- /dev/null +++ b/assets/css/widget-woocommerce-product-data-tabs.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce div.product.elementor ul.tabs:before{border-bottom:0;bottom:auto;content:none;left:auto;position:static;width:auto;z-index:auto}.woocommerce div.product.elementor ul.tabs{margin:0}.woocommerce div.product.elementor ul.tabs li{padding:0}.woocommerce div.product.elementor ul.tabs li a{line-height:1;padding:.8em 1.2em}.woocommerce div.product.elementor ul.tabs li:after,.woocommerce div.product.elementor ul.tabs li:before{border:0;bottom:auto;box-sizing:border-box;content:none;height:auto;position:static;width:auto}.woocommerce div.product.elementor .woocommerce-tabs .panel{border-radius:0;border-width:0;border-top:1px solid #d3ced2;box-shadow:none;margin:-1px 0 0;padding:20px} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-images-rtl.min.css b/assets/css/widget-woocommerce-product-images-rtl.min.css new file mode 100644 index 00000000..f1eabccf --- /dev/null +++ b/assets/css/widget-woocommerce-product-images-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor.product .woocommerce-product-gallery__trigger+.woocommerce-product-gallery__wrapper{overflow:hidden}.woocommerce .elementor-widget-woocommerce-product-images span.onsale{padding:0}body.woocommerce #content div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce-page #content div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce-page div.product .elementor-widget-woocommerce-product-images div.images{float:none;padding:0;width:100%}body.rtl.woocommerce #content div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce-page #content div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce-page div.product .elementor-widget-woocommerce-product-images div.images{float:none;padding:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-images.min.css b/assets/css/widget-woocommerce-product-images.min.css new file mode 100644 index 00000000..f1eabccf --- /dev/null +++ b/assets/css/widget-woocommerce-product-images.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor.product .woocommerce-product-gallery__trigger+.woocommerce-product-gallery__wrapper{overflow:hidden}.woocommerce .elementor-widget-woocommerce-product-images span.onsale{padding:0}body.woocommerce #content div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce-page #content div.product .elementor-widget-woocommerce-product-images div.images,body.woocommerce-page div.product .elementor-widget-woocommerce-product-images div.images{float:none;padding:0;width:100%}body.rtl.woocommerce #content div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce-page #content div.product .elementor-widget-woocommerce-product-images div.images,body.rtl.woocommerce-page div.product .elementor-widget-woocommerce-product-images div.images{float:none;padding:0} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-meta-rtl.min.css b/assets/css/widget-woocommerce-product-meta-rtl.min.css new file mode 100644 index 00000000..bade2415 --- /dev/null +++ b/assets/css/widget-woocommerce-product-meta-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-product-meta .detail-container{position:relative}.elementor-widget-woocommerce-product-meta .detail-container:after{bottom:0;left:0;position:absolute;width:100%}.elementor-widget-woocommerce-product-meta .detail-label{font-weight:700}.elementor-woo-meta--view-inline .product_meta{display:flex;flex-wrap:wrap}.elementor-woo-meta--view-inline .product_meta .detail-container:after{border-bottom:0;border-left-width:1px;border-right:0;border-top:0;border-style:solid;height:100%;inset-block-start:50%;inset-inline:auto -8px;position:absolute;transform:translateY(-50%);width:auto}.elementor-woo-meta--view-table .product_meta{display:flex;flex-direction:column}.elementor-woo-meta--view-table .product_meta .detail-container{display:flex}.elementor-woo-meta--view-table .product_meta .detail-label{min-width:108px}.elementor-woo-meta--view-stacked .product_meta .detail-container{display:block} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-meta.min.css b/assets/css/widget-woocommerce-product-meta.min.css new file mode 100644 index 00000000..bade2415 --- /dev/null +++ b/assets/css/widget-woocommerce-product-meta.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-product-meta .detail-container{position:relative}.elementor-widget-woocommerce-product-meta .detail-container:after{bottom:0;left:0;position:absolute;width:100%}.elementor-widget-woocommerce-product-meta .detail-label{font-weight:700}.elementor-woo-meta--view-inline .product_meta{display:flex;flex-wrap:wrap}.elementor-woo-meta--view-inline .product_meta .detail-container:after{border-bottom:0;border-left-width:1px;border-right:0;border-top:0;border-style:solid;height:100%;inset-block-start:50%;inset-inline:auto -8px;position:absolute;transform:translateY(-50%);width:auto}.elementor-woo-meta--view-table .product_meta{display:flex;flex-direction:column}.elementor-woo-meta--view-table .product_meta .detail-container{display:flex}.elementor-woo-meta--view-table .product_meta .detail-label{min-width:108px}.elementor-woo-meta--view-stacked .product_meta .detail-container{display:block} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-price-rtl.min.css b/assets/css/widget-woocommerce-product-price-rtl.min.css new file mode 100644 index 00000000..790c434f --- /dev/null +++ b/assets/css/widget-woocommerce-product-price-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce .elementor-product-price-block-yes.elementor-widget-woocommerce-product-price .price del,.woocommerce .elementor-product-price-block-yes.elementor-widget-woocommerce-product-price .price ins{display:block} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-price.min.css b/assets/css/widget-woocommerce-product-price.min.css new file mode 100644 index 00000000..790c434f --- /dev/null +++ b/assets/css/widget-woocommerce-product-price.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce .elementor-product-price-block-yes.elementor-widget-woocommerce-product-price .price del,.woocommerce .elementor-product-price-block-yes.elementor-widget-woocommerce-product-price .price ins{display:block} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-rating-rtl.min.css b/assets/css/widget-woocommerce-product-rating-rtl.min.css new file mode 100644 index 00000000..f74f95b7 --- /dev/null +++ b/assets/css/widget-woocommerce-product-rating-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce .elementor-widget-woocommerce-product-rating .elementor-widget-container .woocommerce-product-rating,.woocommerce .elementor-widget-woocommerce-product-rating:not(:has(.elementor-widget-container)) .woocommerce-product-rating{align-items:center;display:flex;margin-bottom:0}.woocommerce .elementor-widget-woocommerce-product-rating .elementor-widget-container .star-rating,.woocommerce .elementor-widget-woocommerce-product-rating:not(:has(.elementor-widget-container)) .star-rating{margin-top:0}.elementor-product-rating--align-left .woocommerce-product-rating{justify-content:flex-end}.elementor-product-rating--align-right .woocommerce-product-rating{justify-content:flex-start}.elementor-product-rating--align-center .woocommerce-product-rating{justify-content:center}.elementor-product-rating--align-justify .woocommerce-product-rating .woocommerce-review-link{margin-inline-start:auto} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-product-rating.min.css b/assets/css/widget-woocommerce-product-rating.min.css new file mode 100644 index 00000000..9360cf18 --- /dev/null +++ b/assets/css/widget-woocommerce-product-rating.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.woocommerce .elementor-widget-woocommerce-product-rating .elementor-widget-container .woocommerce-product-rating,.woocommerce .elementor-widget-woocommerce-product-rating:not(:has(.elementor-widget-container)) .woocommerce-product-rating{align-items:center;display:flex;margin-bottom:0}.woocommerce .elementor-widget-woocommerce-product-rating .elementor-widget-container .star-rating,.woocommerce .elementor-widget-woocommerce-product-rating:not(:has(.elementor-widget-container)) .star-rating{margin-top:0}.elementor-product-rating--align-left .woocommerce-product-rating{justify-content:flex-start}.elementor-product-rating--align-right .woocommerce-product-rating{justify-content:flex-end}.elementor-product-rating--align-center .woocommerce-product-rating{justify-content:center}.elementor-product-rating--align-justify .woocommerce-product-rating .woocommerce-review-link{margin-inline-start:auto} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-products-archive-rtl.min.css b/assets/css/widget-woocommerce-products-archive-rtl.min.css new file mode 100644 index 00000000..2d9cfad5 --- /dev/null +++ b/assets/css/widget-woocommerce-products-archive-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@media (min-width:1025px){.elementor-widget-wc-archive-products .woocommerce.columns-2 ul.products{grid-template-columns:repeat(2,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-3 ul.products{grid-template-columns:repeat(3,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-4 ul.products{grid-template-columns:repeat(4,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-5 ul.products{grid-template-columns:repeat(5,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-6 ul.products{grid-template-columns:repeat(6,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-7 ul.products{grid-template-columns:repeat(7,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-8 ul.products{grid-template-columns:repeat(8,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-9 ul.products{grid-template-columns:repeat(9,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-10 ul.products{grid-template-columns:repeat(10,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-11 ul.products{grid-template-columns:repeat(11,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-12 ul.products{grid-template-columns:repeat(12,1fr)}}@media (max-width:1024px){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(3,1fr)}}@media (max-width:767px){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(2,1fr)}} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-products-archive.min.css b/assets/css/widget-woocommerce-products-archive.min.css new file mode 100644 index 00000000..2d9cfad5 --- /dev/null +++ b/assets/css/widget-woocommerce-products-archive.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +@media (min-width:1025px){.elementor-widget-wc-archive-products .woocommerce.columns-2 ul.products{grid-template-columns:repeat(2,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-3 ul.products{grid-template-columns:repeat(3,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-4 ul.products{grid-template-columns:repeat(4,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-5 ul.products{grid-template-columns:repeat(5,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-6 ul.products{grid-template-columns:repeat(6,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-7 ul.products{grid-template-columns:repeat(7,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-8 ul.products{grid-template-columns:repeat(8,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-9 ul.products{grid-template-columns:repeat(9,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-10 ul.products{grid-template-columns:repeat(10,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-11 ul.products{grid-template-columns:repeat(11,1fr)}.elementor-widget-wc-archive-products .woocommerce.columns-12 ul.products{grid-template-columns:repeat(12,1fr)}}@media (max-width:1024px){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(3,1fr)}}@media (max-width:767px){.elementor-widget-wc-archive-products .products{grid-template-columns:repeat(2,1fr)}} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-products-rtl.min.css b/assets/css/widget-woocommerce-products-rtl.min.css new file mode 100644 index 00000000..128f7a25 --- /dev/null +++ b/assets/css/widget-woocommerce-products-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-products-grid ul.products.elementor-grid{display:grid;margin:0;grid-column-gap:20px;grid-row-gap:40px}.elementor-products-grid ul.products.elementor-grid:after,.elementor-products-grid ul.products.elementor-grid:before{content:none;display:none}.elementor-products-grid ul.products.elementor-grid li.product{display:var(--button-align-display);flex-direction:var(--button-align-direction);float:none;justify-content:var(--button-align-justify);margin:0;padding:0;width:auto}.elementor-products-grid ul.products.elementor-grid li.product .onsale{display:none;padding:0}.elementor-products-grid ul.products.elementor-grid li.product a.woocommerce-loop-product__link{display:block;position:relative}.elementor-products-grid:not(.show-heading-yes) .products>h2{display:none}.elementor-products-grid nav.woocommerce-pagination{margin-top:40px}.elementor-products-grid:not(.elementor-show-pagination-border-yes) nav.woocommerce-pagination ul{border:0}.elementor-products-grid:not(.elementor-show-pagination-border-yes) nav.woocommerce-pagination ul li{border-left:0;border-right:0}.elementor-widget-woocommerce-products:not(.products-heading-show) .cross-sells>h2,.elementor-widget-woocommerce-products:not(.products-heading-show) .related>h2,.elementor-widget-woocommerce-products:not(.products-heading-show) .upsells>h2{display:none}.elementor-widget-woocommerce-products.products-heading-show .cross-sells>h2,.elementor-widget-woocommerce-products.products-heading-show .related>h2,.elementor-widget-woocommerce-products.products-heading-show .upsells>h2{color:var(--products-title-color);display:block;margin-bottom:var(--products-title-spacing,1rem);text-align:var(--products-title-alignment,start)}.elementor-product-loop-item--align-left ul.products li.product .star-rating{margin-right:auto}.elementor-product-loop-item--align-right ul.products li.product .star-rating{margin-left:auto}.elementor-product-loop-item--align-center ul.products li.product .star-rating{margin-left:auto;margin-right:auto}.woocommerce .elementor-element.elementor-products-grid ul.products li.product,.woocommerce div.product .elementor-element.elementor-products-grid .related.products ul.products li.product,.woocommerce div.product .elementor-element.elementor-products-grid .upsells.products ul.products li.product{width:auto} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-products.min.css b/assets/css/widget-woocommerce-products.min.css new file mode 100644 index 00000000..128f7a25 --- /dev/null +++ b/assets/css/widget-woocommerce-products.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-products-grid ul.products.elementor-grid{display:grid;margin:0;grid-column-gap:20px;grid-row-gap:40px}.elementor-products-grid ul.products.elementor-grid:after,.elementor-products-grid ul.products.elementor-grid:before{content:none;display:none}.elementor-products-grid ul.products.elementor-grid li.product{display:var(--button-align-display);flex-direction:var(--button-align-direction);float:none;justify-content:var(--button-align-justify);margin:0;padding:0;width:auto}.elementor-products-grid ul.products.elementor-grid li.product .onsale{display:none;padding:0}.elementor-products-grid ul.products.elementor-grid li.product a.woocommerce-loop-product__link{display:block;position:relative}.elementor-products-grid:not(.show-heading-yes) .products>h2{display:none}.elementor-products-grid nav.woocommerce-pagination{margin-top:40px}.elementor-products-grid:not(.elementor-show-pagination-border-yes) nav.woocommerce-pagination ul{border:0}.elementor-products-grid:not(.elementor-show-pagination-border-yes) nav.woocommerce-pagination ul li{border-left:0;border-right:0}.elementor-widget-woocommerce-products:not(.products-heading-show) .cross-sells>h2,.elementor-widget-woocommerce-products:not(.products-heading-show) .related>h2,.elementor-widget-woocommerce-products:not(.products-heading-show) .upsells>h2{display:none}.elementor-widget-woocommerce-products.products-heading-show .cross-sells>h2,.elementor-widget-woocommerce-products.products-heading-show .related>h2,.elementor-widget-woocommerce-products.products-heading-show .upsells>h2{color:var(--products-title-color);display:block;margin-bottom:var(--products-title-spacing,1rem);text-align:var(--products-title-alignment,start)}.elementor-product-loop-item--align-left ul.products li.product .star-rating{margin-right:auto}.elementor-product-loop-item--align-right ul.products li.product .star-rating{margin-left:auto}.elementor-product-loop-item--align-center ul.products li.product .star-rating{margin-left:auto;margin-right:auto}.woocommerce .elementor-element.elementor-products-grid ul.products li.product,.woocommerce div.product .elementor-element.elementor-products-grid .related.products ul.products li.product,.woocommerce div.product .elementor-element.elementor-products-grid .upsells.products ul.products li.product{width:auto} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-purchase-summary-rtl.min.css b/assets/css/widget-woocommerce-purchase-summary-rtl.min.css new file mode 100644 index 00000000..51e8d23f --- /dev/null +++ b/assets/css/widget-woocommerce-purchase-summary-rtl.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-purchase-summary{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>td,.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>th{background-color:initial}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details{display:flex;flex-wrap:wrap;margin:0 0 2em;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-inline-end-color:var(--payment-details-border-color,#d5d8dc);border-inline-end-style:var(--payment-details-border-type,solid);border-inline-end-width:var(--payment-details-border-width,1px);color:var(--payment-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--payment-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--payment-details-space-between,4em);text-transform:capitalize}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-bottom:var(--payment-details-border-width,1px) var(--payment-details-border-type,solid) var(--payment-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--payment-details-space-between, 20px) / 2);padding-top:calc(var(--payment-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{color:var(--payment-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--payment-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details{display:flex;flex-wrap:wrap;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-inline-end-color:var(--bank-details-border-color,#d5d8dc);border-inline-end-style:var(--bank-details-border-type,solid);border-inline-end-width:var(--bank-details-border-width,1px);color:var(--bank-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--bank-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--bank-details-space-between,4em);text-transform:capitalize}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-bottom:var(--bank-details-border-width,1px) var(--bank-details-border-type,solid) var(--bank-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--bank-details-space-between, 20px) / 2);padding-top:calc(var(--bank-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{color:var(--bank-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--bank-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li:last-of-type{border-inline-end:none}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta .wc-item-meta-label,.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta li p{color:var(--order-details-variations-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;font-size:14px;margin-bottom:0;padding:var(--sections-padding,15px 30px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt{background-color:transparent;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);padding:var(--button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table th{border:0;border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc);padding-block:calc(var(--order-details-rows-gap, 18px) / 2);padding-inline:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th{border-top:none;color:var(--order-details-titles-totals-color,#000);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th span{color:var(--order-details-titles-totals-color,#000)}@media (min-width:1025px){.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td{line-height:unset;vertical-align:top}}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td .woocommerce-Price-amount{color:var(--order-details-items-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot th{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child th{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-quantity,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-expires,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-remaining{color:var(--order-details-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-purchase-note td{border-top:none;color:var(--general-text-color,#69727d);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-table--order-downloads tr td:before{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);margin-bottom:0;margin-top:40px;padding:var(--button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce h2{color:var(--titles-color,#000);font-weight:400;margin-bottom:var(--titles-spacing,45px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-details h2{text-align:var(--order-summary-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-heading{text-align:var(--bank-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-downloads__title{text-align:var(--downloads-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--billing-address h2,.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-customer-details>h2{text-align:var(--billing-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--shipping-address h2{text-align:var(--shipping-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce a{color:var(--order-details-product-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce a:hover{color:var(--order-details-product-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce p{margin-bottom:20px}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-received{color:var(--confirmation-message-color,#69727d);display:var(--confirmation-message-display,none);margin-bottom:var(--sections-spacing,40px);text-align:var(--confirmation-message-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-purchase-summary .woocommerce address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;color:var(--general-text-color,#69727d);padding:var(--sections-padding,15px 30px)}@media (max-width:767px){.elementor-widget-woocommerce-purchase-summary .woocommerce-column--2{margin-top:2em}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details+p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-account-name{color:var(--account-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--account-title-spacing,1rem)}.elementor-widget-woocommerce-purchase-summary .woocommerce section{margin-top:var(--sections-spacing,4em)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details:last-child{margin-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details{table-layout:fixed}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details td{word-wrap:break-word} \ No newline at end of file diff --git a/assets/css/widget-woocommerce-purchase-summary.min.css b/assets/css/widget-woocommerce-purchase-summary.min.css new file mode 100644 index 00000000..51e8d23f --- /dev/null +++ b/assets/css/widget-woocommerce-purchase-summary.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-widget-woocommerce-purchase-summary{color:#69727d;font-family:Roboto,sans-serif;font-size:14px}.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>td,.elementor-widget-woocommerce-purchase-summary table tbody tr:hover>th{background-color:initial}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details{display:flex;flex-wrap:wrap;margin:0 0 2em;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-inline-end-color:var(--payment-details-border-color,#d5d8dc);border-inline-end-style:var(--payment-details-border-type,solid);border-inline-end-width:var(--payment-details-border-width,1px);color:var(--payment-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--payment-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--payment-details-space-between,4em);text-transform:capitalize}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li{border-bottom:var(--payment-details-border-width,1px) var(--payment-details-border-type,solid) var(--payment-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--payment-details-space-between, 20px) / 2);padding-top:calc(var(--payment-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{color:var(--payment-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--payment-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details{display:flex;flex-wrap:wrap;padding-inline-start:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-inline-end-color:var(--bank-details-border-color,#d5d8dc);border-inline-end-style:var(--bank-details-border-type,solid);border-inline-end-width:var(--bank-details-border-width,1px);color:var(--bank-details-titles-color,#000);float:unset;font-size:14px;font-weight:700;margin-inline-end:var(--bank-details-space-between,4em);margin-bottom:30px;padding-inline-end:var(--bank-details-space-between,4em);text-transform:capitalize}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li{border-bottom:var(--bank-details-border-width,1px) var(--bank-details-border-type,solid) var(--bank-details-border-color,#d5d8dc);border-inline-end:none;display:flex;justify-content:space-between;margin-inline-end:0;margin-bottom:0;padding-inline-end:0;padding-bottom:calc(var(--bank-details-space-between, 20px) / 2);padding-top:calc(var(--bank-details-space-between, 20px) / 2);width:100%}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{color:var(--bank-details-items-color,#69727d);font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:normal;margin-top:var(--bank-details-titles-spacing,10px);text-shadow:none;text-transform:none}@media (max-width:1024px){.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong{margin-top:0}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-bacs-bank-details .wc-bacs-bank-details li:last-of-type{border-inline-end:none}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta .wc-item-meta-label,.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-item-meta li p{color:var(--order-details-variations-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;font-size:14px;margin-bottom:0;padding:var(--sections-padding,15px 30px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt{background-color:transparent;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);padding:var(--button-padding,5px 10px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .button.alt:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table th{border:0;border-top:var(--tables-divider-border-width,1px) var(--tables-divider-border-type,solid) var(--tables-divider-border-color,#d5d8dc);padding-block:calc(var(--order-details-rows-gap, 18px) / 2);padding-inline:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th{border-top:none;color:var(--order-details-titles-totals-color,#000);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table thead tr th span{color:var(--order-details-titles-totals-color,#000)}@media (min-width:1025px){.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td{line-height:unset;vertical-align:top}}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tbody td .woocommerce-Price-amount{color:var(--order-details-items-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot th{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child td,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table tfoot tr:last-child th{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-quantity,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-expires,.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table td.download-remaining{color:var(--order-details-items-color,#69727d);font-weight:400}.elementor-widget-woocommerce-purchase-summary .woocommerce .shop_table .product-purchase-note td{border-top:none;color:var(--general-text-color,#69727d);padding-top:0}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-table--order-downloads tr td:before{color:var(--order-details-titles-totals-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button{background:transparent;border:2px solid #5bc0de;border-color:var(--buttons-border-color,#5bc0de);border-radius:var(--button-border-radius,3px);border-style:var(--buttons-border-type,solid);border-width:2px;color:var(--button-normal-text-color,#69727d);margin-bottom:0;margin-top:40px;padding:var(--button-padding,12px 32px);vertical-align:middle}.elementor-widget-woocommerce-purchase-summary .woocommerce .order-again .button:hover{color:var(--button-hover-text-color,#69727d);transition-duration:var(--button-hover-transition-duration,.3s)}.elementor-widget-woocommerce-purchase-summary .woocommerce h2{color:var(--titles-color,#000);font-weight:400;margin-bottom:var(--titles-spacing,45px)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-details h2{text-align:var(--order-summary-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-heading{text-align:var(--bank-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-order-downloads__title{text-align:var(--downloads-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--billing-address h2,.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-customer-details>h2{text-align:var(--billing-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-column--shipping-address h2{text-align:var(--shipping-details-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce a{color:var(--order-details-product-links-normal-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce a:hover{color:var(--order-details-product-links-hover-color,#5bc0de)}.elementor-widget-woocommerce-purchase-summary .woocommerce p{margin-bottom:20px}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-received{color:var(--confirmation-message-color,#69727d);display:var(--confirmation-message-display,none);margin-bottom:var(--sections-spacing,40px);text-align:var(--confirmation-message-alignment,inherit)}.elementor-widget-woocommerce-purchase-summary .woocommerce strong{color:var(--general-text-color,#000)}.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>td,.elementor-widget-woocommerce-purchase-summary .woocommerce table tbody>tr:nth-child(odd)>th{background-color:transparent}.elementor-widget-woocommerce-purchase-summary .woocommerce address{background-color:var(--sections-background-color,#fff);border-color:var(--sections-border-color,#d5d8dc);border-radius:var(--sections-border-radius,3px);border-style:var(--sections-border-type,solid);border-width:1px;color:var(--general-text-color,#69727d);padding:var(--sections-padding,15px 30px)}@media (max-width:767px){.elementor-widget-woocommerce-purchase-summary .woocommerce-column--2{margin-top:2em}}.elementor-widget-woocommerce-purchase-summary .woocommerce .woocommerce-thankyou-order-details+p{color:var(--general-text-color,#69727d)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details-account-name{color:var(--account-title-color,#000);font-size:14px;font-weight:700;margin-bottom:var(--account-title-spacing,1rem)}.elementor-widget-woocommerce-purchase-summary .woocommerce section{margin-top:var(--sections-spacing,4em)}.elementor-widget-woocommerce-purchase-summary .woocommerce .wc-bacs-bank-details:last-child{margin-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-name.product-purchase-note-is-below,.elementor-widget-woocommerce-purchase-summary .woocommerce-table__line-item.order_item .woocommerce-table__product-total.product-total.product-purchase-note-is-below{padding-bottom:0}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details{table-layout:fixed}.elementor-widget-woocommerce-purchase-summary .woocommerce-table--order-details td{word-wrap:break-word} \ No newline at end of file diff --git a/assets/css/woocommerce-notices.css b/assets/css/woocommerce-notices.css new file mode 100644 index 00000000..50431380 --- /dev/null +++ b/assets/css/woocommerce-notices.css @@ -0,0 +1,302 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-editor-preview .woocommerce-notices-wrapper { + padding: 2em 2em 0.3em; +} +.elementor-editor-preview .woocommerce-notices-wrapper.elementor-loading { + opacity: 0.3; +} + +.e-wc-message-notice .woocommerce-message { + border: 0 solid #000000; + border-top: 3px solid var(--message-message-icon-color, #95AC3C); + background-color: #FAFBF5; + color: var(--message-message-text-color, #3f444b); + border-radius: var(--message-box-border-radius, 0); +} +.e-wc-message-notice .woocommerce-message a:not([class]), +.e-wc-message-notice .woocommerce-message .restore-item { + color: var(--notice-message-normal-links-color, #3f444b); + text-decoration: underline; + font-size: 16px; + font-family: Roboto; + font-weight: 400; + line-height: 24px; + text-transform: none; + text-shadow: none; + font-style: normal; + letter-spacing: 0; +} +.e-wc-message-notice .woocommerce-message a:not([class]):hover, +.e-wc-message-notice .woocommerce-message .restore-item:hover { + color: var(--notice-message-hover-links-color, #3f444b); +} +.e-wc-message-notice .woocommerce-message .button { + border-style: var(--message-border-type, solid); + border-color: var(--message-border-color, #95AC3C); + border-width: 1px; + color: var(--message-buttons-normal-text-color, #95AC3C); + background-color: transparent; + padding: var(--message-buttons-padding, 6px 12px); + font-size: 14px; + border-radius: var(--message-buttons-border-radius, 0); + line-height: 1; + font-weight: 400; + transition-duration: var(--message-buttons-hover-transition-duration, 0.3s); + transition-property: color, background, box-shadow; + text-transform: none; + text-shadow: none; + font-style: normal; + letter-spacing: 0; + font-family: Roboto, sans-serif; +} +.e-wc-message-notice .woocommerce-message .button:hover { + color: var(--message-buttons-hover-text-color, #95AC3C); + border-color: var(--message-buttons-hover-border-color, #95AC3C); + background-color: transparent; +} +.e-wc-message-notice .woocommerce-message::before { + color: var(--message-message-icon-color, #95AC3C); +} +.e-wc-info-notice { + /* Need to override some 'Links' styling from My Account Widget */ +} +.e-wc-info-notice .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-info .woocommerce-Button { + color: var(--info-buttons-normal-text-color, #3F84B9); +} +.e-wc-info-notice .woocommerce-info { + border: 0 solid #000000; + border-top: 3px solid var(--info-message-icon-color, #3F84B9); + background-color: #F6F9FB; + color: var(--info-message-text-color, #3f444b); + border-radius: var(--info-box-border-radius, 0); +} +.e-wc-info-notice .woocommerce-info .button { + border-style: var(--info-border-type, solid); + border-color: var(--info-border-color, #3F84B9); + border-width: 1px; + color: var(--info-buttons-normal-text-color, #3F84B9); + background-color: transparent; + padding: var(--info-buttons-padding, 6px 12px); + font-size: 14px; + border-radius: var(--info-buttons-border-radius, 0); + line-height: 1; + font-weight: 400; + transition-duration: var(--info-buttons-hover-transition-duration, 0.3s); + transition-property: color, background, box-shadow; + text-transform: none; + text-shadow: none; + font-style: normal; + letter-spacing: 0; + font-family: Roboto, sans-serif; +} +.e-wc-info-notice .woocommerce-info .button:hover { + color: var(--info-buttons-hover-text-color, #3F84B9); + border-color: var(--info-buttons-hover-border-color, #3F84B9); + background-color: transparent; +} +.e-wc-info-notice .woocommerce-info::before { + color: var(--info-message-icon-color, #3F84B9); +} +.e-wc-error-notice { + /* Need to override some styling from the My Account Widget */ +} +.e-wc-error-notice .elementor-widget-woocommerce-my-account .woocommerce .woocommerce-error strong { + color: var(--error-message-text-color, #3f444b); +} +.e-wc-error-notice .woocommerce-error { + border: 0 solid #000000; + border-top: 3px solid var(--error-message-icon-color, #b81c23); + background-color: #F9F2F5; + color: var(--error-message-text-color, #3f444b); + border-radius: var(--error-box-border-radius, 0); +} +.e-wc-error-notice .woocommerce-error .wc-backward { + color: var(--error-message-normal-links-color, #3f444b); + text-decoration: underline; + font-size: 16px; + font-family: Roboto; + font-weight: 400; + line-height: 1; + text-transform: none; + text-shadow: none; + font-style: normal; + letter-spacing: 0; +} +.e-wc-error-notice .woocommerce-error .wc-backward:hover { + color: var(--error-message-hover-links-color, #3f444b); +} +.e-wc-error-notice .woocommerce-error::before { + color: var(--error-message-icon-color, #b81c23); +} + +div.wc-block-components-notice-banner { + --wc-blocks-notice-banner-color: #2f2f2f; + --wc-blocks-notice-banner-padding: 16px; + --wc-blocks-notice-banner-gap: 12px; + --wc-blocks-notice-banner-gap-smaller: 8px; + --wc-blocks-notice-banner-gap-large: 24px; + --wc-blocks-notice-banner-border-radius: 4px; + --wc-blocks-notice-banner-font-size: .875em; + --message-message-icon-color: #4ab866; + --info-message-icon-color: #007cba; + --error-message-icon-color: #cc1818; +} +div.wc-block-components-notice-banner { + display: flex; + align-items: stretch; + align-content: flex-start; + color: var(--wc-blocks-notice-banner-color); + padding: var(--wc-blocks-notice-banner-padding) !important; + gap: var(--wc-blocks-notice-banner-gap); + margin: var(--wc-blocks-notice-banner-padding) 0; + border-radius: var(--wc-blocks-notice-banner-border-radius); + border-color: var(--wc-blocks-notice-banner-color); + font-weight: 400; + line-height: 1.5; + border: 1px solid; + font-size: var(--wc-blocks-notice-banner-font-size); + background-color: #fff; + box-sizing: border-box; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content { + align-self: center; + white-space: normal; + flex-basis: 100%; + padding-inline-start: initial; + padding-inline-end: var(--wc-blocks-notice-banner-padding); +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content:last-child { + padding-inline-start: initial; + padding-inline-end: 0; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-block-components-notice-banner__summary { + margin: 0 0 var(--wc-blocks-notice-banner-gap-smaller); + font-weight: 600; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content ul, +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content ol { + margin: 0 0 0 var(--wc-blocks-notice-banner-gap-large); + padding: 0; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content ul li::after, +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content ol li::after { + content: ""; + clear: both; + display: block; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-forward { + color: var(--wc-blocks-notice-banner-color) !important; + background: transparent; + padding: 0 !important; + margin: 0; + border: 0; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + opacity: 0.6; + text-decoration-line: underline; + text-underline-position: under; + float: inline-end; +} +div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-forward:hover, div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-forward:focus, div.wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-forward:active { + opacity: 1; +} +div.wc-block-components-notice-banner > svg { + fill: #fff; + border-radius: 50%; + padding: 2px; + background-color: var(--wc-blocks-notice-banner-color); + flex-shrink: 0; + flex-grow: 0; +} +div.wc-block-components-notice-banner > .wc-block-components-button { + margin: 6px 0 0 auto !important; + background: transparent none !important; + box-shadow: none !important; + outline: none !important; + border: 0 !important; + padding: 0 !important; + height: 16px !important; + width: 16px !important; + min-height: auto !important; + color: var(--wc-blocks-notice-banner-color) !important; + min-width: 0 !important; + flex: 0 0 16px; + opacity: 0.6; +} +div.wc-block-components-notice-banner > .wc-block-components-button > svg { + margin: 0 !important; +} +div.wc-block-components-notice-banner > .wc-block-components-button:hover, div.wc-block-components-notice-banner > .wc-block-components-button:focus, div.wc-block-components-notice-banner > .wc-block-components-button:active { + opacity: 1; +} + +div.wc-block-components-notice-banner.is-error { + --wc-blocks-notice-banner-color: var(--error-message-text-color); + --wc-blocks-notice-banner-border-radius: var(--error-box-border-radius); + border-color: var(--wc-blocks-notice-banner-alert-red); + background-color: #fff0f0; +} +div.wc-block-components-notice-banner.is-error .wc-backward { + color: var(--error-message-normal-links-color); +} +div.wc-block-components-notice-banner.is-error .wc-backward:hover { + color: var(--error-message-hover-links-color); +} +div.wc-block-components-notice-banner.is-error > svg { + background-color: var(--error-message-icon-color); + transform: rotate(180deg); +} + +div.wc-block-components-notice-banner.is-success { + --wc-blocks-notice-banner-color: var(--message-message-text-color); + --wc-blocks-notice-banner-border-radius: var(--message-box-border-radius); + border-color: var(--wc-blocks-notice-banner-alert-green); + background-color: #f4fff7; +} +div.wc-block-components-notice-banner.is-success a:not([class]), +div.wc-block-components-notice-banner.is-success .restore-item { + color: var(--notice-message-normal-links-color); +} +div.wc-block-components-notice-banner.is-success a:not([class]):hover, +div.wc-block-components-notice-banner.is-success .restore-item:hover { + color: var(--notice-message-hover-links-color); +} +div.wc-block-components-notice-banner.is-success > svg { + background-color: var(--message-message-icon-color); +} +div.wc-block-components-notice-banner.is-success .button { + border-style: var(--message-border-type); + border-color: var(--message-border-color); + color: var(--message-buttons-normal-text-color) !important; + padding: var(--message-buttons-padding) !important; + border-radius: var(--message-buttons-border-radius); + transition-duration: var(--message-buttons-hover-transition-duration); +} +div.wc-block-components-notice-banner.is-success .button:hover { + color: var(--message-buttons-hover-text-color) !important; + border-color: var(--message-buttons-hover-border-color); +} + +div.wc-block-components-notice-banner.is-info { + --wc-blocks-notice-banner-color: var(--info-message-text-color); + --wc-blocks-notice-banner-border-radius: var(--info-box-border-radius); + border-color: #007cba; + background-color: #f4f8ff; +} +div.wc-block-components-notice-banner.is-info > svg { + background-color: var(--info-message-icon-color); +} +div.wc-block-components-notice-banner.is-info .button { + border-style: var(--info-border-type); + border-color: var(--info-border-color); + color: var(--info-buttons-normal-text-color) !important; + padding: var(--info-buttons-padding) !important; + border-radius: var(--info-buttons-border-radius); + transition-duration: var(--info-buttons-hover-transition-duration); +} +div.wc-block-components-notice-banner.is-info .button:hover { + color: var(--info-buttons-hover-text-color) !important; + border-color: var(--info-buttons-hover-border-color); +} +/*# sourceMappingURL=woocommerce-notices.css.map */ \ No newline at end of file diff --git a/assets/css/woocommerce-notices.min.css b/assets/css/woocommerce-notices.min.css new file mode 100644 index 00000000..361fe431 --- /dev/null +++ b/assets/css/woocommerce-notices.min.css @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +.elementor-editor-preview .woocommerce-notices-wrapper{padding:2em 2em .3em}.elementor-editor-preview .woocommerce-notices-wrapper.elementor-loading{opacity:.3}.e-wc-message-notice .woocommerce-message{background-color:#fafbf5;border:0 solid #000;border-radius:var(--message-box-border-radius,0);border-top:3px solid var(--message-message-icon-color,#95ac3c);color:var(--message-message-text-color,#3f444b)}.e-wc-message-notice .woocommerce-message .restore-item,.e-wc-message-notice .woocommerce-message a:not([class]){color:var(--notice-message-normal-links-color,#3f444b);font-family:Roboto;font-size:16px;font-style:normal;font-weight:400;letter-spacing:0;line-height:24px;text-decoration:underline;text-shadow:none;text-transform:none}.e-wc-message-notice .woocommerce-message .restore-item:hover,.e-wc-message-notice .woocommerce-message a:not([class]):hover{color:var(--notice-message-hover-links-color,#3f444b)}.e-wc-message-notice .woocommerce-message .button{background-color:transparent;border-color:var(--message-border-color,#95ac3c);border-radius:var(--message-buttons-border-radius,0);border-style:var(--message-border-type,solid);border-width:1px;color:var(--message-buttons-normal-text-color,#95ac3c);font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:1;padding:var(--message-buttons-padding,6px 12px);text-shadow:none;text-transform:none;transition-duration:var(--message-buttons-hover-transition-duration,.3s);transition-property:color,background,box-shadow}.e-wc-message-notice .woocommerce-message .button:hover{background-color:transparent;border-color:var(--message-buttons-hover-border-color,#95ac3c);color:var(--message-buttons-hover-text-color,#95ac3c)}.e-wc-message-notice .woocommerce-message:before{color:var(--message-message-icon-color,#95ac3c)}.e-wc-info-notice .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-info .woocommerce-Button{color:var(--info-buttons-normal-text-color,#3f84b9)}.e-wc-info-notice .woocommerce-info{background-color:#f6f9fb;border:0 solid #000;border-radius:var(--info-box-border-radius,0);border-top:3px solid var(--info-message-icon-color,#3f84b9);color:var(--info-message-text-color,#3f444b)}.e-wc-info-notice .woocommerce-info .button{background-color:transparent;border-color:var(--info-border-color,#3f84b9);border-radius:var(--info-buttons-border-radius,0);border-style:var(--info-border-type,solid);border-width:1px;color:var(--info-buttons-normal-text-color,#3f84b9);font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;letter-spacing:0;line-height:1;padding:var(--info-buttons-padding,6px 12px);text-shadow:none;text-transform:none;transition-duration:var(--info-buttons-hover-transition-duration,.3s);transition-property:color,background,box-shadow}.e-wc-info-notice .woocommerce-info .button:hover{background-color:transparent;border-color:var(--info-buttons-hover-border-color,#3f84b9);color:var(--info-buttons-hover-text-color,#3f84b9)}.e-wc-info-notice .woocommerce-info:before{color:var(--info-message-icon-color,#3f84b9)}.e-wc-error-notice .elementor-widget-woocommerce-my-account .woocommerce .woocommerce-error strong,.e-wc-error-notice .woocommerce-error{color:var(--error-message-text-color,#3f444b)}.e-wc-error-notice .woocommerce-error{background-color:#f9f2f5;border:0 solid #000;border-radius:var(--error-box-border-radius,0);border-top:3px solid var(--error-message-icon-color,#b81c23)}.e-wc-error-notice .woocommerce-error .wc-backward{color:var(--error-message-normal-links-color,#3f444b);font-family:Roboto;font-size:16px;font-style:normal;font-weight:400;letter-spacing:0;line-height:1;text-decoration:underline;text-shadow:none;text-transform:none}.e-wc-error-notice .woocommerce-error .wc-backward:hover{color:var(--error-message-hover-links-color,#3f444b)}.e-wc-error-notice .woocommerce-error:before{color:var(--error-message-icon-color,#b81c23)}div.wc-block-components-notice-banner{--wc-blocks-notice-banner-color:#2f2f2f;--wc-blocks-notice-banner-padding:16px;--wc-blocks-notice-banner-gap:12px;--wc-blocks-notice-banner-gap-smaller:8px;--wc-blocks-notice-banner-gap-large:24px;--wc-blocks-notice-banner-border-radius:4px;--wc-blocks-notice-banner-font-size:.875em;--message-message-icon-color:#4ab866;--info-message-icon-color:#007cba;--error-message-icon-color:#cc1818;align-content:flex-start;align-items:stretch;background-color:#fff;border:1px solid;border-radius:var(--wc-blocks-notice-banner-border-radius);box-sizing:border-box;color:var(--wc-blocks-notice-banner-color);display:flex;font-size:var(--wc-blocks-notice-banner-font-size);font-weight:400;gap:var(--wc-blocks-notice-banner-gap);line-height:1.5;margin:var(--wc-blocks-notice-banner-padding) 0;padding:var(--wc-blocks-notice-banner-padding)!important}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content{align-self:center;flex-basis:100%;padding-inline-end:var(--wc-blocks-notice-banner-padding);padding-inline-start:0;white-space:normal}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content:last-child{padding-inline-end:0;padding-inline-start:0}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content .wc-block-components-notice-banner__summary{font-weight:600;margin:0 0 var(--wc-blocks-notice-banner-gap-smaller)}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content ol,div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content ul{margin:0 0 0 var(--wc-blocks-notice-banner-gap-large);padding:0}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content ol li:after,div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content ul li:after{clear:both;content:"";display:block}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content .wc-forward{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--wc-blocks-notice-banner-color)!important;float:inline-end;margin:0;opacity:.6;padding:0!important;text-decoration-line:underline;text-underline-position:under}div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content .wc-forward:active,div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content .wc-forward:focus,div.wc-block-components-notice-banner>.wc-block-components-notice-banner__content .wc-forward:hover{opacity:1}div.wc-block-components-notice-banner>svg{fill:#fff;background-color:var(--wc-blocks-notice-banner-color);border-radius:50%;flex-grow:0;flex-shrink:0;padding:2px}div.wc-block-components-notice-banner>.wc-block-components-button{background:transparent none!important;border:0!important;box-shadow:none!important;color:var(--wc-blocks-notice-banner-color)!important;flex:0 0 16px;height:16px!important;margin:6px 0 0 auto!important;min-height:auto!important;min-width:0!important;opacity:.6;outline:none!important;padding:0!important;width:16px!important}div.wc-block-components-notice-banner>.wc-block-components-button>svg{margin:0!important}div.wc-block-components-notice-banner>.wc-block-components-button:active,div.wc-block-components-notice-banner>.wc-block-components-button:focus,div.wc-block-components-notice-banner>.wc-block-components-button:hover{opacity:1}div.wc-block-components-notice-banner.is-error{--wc-blocks-notice-banner-color:var(--error-message-text-color);--wc-blocks-notice-banner-border-radius:var(--error-box-border-radius);background-color:#fff0f0;border-color:var(--wc-blocks-notice-banner-alert-red)}div.wc-block-components-notice-banner.is-error .wc-backward{color:var(--error-message-normal-links-color)}div.wc-block-components-notice-banner.is-error .wc-backward:hover{color:var(--error-message-hover-links-color)}div.wc-block-components-notice-banner.is-error>svg{background-color:var(--error-message-icon-color);transform:rotate(180deg)}div.wc-block-components-notice-banner.is-success{--wc-blocks-notice-banner-color:var(--message-message-text-color);--wc-blocks-notice-banner-border-radius:var(--message-box-border-radius);background-color:#f4fff7;border-color:var(--wc-blocks-notice-banner-alert-green)}div.wc-block-components-notice-banner.is-success .restore-item,div.wc-block-components-notice-banner.is-success a:not([class]){color:var(--notice-message-normal-links-color)}div.wc-block-components-notice-banner.is-success .restore-item:hover,div.wc-block-components-notice-banner.is-success a:not([class]):hover{color:var(--notice-message-hover-links-color)}div.wc-block-components-notice-banner.is-success>svg{background-color:var(--message-message-icon-color)}div.wc-block-components-notice-banner.is-success .button{border-color:var(--message-border-color);border-radius:var(--message-buttons-border-radius);border-style:var(--message-border-type);color:var(--message-buttons-normal-text-color)!important;padding:var(--message-buttons-padding)!important;transition-duration:var(--message-buttons-hover-transition-duration)}div.wc-block-components-notice-banner.is-success .button:hover{border-color:var(--message-buttons-hover-border-color);color:var(--message-buttons-hover-text-color)!important}div.wc-block-components-notice-banner.is-info{--wc-blocks-notice-banner-color:var(--info-message-text-color);--wc-blocks-notice-banner-border-radius:var(--info-box-border-radius);background-color:#f4f8ff;border-color:#007cba}div.wc-block-components-notice-banner.is-info>svg{background-color:var(--info-message-icon-color)}div.wc-block-components-notice-banner.is-info .button{border-color:var(--info-border-color);border-radius:var(--info-buttons-border-radius);border-style:var(--info-border-type);color:var(--info-buttons-normal-text-color)!important;padding:var(--info-buttons-padding)!important;transition-duration:var(--info-buttons-hover-transition-duration)}div.wc-block-components-notice-banner.is-info .button:hover{border-color:var(--info-buttons-hover-border-color);color:var(--info-buttons-hover-text-color)!important} \ No newline at end of file diff --git a/assets/data/responsive-widgets.json b/assets/data/responsive-widgets.json new file mode 100644 index 00000000..56de3fc1 --- /dev/null +++ b/assets/data/responsive-widgets.json @@ -0,0 +1 @@ +{"animated-headline":true,"call-to-action":true,"testimonial-carousel":true,"code-highlight":true,"flip-box":true,"loop-grid":true,"mega-menu":true,"nav-menu":true,"slides":true,"video-playlist":true,"woocommerce-cart":true,"woocommerce-checkout-page":true,"woocommerce-menu-cart":true,"woocommerce-my-account":true,"woocommerce-product-add-to-cart":true,"woocommerce-products-archive":true,"woocommerce-purchase-summary":true} diff --git a/assets/images/announcements/license-expired.png b/assets/images/announcements/license-expired.png new file mode 100644 index 0000000000000000000000000000000000000000..d0d28558760ef7afb781e6f9a29da86e0dad6b42 GIT binary patch literal 15106 zcmV+dJN?9oP)+7$tuat=R0001wkB|TU|MT(w{{H{(@9+2b_wDQb=;-L*-2M6Z z|J~XA-{0SWfPmrN{R0C7_xJzy_5YZdm}qEd<>LJyARwii`5PM>{QLj-`2YL+`~Cg> z1qB7~?fy_uQ2qS>r>Cdv>i!Q84=5-o;NATZ5fOxhgzoMBFfcG8A|vzj^ZWY$+}Ql| z^z)D=H_E#W68^M zLPEvG#ZggGi;Ik@sHzne6{4b|E-o(Q;r*+ttF5iA)z#Irv$TnciEM0axVX3y5)w8x zHU|d>q@<*}y1I#e=2}`>ot>SUnwrGK#NpxLrlzK~wYGeGd~R-TaBy&-pP-G6j`;Za zhlhufl9F?Cbnff^_4V~rQ&e1BU43)X7Z(@j&(o|hJ51Q-rqGbS%G%gj)U%4QIwpUoaN=^YHDiV+x%2c zjo{$mYin!A$H!(~tZ!zylarK+ii%`hryCh9?(XkwW3;@yyuQA^mzS4eS)$_N;_>nE z$i?0+Dou22!~5lY`M13-rnYZ ze2u}s&^$P0P)df^)AMO*X|1fgCnP~;WOALGse^)zt*XXqXmvzCb1Eq>U0i9vz1rN_ z>meRE;otJx+44CxU`9kv(a+$bpSI}c^5*64cy@-hv%ykPU4?^}jESM|?)&NJ_B=a8 zy1B>l@%Q!h{FarXi;9+*m93JGrEhF}?ddkJ3Dy+qAzbfdYwWItSP?><~xs2~EZXIpRK|I^TU z=6QG~{qxUEXXcrw2m$~A0000000000000000DeV?{dNcf_&5p)nN2)A9IsMy2!pZQGeNbJ(NZ8-AoO&(!QS$4shkil5OVRQK{r)SLbyPvb)e*++ghnw2p9;h zgtJ}2HZ>rJO6?q5UQw5bNuC?O}9B6PO4ifB$+kv&aCb=+93%nQ6B$uX{vY515hb1LRI9O(S z>-LADGsrz42f@;FL{dG&05Ju@%Tm^4I@~Me6Q)eGXlA9XwM_)okC-IYA!N}5>;rB$ zL=^;!csZA^U%L_;k12gK(CW%SP#uj(-8!SaC9cO(-5~6Tz=Gh&inxyT)=QPN^5yee zOh+&s(PLuB?i{W7T>YiFUi>bIEC`C8#&>V9Z|p6;+6%S^pu zj?XBE(1Lf|n8q5{3|!F*hBh8@RacYjeW}b2W>@O8AP$|Wex{F#TI14^iKW~8H%Ucb6Hmtl+<+77HlArSa&Y9V#xEP9>MmaA7C_j6KmROT zbM0Hl+Jsru_tDPIBn0|psj4<{B;Y1U#&)b$SC^IFL#a)o)MiTN%&-px%fu4a<#$%r zCr){Oo)ZSX*`~qB12xelAYz$lSdBYV+eeAB@b7igqPS*=Jn-%ATG^%R-Oxy;mLrJr zVc-sM_?`eQux(;HR%>lhTUw{$)YVnh_Z0(tE)!x8JSLO^%lcPa&S9*^njofJBL;dt ziD;zjbjdh%IbjwTA9a7OXGorOvXgfff)5bH!qUh#s*7jVvxB(OjBK8z2_04wDOvx3 zKZZL$*D6xB-bzg^8IUwl;c5&(?DrXS8`p9QQ27UMVwzMq-KZsXI4?+VwbVYS>+Q@` zP)b?R1=M(m|F+k5IhP+XkY1=F}~Ytx+!syUU7)-V_hmW?MwQIzJvWqNSEOEk|Kp-@=E zvoU;Fo`0TpLR3IwGtH?@CDD~~Wl~k?6@F%XL-+ltC<-N|udkXwAk6yocuZB#&Ng&^ zmET?3pvhwv$+?0WTTL@{5Y@!j!rU?2{1mt;qw4GYxjKim-8o`(b7JiDwc`)ybhcjgmj z;G7724D?%hiNYqiB!iKg1P{)G2orr3%}SlU<69=?bfGN}5)es4#Z`0JtIC&DItU7g zoH=15k-Ta=qgudV^g>ub#AMXHU3OfFK4>I<_OoEM(bc)Q~tK&Or7w;$-3R@d$F>Q<^~%_>g6r zf!lqd6C?D6G-L9t_hlg7=J}aerldlaZN>$O6EfFoAfMhJe0^i+aCneU?@t7Y6EY+Q zW~-qtUzc8ow_>G~h{rdtscl}}P4W8udwvZjh6o*_O^e+^MxH;PfBgFC3nq(78z8vE zZ`I8&{M4MQs_8O$OV8&Q{`^RgTdH2FeD!?c?sporn7>q>pMO=2$;esT{kIDXcPXBu z1{o43WJYXTZ>p;UX-7W);hSF`WiXfx7gh~eNIN+GWbmJl6~*$Ko)U5Y;n?xNT(l{D zmsW_r^6}dmUV}Fv2X@5nm+@(LR(DH0ay)(UAKYfouF?sK6Eb3(Y-_%;1A7j~F8ufc z!y8(8UL-B{SPJ!*y@h3%i@xt}Jn(t?ap}XvDu0W#tLaCiB{pwAF&7Ub6GF$y!fx63Mm%yg_J_w3mEz4;CZ`?W+f)2q>`_xRdV6Wbj`73N zDn?5Ga)XN4qZ|sxd&`4({7*>xV5`5ceaF&|=~~>YID6;ocF}0 zA%x{Gz1X)i{pz>;;-}(M19@$j+xQqroRA^g{L^iX|6zBS9Xz$u`;Jx}WU3h6rSJd6435-|v0fOYSCnjqF&wo1?^BAN7^U z|M~6RCxb7(A!}(0|C;odacgfr0ptlVe+W$)}`nn?3F{?oGF9G#`oS^8!h zs1#;f3PtrHEPgMNbsLBlH&ii`?dti#oa8WH;HE zi;%dr*BJ))%aY zec69JQ_XXOPM@WQEea#kixxF5U_^9`2n1Zo$o|yUbSe_oQV$%OPrG#C$#gP82wj>` zy@8Sj*mRP8;TJ)g;b(fStE{q?)Y}r@^?eV}m=7H~o*Q)fjX4}AGGZAcTTC15PK+6W z00P2ttVk8fB+G2n_+**J*L)-#1B>C8S;0=y!T{_p=MK7QYGQl8wD%1~tx^fE7$!4d zW!?v{%*S(sPD3h)5C~d3xo9_%vA=N)2?P%#$9oH+D{7@_o#!7qu$`r~UCplzX$(tW zED3}@LX6j#mPfq;z1I4TbYkou=7eCm!KSs+AfSvK-pF1qWc0U3eXg1URWsaV#Ob|R zH{AgFrvbWDJU8gn+BStikU1C24hy*MHKqgtEy0hJ=i`yKg&-lt@l^QZt-F^Ve>Xms z3z@+!@!UdKm3Kq`_migFmdkyw_9R?6-vTKGB@!znrLxXqw~6NlofM9#1cFGiIJe=_ zyRjw^chgWm5ZyK&w~Js^YJ1>yqE|bb3n!!jw@~R(-`@GSy=iCnO7@wwK#OLyw%hlC zj3suzfeqYF^842!)X`1T2*ejD9+vb$%n1ZBC5G;@=rC~x8*(hE2?fBStGSSF4vf`# z?bNNEl??}nxrR+?WbO=P>RLhT2PkEYFr3Tfxk0DhOQ#VCa!S4kcd-S#))*5A0ylYN zTXgeToRGun)cO#CJ6Nu2dbo5U<-D7ZVU1@)=|R1}1H%T{r^o_tX`0zXYYKU8&?%*O zI)R+Ggx&^++{;)KNKzIkkw%OAXaOAW>H&I-LjEuZ#31_71LImc5Wpq;XdRALk5*wOW2v2&B?xPGsj4v^?jQHz+@THv9Z4B6r zQl1-hI#e^0K%g14c34hCt{iIuL1_iNESi?qTi}g^wP7plrLI*vH2XutBr?`y?~vY* z!@24@MXz2-l~h**&F_*-o*Q&J{oX7B(-X*KE@8MXdrnn;%w+NXL%?aQ8z!GSrB%&eAx3%<(diY%t z&kZ`|ub53BXzl23z$M}0hd`3`2-YSn4>vt*DDt<>fD0+=W)bH4Es&yQ$%d~Qas&RJ zlJepMnmxb~XkjwkW7jVo$Z66HHlF6WL8r}o<{%K4Aj?Y!#)IRBKrX3w4ErS9;s)l< zxh!t|qn}LKO@Xd4O-uBh%`e!`{ujJX_bs!uxT@orqSmH`^rmO_WDj(xbcc9u&}sXj zIS53Um!>6TToK5IBH-H<>7a=;XgBCZUvD-1)RP-JDAUu>lG+2>WRGZ~^WpdX2A!)n zP_{aZ3zNO%hP;D3H|UhPWG(`McB84&k`q%)|Kor_n*bo|{iute_K&C5ZIkZ4&1GZ4 z&LZJ~U3(w1(B=64BJ(m&+fC*RIHYiC1JZ3zE9d<{gepBaCxN6Ji5}4LWT)JP(0sk_G3bXQj5|!4ISX9G`RRDR}jdTADgrSAsFaPF(t@ zIU#E}@-8FASh}#LGxfnqG*;(bD8kx9C#|EcJU8g%I64o3tdF$N@nMk{;*LN+`w>*H zgIG!YYF|^{{$qiIi57`dxd$`ti+oVRP24fG?X5O^%PkeCc8&-Y*!J$w@)9n7I}wCx zQp`sn>%=YW(z6kc0|MPb!1wN>o&MF_9Jpx6@7Y4 z)(hkMNyntQth|Hk6g&CtL=ei$Rz`WMCpG`_v)W_22X5lRf6QCi=s35X=LVfrt@9GNz`Qg) zd&)`d2}~o5o_o5BgPPKf(@(Im@O46+RIb_pM#2MU8bV{kN=Ce~?fRP9p{#UJ+lbqT zrB(P=emfC_N^O~+z-VFLOGx%>aU2pTBP7hTY*W_I%+;^BY>bvMt}HG5QbH$|n8PW8 zM5PzMb-kdr|0}Mg_A(E2gC>4E5ri68_8bBiP%ll+HMAUi0xbkVjg?jF94nS>nMEK= z8w?j-^OGA?gHyhUmANZz49#^<^iU&ateNKqopcADL*R@-wHJ|KuI@AT1SXQC@yX5e z7k-{B)2;Y$27#=N7Q!W8-MYf^b`2}G!< zPc!!fB{lUjd1-p?r5ECeKmf5_BJS{2)=wo+O%ck!VtF-P8`7r)FCKa{b^N=}YqGPK zaL(fs^G2Qp0vAChX96s{B|PfG#uR`Z5{&g7oWG3Hs8`80Rr#;IZg;%UZrUd z6KG^;e6=cvwAhIAS85VUJA&U|4jZMlY@cZ(`i>th+W}wt>UnUG=~e9A|3e^HUN|1s z&R5R?k$2M`E0RVqT0%wS68oMNRFp4cmZ^;ZKb0jEGKHOd*2?GKtp)`ZB zkrwDk7fKsKr-P}`^3f6KVXf+YSSLb9zX zZQ36@`%G{MvF{ustm&SAB5W%X)-Uh#e%2%FXj^n8v3N=VS{?I-y~#V6oSwa5eN`R z4>-DTvv4M2gy(OVmf5OSnbpX%Ynnd+meh5wrcPmSx2!iEXgtvPoD8RE@s{GZc?H7j zCEb@+uCE8V1b&M#rILly1QGDzlAon27u`{TcYZNDYwRC9{l>aqsu8el!J^L0S79;2 z{mqTjWjIBPmut4=6$p?nDS6mzoRw2xPY@zW$X+4>L4At}?E2|!o$m7{uxLqk<6vZG zJ@|gjA7LkNWG%xZne0Hp{7mTqu% z`x#x!?WX&5;;*pVY;3j#?$ z4WXFbik5~zP+bY0SokmV>fU7+Cv0oN>S-JH)oi;b5L8xQD3==>7B4Q8PZuLlD8efy zDsz<|Obfh;<2XwaC}X8dL!h>WAL zwitoHEOK8u_mojsiTIsv#!j;ghVt3i{^$kr|2fOodyhOnZ{pw1U{@LFSDdIla_-}? zYYdhfy{Bb3MT^b%<}^74=1i{HAIrIYE$m2>xSL{F6t_cUNsNI2R(G{ut5M8*=12Fx zqw4BX|E=b!=jRO!)HL@Ci#E*{Psxo9ix<0>{7{s@tRjH9Vla29g|xu``kk1Ia1oR} z8nyF_l1DEPXc~0te}A`NVBW5e$K$H6HX&dBL%s9HS68ZYNU2I6l_c zFpoe`)|daDmcfyG+a@jW?@6DBB{0H`V^)Sl(Gn2Ihpzqho$I%LSJ(Xh3t6vrSAx^c zyOoA(*NycsIQU-OG5*C*F^*vvD}z~C3`MP_ zAh2?EleVwrFR$$=zcjWuOI4mbwB&56dRv9D3gLg2uLj`I9@$OtVt?Iykpe+Q-aOo3 zghdGamW#7Kr=P`xb^^7s59NfeFo8Tdi`smA`@pX=UrPOY0Jfw`eDZ5yxK-V*2d_6C z0IxU6Zi*LKEzBeaag=mN_5rO)#W8guX6AwnYC>4zb-3&(Hc00cmp-V>~Fc~e%RdtJ$RTW@* zDZ@lA^!91vzHV*-`k=8t;YWII!eahoddZjd4nXea&9pqR%x(*jqG+J?E& z7#ECEl-nPr7>Z^w4CPaC@wR2AC@@{W^Jwoi0M5-BFECa2cjYTGqA5kz9RsCu&MT4x zPFi2uAnGc=uo6iO1>*idDDJ`CF2Y6OEM;~1Sc-v2d#MNngMF~_uTRc@spHxE1cI{e zpKp;76)P&VZ@(u^AYAppeQDTH21E-CjSNL%k(e_X^bE%cA5G%8pCV8S;s-%%i3o%p zi1tRu!Bd%v(OCjbU7s(N9{14dFNXs*+mJ08ih6A$v0>+sGvcN> z)J;GvN}?!5mxe%XYfsPqFWS3zwiw%yE1mN%&#gHklpMVDJ=s!Wq0Fc=@e&b>pytRM z(gnifpIeg9en}9h@YZ+(!~Q@#G{Ub$+>xM@3;Fy(E=UHW1cuuoh{hkiz_D*l)nnOt z{TBa+yLCr%x*7JaIkKgxFjNUk5tXK5Rs%3^nJHc1efOmY#g{e`1TF}B`LH={37a#S z;9R&T=w~A?H$h<$hGMNKWQ9scVERk@=7zdK59Yt!o2odw^j(>eM0Df+p#ex{DCDPu zmbOm|5IAn)r%{V<|0M`4SA@Og;n8ryHZnY7b0vqlkcad5D5szFVGQnOA-f$Vr*vL3Jg7x zo(<}idSKEb8m&qXuQ^$Wz^pvnPz_5Icv-)iCiBK)1qmFh zT9KwzqB2WJP4 zuDvL0DttnSD1k}Y!~axiHHHd{Vf%r?1ZE0FOKg9bC9u51+ZYIY6ShDo5Q@kAu1Lf~ z_+3PlAp8UyL@@?J*%A}T6KnuS>-Na4HKm7e3euY11*|ae>*1argQmVhrC&ayFoBu6 zmgZ`>K!J({jUz+hA)Cz`P9);-WFo}*ot_96@!$*&VHiQvR;b`dIWq#6&lMei`fB5n z$={upIh9j6dX)1N$7E0iPXyBohz6A|wUjlt>Xh0$hYA!3+WTN&P)lorofi1`mAi5B z%9UIHWA9vJnn>3;{!)2h0_g4_-l>jBXMt``a# z%pw=1fEWR{pNz&YtR#}G$%dGP1e49ioSejD*H8Ollk??l&Lug=_j(ZbJkOMEMtpcBTmp$SGs>;B z4 zYrC6bF>mh>TLQ^sNykeF6lYJn(AE7xnb~@48$b>r-q({Ng$dQ z&$_NI`K`(&^W6ug7@FVc9owggO3ZlhA^IzpvpUj`F`O;c=!nb(N zx?5Uusiq=7VQ^vPzwgou!y^z|l5BW}A02_K4!XuAi9x(V+R4XpYVB;VDR|lKtdZXK z{QJXKMPU($`tqU~>UhKof!4u50-X!Y1d1GV8!9n$heOF#Effqew_cfCE=o|;l!igz z%==oE?CMMNnZWPUvjPazj58CsCztNbPEZgrMvd0hz8qoWqAXV1Gn%*(sI32R|L2-x zoWRVM%K-$o-exAS)KLgXDM3QW81z-QeeXQmH!lyj6qz^?7?2lDq^V+=z_K4f6@Bib z|9^)a@Eia#Yg;qlNR7HOkn#o z_|YK(=r44}SiT#-Cfkiey2MAcN+!EU!{CT+9T zrP%tzeDp+4)71cPYyc>vi`lu#_b?G?xPKQ&m4G5~0)-4lQj-&o^{miu!-8ys6wA<< zCD59?2r8?51UgDUiXxTK7e1x?x0^naUWt$h#3rJ;p?#VZ@=d{Nbl}W=9{3%NNj%zD zE_|=-x*<&_BY`f(I~>92jC0BplM+L4A}5pF7^-b#@V-g50xV_;1cjeI?0QdN;@)7* zgZ&9StMybpQQD*u?}tXAI~>7(Mx)?F2pb&S@XYncE`eaOLH(Y+Fg051A%jjp@)T%^T*z}`MeER_&mf6M}jiMT`+J;%4Z zCSj;mNuM8%MFO+b4*;0*5vT{?TZf2|z!!Bh1cl)krNqSIjeLCxh^k3(A^3%3jQxYD zB{CKXTer}j47;$}-9rQ%3FE4sqzGSgT z;8+Sqz@pmyJ?UXDogR2|7=(z%EL6-PHWb4!w?#0+`7cV^qsZH0gG1NoKrPKN7>xm7 zGGsE5KYm5 zu!q5zbd>b8C(yvmus;8Wj!?^TKVmP<7D+sKZMlEE#CntfJ zftW;7df(<8r@l$}l4^GoST;tQRmCb?Qkp-m{n*U=v{xF8h0&2Gu+m5(5;@+ZJPFL(>2a1 zjplKoZ?m}CN#{gM{o;U-z^J*y9UgbMznI%Fd_Tr3O5*9&PQ(rPGBE?dKZy z_x4-jJ%Qild|}iH%j*t~I~PYgpD@=M1FH?zftaUX~8H}jpq z^Vv^NO@=@G>!z#ao>XcK5*SToc3ol4i{91_2hW%05rHnD{90m4Wq5-t8wSSo!aN8_ z^fj(Y4(||7a68N=E8I%wMBA%1Q!6G8mUuGd^KaV)@&xzT?DLS1=<7!AU&9-S1wB8^ zCjy`KxTb~&?cQd``K@Jb&%SuRe)H0m71y%WU@|>PNl7u8E?Ya#uUxsENF-RE7M}=oRs(Q^0wTlN>v!VXXN`^j(K?2N+bF$U zr`C7Rw#PYd4;Z{trs?E7(d! z`9z?hb{`T@54(Vy&vj=O(y{JCD?K{-WX?(_*`}tf=f`mj{J$HQnvCA%(fm4%+t#N5y?F-vSZ2@y2 zR=_FWxksT(cYDc0x>n5#D?BzFJuOVrUq!bnhH4$T+3AB$D;GQ5&tn4nu2abYFU)Xh zPzD6{){1)?O;4l34Wj<`Bt#`jdOi$5`^ZU^vg;2W)4RUnUD*z&+?&62rd;CSYnst~ONyd3gU{NZt%x&`C z*^kbW`)|rs<|u@X`yegR(3MXns~ZagUfNTm`YV?FWbMrhk3< z+;h)4_y2%hfSyswO}-e~y_)>PZ1bK|3_P}`KEB<~QhWFQb#(^b3I!{o0)cdNBJ+HX z0wd3t>&Gy1aOU=n*cB=G$A=tcV9LTJ#ty$>rUNBNI%)wMpl3rX82~@>gt>P3&~tV~ ze>Vy5<=_+pi#mwUe`Mt#eDlNKt}NYYIi76l?d}XNnGwYU$}DcF>6yOIQ|6k{?>=wO zqWi;T{l%d<$((4DqYOMy5ug9bN<#Qc9>EE_Xy&^n8?aIrDFvXDr_A+2Ztp*Dm)dMR zexZr{1!3ZnJqYL(0e@D+QfxdNCbhgUeh#7($Vqmi}?Lq#DcALNa z=hdZ`a;~DJubym;AXLYb=6W$WdC@x>$;}sA*~8$2^R0Qc4>OuL!@y*XgkHKyI|cuo zM{fT7TF&YiOg3=Lu*7rbda+o0(cXGEyED>d4EZmfrM>G;Uy;PijVpVlpGa#kDlY50 z+gEo7LV;ZMKh;CMh0*C6F;ALn#pH!a-MzvrB^b0=f4TJcDyn9RxN&8hx`y=PU&-+3 zZ~v4>nBUr`oYhJ*+2{@GF#%7S>vhLmy!*tN`C_%gf0ZAUcsjbdacP>2=j0)o*LNeI z8ez8i96L}*szfzthYp0bJZlPw+A7+dm$!wk7|;KzU1j3Lxp%xyFa4b`1i!nTPl+Zt zr)EbtAnVQU5`Mw=Fi(pDq69vqTB+*FqX8}JHJnfrtg88A}err z1$DbNOi-j!Lk4N>7~H`@gPNyCpC&dZp~mV>Mi@kx;AYPUPfz&f#} zp3)9MF#FL{SkmC%?Yt7WN+=sfn z|0HjLx_hvMUJUa>j#yyHVGpwHX zNNye8%}7oZMr88cj0#`vZ}%T1KWy!2%(>jOr=K3V(N3C#4y28;5W^}=N+?CY0h+8j zN%H*QFdTiXM#)TKP-(L%?jLu!Tn9y?iNoXKXth+ZzPR{aCX*Qfjwz(+@6HKZ{gaLc z(_C|s%usg;(+)pBHLpnIZVjy!9fm;6n!#W2_nEs$0G2V;4!dz(U?kU_lni?Suw{p+o`#2>rV6V|NLlCSBY56xXXHlnrQ_3D3pi+Tg9UiaOYF++0Jo5U9 zW4Nhv!X!ac+_a;o!1O{8^-n)7uHJaRW}8AEgP1!;)w7!gPO_b*=lC)yT$zhA0CY(` ztUETVUdZ`-%~2TH>?}?I@usP0PkN&Dn)}C8It&jfg?2lFLV7`~V3@;bSwswj12a zUX@2yl48-Vx~{G{iA2(EGWDh!$x+uBQ_*H)Ge{Q&Eo#rv$zj zJ=K?5(?-8}cUKW)ZzXE?^41_1(Tua`kJ(Z%_mm_mAt)H@s~}fOT8X^r(s*?%P&zBf zEM(u{>7(^gh_n_xgRxP*+Bx?icRy#5{(Z~~T^*14VW6UW9gnC0RY=mIkv`~GXugck zX-*B?A8S@WE@@QNjVc5GD&`)%%j_L{$g;~=wh@570R3K#BUHM&NiQReMfK!66anqS zwBgt++$a1vpAGgq+CHmov?~+U0>dWfmBV_%Oq{9k;QuZw4 z$tgY515mTicS*Q|vb*dZyBzZ~mK6Xxv}*upo8yW19vlIlPhl5r8j{YM6#PnKahVfW z8XMox#f&4bJqXYp^Lmgg*kh4_B`EWb_z8#+!yM&SFhf(TIsP;NH{QyJ6f-@z|#1ABL3B^5C-_d`|M*?#^S*{8mU%3USHOdpQx4$ zTQFSEncn=RA+c=KRiVbk#BOK0(<3(}oT$b8Xm|zMnMV=xINvE@8HPO;58h8#+H`Lkn`?T*h9a2f%dvw9%HA5$RwAwIfhk1wsEg+UJ2+%DTh83ZSoDsR zspQb>wsyA#sI>b*$^DYrwqM&j|JSsxD1e`c1_vtpAtFpfP#M86iGk`%e9tOM4S~$o zOtDJEm{Lv5QjwUbF{E3XxJ5P^DK9ZU6^g&CgH%{ySeQSo5c*&3-j{EUu=U02EarTE z5Z-&fFZvGW+;i?Z=SIxmIHYn-yon>ieqiitf1jDo`-b=|pLAzsD0_Eq%)Am|zS#7< zI4IIusmbzfw8l4#^hw)}ks-0h)z^*HyOg1)yFRIAD(2ih)J_p0w3e~9^F|SGbAZ|D z$UBjzN?hG~h?+OIRvo`5O<2vea@4<9#~1T?(Zk_UwJjLw6Q8Uo`K`N;GRx*HTN#rO zWlRh;4EWwZ4>ZMZNi&8IuYI zp1I%$$pTBJ@X_c}N8z$_iK?>zdE#d(X~tAe1#l~R-_)t!nb%|JZqV7hQq0Tibu0eo z?rXOF<;ZB>qc?zYo?MHW0dTtjezaGho{|Ar_JN6a=rK5O;jY0~fmav%u<2SLOOIVg z^BhOXXo^S+acStNO)1!PR!ekZgQG_b3gDz2NfQ6N4L#L?r@U}Q>7;1jgwvNqp8Zw{ z@Ux_{9ph*=a zZyvsMMWS99{g#N2gN7AXO|46Z`0WHZ=TdTcAy)o7_cHwNQxOL4<*X#BE#^*FwLg6~q^2Am zl;^kh-3~fsyCHlh<0=<;{DYB?uzQ+vP|Sktd6tYHi9<5M2oXGqpc=i_Ff{KG**qp% zFUjx<_UHLYv&KGY9m^DBF~3A2@wp{#-{PVqQVb?iHr>>;d}Z-n@L%OXMa$^*g)}#IPF#A4e%3EvTqv#-NaS$_oaRU51emcw7L{KR{^~3NB@WcTsu|fe9$R z065A)z$7Tiu<*HzlW@oF+tSqZ(#j&4%&Dh zKutTm9^=3d>55qBn5&!@I07*qoM6N<$f(UL-FaQ7m literal 0 HcmV?d00001 diff --git a/assets/images/logo-placeholder.png b/assets/images/logo-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..5b15044d821cbc08467640d0d666af6e0c6b0d94 GIT binary patch literal 4059 zcmd5<`8U*$_a0-$3}YEv)_66>l4WcmOUz&_S>GbcmZg%N?1UM~NW<9kw#$~CC?s1G zBa}6JWnV%yO-V&x=ldso&-s4N=cnh~=bm%VdG2%0J@-krwlwBo6J`T}KpdtfhBhD& zGXMfHIl-Av7}&V%&|1h9~-mC;TFa&-!Q)#0NxjPW{vF;5$h#21avBYs%_c z$+;yN1r-HVjdw`tEze&jW#m^kcRVbu$t|mSkXyo+RvCCQiYdg#@=~|2p3xo%#C6fs z5N8`PzdOmq1X6X2v^yi zROSEyNKiBA_`>SPSzY$}q@pS)^D%qykIXaX|4$+?+Toq~=h+k895z!lx;)Pw#5G=e zxDCH}UfD%Vx&mgKQze^#BL`%%E)~5t7jFDl8a3euHa)dIMH&oc^(;=g z77|U8m$a)%roDspPvyx?1fnUYNA&li^}e5yk%Mr6=j6Q~FI%E`Xhojmy@%_~GUxJH z2nFNu-_M<5^&AxPql$}Y+rw7C^Mbo|7=jL)*Y&Whw~zGw0DqQp3XF%wT$$FLD5w+# zQyKM=9>bz3(dOcJ5P9-~h0H;06#Xz0fD1K0kwtJVJ7UfYl6+qG8BO{8#!JB_6=d`o zivkjNGqBxXy%eWM_rz&JdmP^?Iw8T2CUL!@Z|$yyaC#cR!mTvv2D(X@HmRaw;7XJY14%C=WH-#PaOZl-E)r!DgibpGeDnTf(%L zEN1Fg4$u^ln+)FM(%vmm6Rch`3qaVlT7P^c&c^SDh?rv2%+M1*J{mFRqU&sKQGQP` zgf0oBSq_ZrNp1hS9Tj#{-T$xjbA=ifLiKJ+(Xo~KT&5M{w<*A7aK)`O`ciew-Jgp( zx}r;tC(G#$Y+()f22aNxv(l7AqRu_8F(w)1Oz)97LkVkl=*eP!I~HPRc;Kq42h~Re z_DXl9y3#vFb`W>j)Ok$TpoAg#Q10U_>_TRsZ-sL+z3Tm>lNjy3M^VvXM2ay9LeH() zmS{u{a&7#Mcr#i-Ft@wo$?v}XEEC%hvscS2o)~^9a|Sl}xF4(k#)9yqyKiQjhnC$C zyK0?VKSA;k`I^&@wHI2AeOF`Jb?~R-8`KcSwX0->siTLK5*cnNzbhP4JlxI zdP{D{{+1h1IW+2;);*YkJ#Gqb@bP=8Bp8bx4qMq6>)-!-RpTR}Uc}=1x|zt$s5oZt zYFEb`uESSQn+MzM3K(V<wa+9Zgun=0n={yjO^P;w8 zH~U{XWY2q)4-vA)%i|lz7%2hH$ep0j*EaU!$&~IHG)-t`?;uI{;XZMU%QpL2)Q%hl z@0AH~+jU6DCcP)G69Mf>YmE;ACP#w+>9vKz`WWI22Hv8|5vss{X?@8EX;UT}eC`24 zpIfj_2q!2_i`g63mYj!w8S}4eiMDaKkJV} znM~$4J0S(A(2it;K8Az{77@66Qm?6F;JBF)k~6ZnJYeJ)@>TX77(;uc$V(rG~< z?eO0-P)ukC%Drc_EZd-~+gCor2yH&occ>@6BS)+4h0OdM4+$h+Zpe%rL^p(c7q`@3&PN}C8Q?Pqu#2N zh-iP4QV<(>XC&k`LMbHTV&$d_lo7(%>;2&|ErC^Beu&(&lhrN7Fo`rJx)`E-BCk`QzpIAqN|LteGS+`AS{{**)k z2CT#Lan~~eSd}2U_Xjp-F2Ow_PowCR&Or1Bm^)dS%yKkz({XY$tbXudPL<3|bf1fsVqHyu# zbBwF;V}=R2krg5#>3c+mk66^H200~pa%jr}ha;Iyg&}vAAu#?v(>2&aWEy%|YR5Dp z5h&bAhzs~ZV?!O?&=eSnK5Zb(ZDIp}s)^QxV)`h)Q=R-6-S_sbA;Q+EYT z&LfA5dIgDXe4VCm?b3%G*CwfIv|qDypsf|4>h9;06v<0KQ@{jrbrGFu) z^VnuV=lMP{hFc}Ts014IjwpcsdSfl{h~l^ZI~1oo*HT*K#qFl>lWCU<;*;!2?ikXJ zai-`!6ikjiE#J)91&ByROn&%qD_=7QL5J!LO<3tkeCkEC zJ8mA5hybrWCVmt#<18=beUB`~Z;W)^s`^L-Mb-d;26S^R2ANM0UO_(kq6w!+BlK}i zv0i7pPTL5H7TdaX-A`PZBU&TN#iLvzRPXNpL$8dr-uwi}6k*_RkdME5m>JyNR~dea zPp0|3@7p5A7(5KLz^5%y*pZNF1!`({-+}w`ECG1<=FikPxVMSe;dY^b@=1Kg>uGC& zS6Vyp;nLlibYqpkp&WuN4#E_I&>Xk;B?UXVLM%SNCk1KolH++=VAd9`Q7uJsUf~y% zVyl@GC7-X4Lp-XpR4bhsPK@v}ZKV}B#=K2MwDhJlff;x&{EoRHo4dH?x8bEE%pW5U z4UZ1M3_?bIsXh0y_hMxpsfj2rQ#R(2H&G;xp`F&}b}$>~wd7AO(5E+_mlBq>*ihASD#Jz+gol*r3i=PeJ+vRglg{D%DXG6i3(T@)pW;=D_Wd?u<^@b=t zYb`A+N9%`j!RC()e0NqWdtA?A@P?+>w~F6K;yNx2$$R$H^MhVpWGhIE)t`Ef0N#N9 z+lLCwp)2IMw0uh(@E2O#llh&1{o_O3oOKj{Q+sxT6>E7RE3UyExznuRpvHs$MP;cl zw?}KYWm|b6?jvY5-wA{dV-iVHn;DI^%6uDn$puL|`z^CDva@zFNb97KRQ6jE3*xR? z4e0`qW;>Y%#df!YwCL|Rz{;MBor*yi7ucyz91uoDg@5u#d2kmsS>k~lH1{0Ei#g5;t z_v&lFsU-Otm31edqweKge%c|NdcW3p(Ac3$0x40pyZX(9$qG&-st>8xjeSVK`c~5u zVe&q3YP`!EWk}aOtUSroQW@Gs!pd*0r9w%X5cgg*is8mf5FC^G)pY-)pRD@;h2&i^ z6j$daaqI!G*Nh-`aPw-yXFYioQgs8JB$FGTaH4)t=Z3(mBto*>?Q8?ItBEIT!1UmMd WgwB!D{DhN;4Kl@B8aC)(BmNK08|It< literal 0 HcmV?d00001 diff --git a/assets/js/0726b2d81686a5392236.bundle.min.js b/assets/js/0726b2d81686a5392236.bundle.min.js new file mode 100644 index 00000000..e4938535 --- /dev/null +++ b/assets/js/0726b2d81686a5392236.bundle.min.js @@ -0,0 +1,3 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/*! For license information please see 0726b2d81686a5392236.bundle.min.js.LICENSE.txt */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[786],{4786:e=>{const{entries:t,setPrototypeOf:n,isFrozen:o,getPrototypeOf:a,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:l,create:c}=Object,{apply:s,construct:u}="undefined"!=typeof Reflect&&Reflect;i||(i=function freeze(e){return e}),l||(l=function seal(e){return e}),s||(s=function apply(e,t,n){return e.apply(t,n)}),u||(u=function construct(e,t){return new e(...t)});const p=unapply(Array.prototype.forEach),d=unapply(Array.prototype.lastIndexOf),m=unapply(Array.prototype.pop),f=unapply(Array.prototype.push),h=unapply(Array.prototype.splice),T=unapply(String.prototype.toLowerCase),g=unapply(String.prototype.toString),y=unapply(String.prototype.match),S=unapply(String.prototype.replace),_=unapply(String.prototype.indexOf),E=unapply(String.prototype.trim),A=unapply(Object.prototype.hasOwnProperty),b=unapply(RegExp.prototype.test),N=function unconstruct(e){return function(){for(var t=arguments.length,n=new Array(t),o=0;o1?n-1:0),a=1;a2&&void 0!==arguments[2]?arguments[2]:T;n&&n(e,null);let r=t.length;for(;r--;){let n=t[r];if("string"==typeof n){const e=a(n);e!==n&&(o(t)||(t[r]=e),n=e)}e[n]=!0}return e}function cleanArray(e){for(let t=0;t/gm),U=l(/\$\{[\w\W]*/gm),H=l(/^data-[\-\w.\u00B7-\uFFFF]+$/),F=l(/^aria-[\-\w]+$/),G=l(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),B=l(/^(?:\w+script|data):/i),W=l(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Y=l(/^html$/i),j=l(/^[a-z][.\w]*(-[.\w]+)+$/i);var X=Object.freeze({__proto__:null,ARIA_ATTR:F,ATTR_WHITESPACE:W,CUSTOM_ELEMENT:j,DATA_ATTR:H,DOCTYPE_NAME:Y,ERB_EXPR:P,IS_ALLOWED_URI:G,IS_SCRIPT_OR_DATA:B,MUSTACHE_EXPR:z,TMPLIT_EXPR:U});const q=1,V=3,$=7,K=8,Z=9,J=function getGlobal(){return"undefined"==typeof window?null:window};var Q=function createDOMPurify(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:J();const DOMPurify=e=>createDOMPurify(e);if(DOMPurify.version="3.2.6",DOMPurify.removed=[],!e||!e.document||e.document.nodeType!==Z||!e.Element)return DOMPurify.isSupported=!1,DOMPurify;let{document:n}=e;const o=n,a=o.currentScript,{DocumentFragment:r,HTMLTemplateElement:l,Node:s,Element:u,NodeFilter:z,NamedNodeMap:P=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:U,DOMParser:H,trustedTypes:F}=e,B=u.prototype,W=lookupGetter(B,"cloneNode"),j=lookupGetter(B,"remove"),Q=lookupGetter(B,"nextSibling"),ee=lookupGetter(B,"childNodes"),te=lookupGetter(B,"parentNode");if("function"==typeof l){const e=n.createElement("template");e.content&&e.content.ownerDocument&&(n=e.content.ownerDocument)}let ne,oe="";const{implementation:ae,createNodeIterator:re,createDocumentFragment:ie,getElementsByTagName:le}=n,{importNode:ce}=o;let se={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};DOMPurify.isSupported="function"==typeof t&&"function"==typeof te&&ae&&void 0!==ae.createHTMLDocument;const{MUSTACHE_EXPR:ue,ERB_EXPR:pe,TMPLIT_EXPR:de,DATA_ATTR:me,ARIA_ATTR:fe,IS_SCRIPT_OR_DATA:he,ATTR_WHITESPACE:Te,CUSTOM_ELEMENT:ge}=X;let{IS_ALLOWED_URI:ye}=X,Se=null;const _e=addToSet({},[...w,...R,...k,...O,...C]);let Ee=null;const Ae=addToSet({},[...v,...L,...M,...I]);let be=Object.seal(c(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Ne=null,we=null,Re=!0,ke=!0,xe=!1,Oe=!0,De=!1,Ce=!0,ve=!1,Le=!1,Me=!1,Ie=!1,ze=!1,Pe=!1,Ue=!0,He=!1,Fe=!0,Ge=!1,Be={},We=null;const Ye=addToSet({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let je=null;const Xe=addToSet({},["audio","video","img","source","image","track"]);let qe=null;const Ve=addToSet({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),$e="http://www.w3.org/1998/Math/MathML",Ke="http://www.w3.org/2000/svg",Ze="http://www.w3.org/1999/xhtml";let Je=Ze,Qe=!1,et=null;const tt=addToSet({},[$e,Ke,Ze],g);let nt=addToSet({},["mi","mo","mn","ms","mtext"]),ot=addToSet({},["annotation-xml"]);const at=addToSet({},["title","style","font","a","script"]);let rt=null;const it=["application/xhtml+xml","text/html"];let lt=null,ct=null;const st=n.createElement("form"),ut=function isRegexOrFunction(e){return e instanceof RegExp||e instanceof Function},pt=function _parseConfig(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ct||ct!==e){if(e&&"object"==typeof e||(e={}),e=clone(e),rt=-1===it.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,lt="application/xhtml+xml"===rt?g:T,Se=A(e,"ALLOWED_TAGS")?addToSet({},e.ALLOWED_TAGS,lt):_e,Ee=A(e,"ALLOWED_ATTR")?addToSet({},e.ALLOWED_ATTR,lt):Ae,et=A(e,"ALLOWED_NAMESPACES")?addToSet({},e.ALLOWED_NAMESPACES,g):tt,qe=A(e,"ADD_URI_SAFE_ATTR")?addToSet(clone(Ve),e.ADD_URI_SAFE_ATTR,lt):Ve,je=A(e,"ADD_DATA_URI_TAGS")?addToSet(clone(Xe),e.ADD_DATA_URI_TAGS,lt):Xe,We=A(e,"FORBID_CONTENTS")?addToSet({},e.FORBID_CONTENTS,lt):Ye,Ne=A(e,"FORBID_TAGS")?addToSet({},e.FORBID_TAGS,lt):clone({}),we=A(e,"FORBID_ATTR")?addToSet({},e.FORBID_ATTR,lt):clone({}),Be=!!A(e,"USE_PROFILES")&&e.USE_PROFILES,Re=!1!==e.ALLOW_ARIA_ATTR,ke=!1!==e.ALLOW_DATA_ATTR,xe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Oe=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,De=e.SAFE_FOR_TEMPLATES||!1,Ce=!1!==e.SAFE_FOR_XML,ve=e.WHOLE_DOCUMENT||!1,Ie=e.RETURN_DOM||!1,ze=e.RETURN_DOM_FRAGMENT||!1,Pe=e.RETURN_TRUSTED_TYPE||!1,Me=e.FORCE_BODY||!1,Ue=!1!==e.SANITIZE_DOM,He=e.SANITIZE_NAMED_PROPS||!1,Fe=!1!==e.KEEP_CONTENT,Ge=e.IN_PLACE||!1,ye=e.ALLOWED_URI_REGEXP||G,Je=e.NAMESPACE||Ze,nt=e.MATHML_TEXT_INTEGRATION_POINTS||nt,ot=e.HTML_INTEGRATION_POINTS||ot,be=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(be.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(be.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(be.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),De&&(ke=!1),ze&&(Ie=!0),Be&&(Se=addToSet({},C),Ee=[],!0===Be.html&&(addToSet(Se,w),addToSet(Ee,v)),!0===Be.svg&&(addToSet(Se,R),addToSet(Ee,L),addToSet(Ee,I)),!0===Be.svgFilters&&(addToSet(Se,k),addToSet(Ee,L),addToSet(Ee,I)),!0===Be.mathMl&&(addToSet(Se,O),addToSet(Ee,M),addToSet(Ee,I))),e.ADD_TAGS&&(Se===_e&&(Se=clone(Se)),addToSet(Se,e.ADD_TAGS,lt)),e.ADD_ATTR&&(Ee===Ae&&(Ee=clone(Ee)),addToSet(Ee,e.ADD_ATTR,lt)),e.ADD_URI_SAFE_ATTR&&addToSet(qe,e.ADD_URI_SAFE_ATTR,lt),e.FORBID_CONTENTS&&(We===Ye&&(We=clone(We)),addToSet(We,e.FORBID_CONTENTS,lt)),Fe&&(Se["#text"]=!0),ve&&addToSet(Se,["html","head","body"]),Se.table&&(addToSet(Se,["tbody"]),delete Ne.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw N('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw N('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');ne=e.TRUSTED_TYPES_POLICY,oe=ne.createHTML("")}else void 0===ne&&(ne=function _createTrustedTypesPolicy(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+a+" could not be created."),null}}(F,a)),null!==ne&&"string"==typeof oe&&(oe=ne.createHTML(""));i&&i(e),ct=e}},dt=addToSet({},[...R,...k,...x]),mt=addToSet({},[...O,...D]),ft=function _forceRemove(e){f(DOMPurify.removed,{element:e});try{te(e).removeChild(e)}catch(t){j(e)}},ht=function _removeAttribute(e,t){try{f(DOMPurify.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(DOMPurify.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e)if(Ie||ze)try{ft(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},Tt=function _initDocument(e){let t=null,o=null;if(Me)e=""+e;else{const t=y(e,/^[\r\n\t ]+/);o=t&&t[0]}"application/xhtml+xml"===rt&&Je===Ze&&(e=''+e+"");const a=ne?ne.createHTML(e):e;if(Je===Ze)try{t=(new H).parseFromString(a,rt)}catch(e){}if(!t||!t.documentElement){t=ae.createDocument(Je,"template",null);try{t.documentElement.innerHTML=Qe?oe:a}catch(e){}}const r=t.body||t.documentElement;return e&&o&&r.insertBefore(n.createTextNode(o),r.childNodes[0]||null),Je===Ze?le.call(t,ve?"html":"body")[0]:ve?t.documentElement:r},gt=function _createNodeIterator(e){return re.call(e.ownerDocument||e,e,z.SHOW_ELEMENT|z.SHOW_COMMENT|z.SHOW_TEXT|z.SHOW_PROCESSING_INSTRUCTION|z.SHOW_CDATA_SECTION,null)},yt=function _isClobbered(e){return e instanceof U&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof P)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},St=function _isNode(e){return"function"==typeof s&&e instanceof s};function _executeHooks(e,t,n){p(e,(e=>{e.call(DOMPurify,t,n,ct)}))}const _t=function _sanitizeElements(e){let t=null;if(_executeHooks(se.beforeSanitizeElements,e,null),yt(e))return ft(e),!0;const n=lt(e.nodeName);if(_executeHooks(se.uponSanitizeElement,e,{tagName:n,allowedTags:Se}),Ce&&e.hasChildNodes()&&!St(e.firstElementChild)&&b(/<[/\w!]/g,e.innerHTML)&&b(/<[/\w!]/g,e.textContent))return ft(e),!0;if(e.nodeType===$)return ft(e),!0;if(Ce&&e.nodeType===K&&b(/<[/\w]/g,e.data))return ft(e),!0;if(!Se[n]||Ne[n]){if(!Ne[n]&&At(n)){if(be.tagNameCheck instanceof RegExp&&b(be.tagNameCheck,n))return!1;if(be.tagNameCheck instanceof Function&&be.tagNameCheck(n))return!1}if(Fe&&!We[n]){const t=te(e)||e.parentNode,n=ee(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o){const a=W(n[o],!0);a.__removalCount=(e.__removalCount||0)+1,t.insertBefore(a,Q(e))}}}return ft(e),!0}return e instanceof u&&!function _checkValidNamespace(e){let t=te(e);t&&t.tagName||(t={namespaceURI:Je,tagName:"template"});const n=T(e.tagName),o=T(t.tagName);return!!et[e.namespaceURI]&&(e.namespaceURI===Ke?t.namespaceURI===Ze?"svg"===n:t.namespaceURI===$e?"svg"===n&&("annotation-xml"===o||nt[o]):Boolean(dt[n]):e.namespaceURI===$e?t.namespaceURI===Ze?"math"===n:t.namespaceURI===Ke?"math"===n&&ot[o]:Boolean(mt[n]):e.namespaceURI===Ze?!(t.namespaceURI===Ke&&!ot[o])&&!(t.namespaceURI===$e&&!nt[o])&&!mt[n]&&(at[n]||!dt[n]):!("application/xhtml+xml"!==rt||!et[e.namespaceURI]))}(e)?(ft(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!b(/<\/no(script|embed|frames)/i,e.innerHTML)?(De&&e.nodeType===V&&(t=e.textContent,p([ue,pe,de],(e=>{t=S(t,e," ")})),e.textContent!==t&&(f(DOMPurify.removed,{element:e.cloneNode()}),e.textContent=t)),_executeHooks(se.afterSanitizeElements,e,null),!1):(ft(e),!0)},Et=function _isValidAttribute(e,t,o){if(Ue&&("id"===t||"name"===t)&&(o in n||o in st))return!1;if(ke&&!we[t]&&b(me,t));else if(Re&&b(fe,t));else if(!Ee[t]||we[t]){if(!(At(e)&&(be.tagNameCheck instanceof RegExp&&b(be.tagNameCheck,e)||be.tagNameCheck instanceof Function&&be.tagNameCheck(e))&&(be.attributeNameCheck instanceof RegExp&&b(be.attributeNameCheck,t)||be.attributeNameCheck instanceof Function&&be.attributeNameCheck(t))||"is"===t&&be.allowCustomizedBuiltInElements&&(be.tagNameCheck instanceof RegExp&&b(be.tagNameCheck,o)||be.tagNameCheck instanceof Function&&be.tagNameCheck(o))))return!1}else if(qe[t]);else if(b(ye,S(o,Te,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==_(o,"data:")||!je[e]){if(xe&&!b(he,S(o,Te,"")));else if(o)return!1}else;return!0},At=function _isBasicCustomElement(e){return"annotation-xml"!==e&&y(e,ge)},bt=function _sanitizeAttributes(e){_executeHooks(se.beforeSanitizeAttributes,e,null);const{attributes:t}=e;if(!t||yt(e))return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ee,forceKeepAttr:void 0};let o=t.length;for(;o--;){const a=t[o],{name:r,namespaceURI:i,value:l}=a,c=lt(r),s=l;let u="value"===r?s:E(s);if(n.attrName=c,n.attrValue=u,n.keepAttr=!0,n.forceKeepAttr=void 0,_executeHooks(se.uponSanitizeAttribute,e,n),u=n.attrValue,!He||"id"!==c&&"name"!==c||(ht(r,e),u="user-content-"+u),Ce&&b(/((--!?|])>)|<\/(style|title)/i,u)){ht(r,e);continue}if(n.forceKeepAttr)continue;if(!n.keepAttr){ht(r,e);continue}if(!Oe&&b(/\/>/i,u)){ht(r,e);continue}De&&p([ue,pe,de],(e=>{u=S(u,e," ")}));const d=lt(e.nodeName);if(Et(d,c,u)){if(ne&&"object"==typeof F&&"function"==typeof F.getAttributeType)if(i);else switch(F.getAttributeType(d,c)){case"TrustedHTML":u=ne.createHTML(u);break;case"TrustedScriptURL":u=ne.createScriptURL(u)}if(u!==s)try{i?e.setAttributeNS(i,r,u):e.setAttribute(r,u),yt(e)?ft(e):m(DOMPurify.removed)}catch(t){ht(r,e)}}else ht(r,e)}_executeHooks(se.afterSanitizeAttributes,e,null)},Nt=function _sanitizeShadowDOM(e){let t=null;const n=gt(e);for(_executeHooks(se.beforeSanitizeShadowDOM,e,null);t=n.nextNode();)_executeHooks(se.uponSanitizeShadowNode,t,null),_t(t),bt(t),t.content instanceof r&&_sanitizeShadowDOM(t.content);_executeHooks(se.afterSanitizeShadowDOM,e,null)};return DOMPurify.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,a=null,i=null,l=null;if(Qe=!e,Qe&&(e="\x3c!--\x3e"),"string"!=typeof e&&!St(e)){if("function"!=typeof e.toString)throw N("toString is not a function");if("string"!=typeof(e=e.toString()))throw N("dirty is not a string, aborting")}if(!DOMPurify.isSupported)return e;if(Le||pt(t),DOMPurify.removed=[],"string"==typeof e&&(Ge=!1),Ge){if(e.nodeName){const t=lt(e.nodeName);if(!Se[t]||Ne[t])throw N("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof s)n=Tt("\x3c!----\x3e"),a=n.ownerDocument.importNode(e,!0),a.nodeType===q&&"BODY"===a.nodeName||"HTML"===a.nodeName?n=a:n.appendChild(a);else{if(!Ie&&!De&&!ve&&-1===e.indexOf("<"))return ne&&Pe?ne.createHTML(e):e;if(n=Tt(e),!n)return Ie?null:Pe?oe:""}n&&Me&&ft(n.firstChild);const c=gt(Ge?e:n);for(;i=c.nextNode();)_t(i),bt(i),i.content instanceof r&&Nt(i.content);if(Ge)return e;if(Ie){if(ze)for(l=ie.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(Ee.shadowroot||Ee.shadowrootmode)&&(l=ce.call(o,l,!0)),l}let u=ve?n.outerHTML:n.innerHTML;return ve&&Se["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&b(Y,n.ownerDocument.doctype.name)&&(u="\n"+u),De&&p([ue,pe,de],(e=>{u=S(u,e," ")})),ne&&Pe?ne.createHTML(u):u},DOMPurify.setConfig=function(){pt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Le=!0},DOMPurify.clearConfig=function(){ct=null,Le=!1},DOMPurify.isValidAttribute=function(e,t,n){ct||pt({});const o=lt(e),a=lt(t);return Et(o,a,n)},DOMPurify.addHook=function(e,t){"function"==typeof t&&f(se[e],t)},DOMPurify.removeHook=function(e,t){if(void 0!==t){const n=d(se[e],t);return-1===n?void 0:h(se[e],n,1)[0]}return m(se[e])},DOMPurify.removeHooks=function(e){se[e]=[]},DOMPurify.removeAllHooks=function(){se={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},DOMPurify}();e.exports=Q}}]); \ No newline at end of file diff --git a/assets/js/0726b2d81686a5392236.bundle.min.js.LICENSE.txt b/assets/js/0726b2d81686a5392236.bundle.min.js.LICENSE.txt new file mode 100644 index 00000000..6e97ec6e --- /dev/null +++ b/assets/js/0726b2d81686a5392236.bundle.min.js.LICENSE.txt @@ -0,0 +1 @@ +/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */ diff --git a/assets/js/36c2990924ec9596ffad.bundle.js b/assets/js/36c2990924ec9596ffad.bundle.js new file mode 100644 index 00000000..68ad92a4 --- /dev/null +++ b/assets/js/36c2990924ec9596ffad.bundle.js @@ -0,0 +1,178 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["modules_query-control_assets_js_editor_template-query-control_js"],{ + +/***/ "../modules/query-control/assets/js/editor/template-query-control.js": +/*!***************************************************************************!*\ + !*** ../modules/query-control/assets/js/editor/template-query-control.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _queryControl = _interopRequireDefault(__webpack_require__(/*! ./query-control */ "../modules/query-control/assets/js/editor/query-control.js")); +class TemplateQueryControl extends _queryControl.default { + ui() { + return { + ...super.ui(), + newButton: 'button[data-action="new"]', + editButton: 'button[data-action="edit"]' + }; + } + events() { + return { + ...super.events(), + 'click @ui.newButton': 'onNewButtonClicked', + 'click @ui.editButton': 'onEditButtonClicked' + }; + } + onRender(...args) { + super.onRender(...args); + this.toggleButtons(this.getControlValue()); + } + onBaseInputChange(...args) { + super.onBaseInputChange(...args); + this.toggleButtons(this.getInputValue(args[0].currentTarget)); + } + toggleButtons(templateID) { + if (!templateID) { + this.showNewTemplateButton(); + } else { + this.showEditTemplateButton(); + } + } + showNewTemplateButton() { + const newButton = this.ui?.newButton?.get(0), + editButton = this.ui?.editButton?.get(0); + if (newButton) { + newButton.style.display = 'block'; + } + if (editButton) { + editButton.style.display = 'none'; + } + } + showEditTemplateButton() { + const newButton = this.ui.newButton.get(0), + editButton = this.ui.editButton.get(0); + if (newButton) { + newButton.style.display = 'none'; + } + if (editButton) { + editButton.style.display = 'block'; + } + } + async onNewButtonClicked() { + this.createTemplate(); + } + + /** + * This function is used to create a new template via the REST API. + * We first show a confirm dialog so the user knows that the current document will be saved while creating + * and editing a new template. If the user chooses to cancel the process will not continue, + * and if confirmed the new template is created and the Editor switched to this newly created template. + * + * @since 3.8.0 + * + * @return {void} + */ + createTemplate() { + if (!this.confirmSaveBeforeTemplateCreateDialog) { + this.confirmSaveBeforeTemplateCreateDialog = elementorCommon.dialogsManager.createWidget('confirm', { + id: 'e-confirm-save-before-template-create', + headerMessage: __('Save Changes', 'elementor-pro'), + message: __('Would you like to save the changes you\'ve made?', 'elementor-pro'), + position: { + my: 'center center', + at: 'center center' + }, + strings: { + confirm: __('Save', 'elementor-pro'), + cancel: __('Discard', 'elementor-pro') + }, + onConfirm: async () => { + await this.onConfirmCreateTemplate(); + } + }); + } + this.confirmSaveBeforeTemplateCreateDialog.show(); + } + async onConfirmCreateTemplate() { + $e.internal('panel/state-loading'); + const templateID = await this.createAndSetTemplate(); + this.afterAction('new', templateID); + $e.internal('panel/state-ready'); + } + async createAndSetTemplate() { + const controlId = this.model.get('name'), + newTemplateType = this.options.container.controls[controlId].actions.new.document_config.type, + newTemplateSource = this.getTemplateSourceTypeValue(), + newTemplate = await $e.data.create('library/templates', { + type: newTemplateType, + page_settings: { + source: newTemplateSource + } + }), + templateID = parseInt(newTemplate.data.template_id); + this.setValue(templateID); + return templateID; + } + getTemplateSourceTypeValue() { + if ('repeater' === this.options?.container?.args?.type) { + return this.options.container.renderer.args.settings.attributes._skin || undefined; + } + return this.options.container.controls._skin ? this.options.container.panel.getControlView('_skin').getControlValue() : undefined; + } + + /** + * Function to switch the Editor when a user clicks to create a new template or edit the chosen template. + * + * @since 3.8.0 + * + * @param {string|number} id + * + * @return {Promise} + */ + async switchDocument(id) { + // Await $e.run( 'document/save/update', { force: true } ); + await $e.run('editor/documents/switch', { + id: parseInt(id), + mode: 'save' + }); + const document = elementor.documents.getCurrent(); + if (document.config.container_attributes && document.config.container_attributes.class) { + document.$element.addClass(document.config.container_attributes.class); + } + } + async onEditButtonClicked() { + this.afterAction('edit', this.getControlValue()); + } + getSelect2Placeholder() { + return { + id: '', + text: __('Start typing its name', 'elementor-pro') + }; + } + async afterAction(context, templateID) { + const action = 'new' === context ? this.ui.newButton[0].getAttribute('data-after-action') : this.ui.editButton[0].getAttribute('data-after-action'); + if ('switch_document' === action) { + await this.switchDocument(templateID); + } else { + window.open(this.getThemeBuilderURL(templateID), '_blank'); + } + } + getThemeBuilderURL(templateID) { + return `${elementor.config.admin_url}post.php?post=${templateID}&action=elementor`; + } +} +exports["default"] = TemplateQueryControl; + +/***/ }) + +}]); +//# sourceMappingURL=36c2990924ec9596ffad.bundle.js.map \ No newline at end of file diff --git a/assets/js/8b11be0d97d58e135d30.bundle.js b/assets/js/8b11be0d97d58e135d30.bundle.js new file mode 100644 index 00000000..3d3d58fc --- /dev/null +++ b/assets/js/8b11be0d97d58e135d30.bundle.js @@ -0,0 +1,1364 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["vendors-node_modules_dompurify_dist_purify_cjs_js"],{ + +/***/ "../node_modules/dompurify/dist/purify.cjs.js": +/*!****************************************************!*\ + !*** ../node_modules/dompurify/dist/purify.cjs.js ***! + \****************************************************/ +/***/ ((module) => { + +/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */ + + + +const { + entries, + setPrototypeOf, + isFrozen, + getPrototypeOf, + getOwnPropertyDescriptor +} = Object; +let { + freeze, + seal, + create +} = Object; // eslint-disable-line import/no-mutable-exports +let { + apply, + construct +} = typeof Reflect !== 'undefined' && Reflect; +if (!freeze) { + freeze = function freeze(x) { + return x; + }; +} +if (!seal) { + seal = function seal(x) { + return x; + }; +} +if (!apply) { + apply = function apply(fun, thisValue, args) { + return fun.apply(thisValue, args); + }; +} +if (!construct) { + construct = function construct(Func, args) { + return new Func(...args); + }; +} +const arrayForEach = unapply(Array.prototype.forEach); +const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf); +const arrayPop = unapply(Array.prototype.pop); +const arrayPush = unapply(Array.prototype.push); +const arraySplice = unapply(Array.prototype.splice); +const stringToLowerCase = unapply(String.prototype.toLowerCase); +const stringToString = unapply(String.prototype.toString); +const stringMatch = unapply(String.prototype.match); +const stringReplace = unapply(String.prototype.replace); +const stringIndexOf = unapply(String.prototype.indexOf); +const stringTrim = unapply(String.prototype.trim); +const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty); +const regExpTest = unapply(RegExp.prototype.test); +const typeErrorCreate = unconstruct(TypeError); +/** + * Creates a new function that calls the given function with a specified thisArg and arguments. + * + * @param func - The function to be wrapped and called. + * @returns A new function that calls the given function with a specified thisArg and arguments. + */ +function unapply(func) { + return function (thisArg) { + if (thisArg instanceof RegExp) { + thisArg.lastIndex = 0; + } + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + return apply(func, thisArg, args); + }; +} +/** + * Creates a new function that constructs an instance of the given constructor function with the provided arguments. + * + * @param func - The constructor function to be wrapped and called. + * @returns A new function that constructs an instance of the given constructor function with the provided arguments. + */ +function unconstruct(func) { + return function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + return construct(func, args); + }; +} +/** + * Add properties to a lookup table + * + * @param set - The set to which elements will be added. + * @param array - The array containing elements to be added to the set. + * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set. + * @returns The modified set with added elements. + */ +function addToSet(set, array) { + let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase; + if (setPrototypeOf) { + // Make 'in' and truthy checks like Boolean(set.constructor) + // independent of any properties defined on Object.prototype. + // Prevent prototype setters from intercepting set as a this value. + setPrototypeOf(set, null); + } + let l = array.length; + while (l--) { + let element = array[l]; + if (typeof element === 'string') { + const lcElement = transformCaseFunc(element); + if (lcElement !== element) { + // Config presets (e.g. tags.js, attrs.js) are immutable. + if (!isFrozen(array)) { + array[l] = lcElement; + } + element = lcElement; + } + } + set[element] = true; + } + return set; +} +/** + * Clean up an array to harden against CSPP + * + * @param array - The array to be cleaned. + * @returns The cleaned version of the array + */ +function cleanArray(array) { + for (let index = 0; index < array.length; index++) { + const isPropertyExist = objectHasOwnProperty(array, index); + if (!isPropertyExist) { + array[index] = null; + } + } + return array; +} +/** + * Shallow clone an object + * + * @param object - The object to be cloned. + * @returns A new object that copies the original. + */ +function clone(object) { + const newObject = create(null); + for (const [property, value] of entries(object)) { + const isPropertyExist = objectHasOwnProperty(object, property); + if (isPropertyExist) { + if (Array.isArray(value)) { + newObject[property] = cleanArray(value); + } else if (value && typeof value === 'object' && value.constructor === Object) { + newObject[property] = clone(value); + } else { + newObject[property] = value; + } + } + } + return newObject; +} +/** + * This method automatically checks if the prop is function or getter and behaves accordingly. + * + * @param object - The object to look up the getter function in its prototype chain. + * @param prop - The property name for which to find the getter function. + * @returns The getter function found in the prototype chain or a fallback function. + */ +function lookupGetter(object, prop) { + while (object !== null) { + const desc = getOwnPropertyDescriptor(object, prop); + if (desc) { + if (desc.get) { + return unapply(desc.get); + } + if (typeof desc.value === 'function') { + return unapply(desc.value); + } + } + object = getPrototypeOf(object); + } + function fallbackValue() { + return null; + } + return fallbackValue; +} + +const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); +const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); +const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); +// List of SVG elements that are disallowed by default. +// We still need to know them so that we can do namespace +// checks properly in case one wants to add them to +// allow-list. +const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); +const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); +// Similarly to SVG, we want to know all MathML elements, +// even those that we disallow by default. +const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); +const text = freeze(['#text']); + +const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']); +const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); +const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); +const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); + +// eslint-disable-next-line unicorn/better-regex +const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode +const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); +const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex +const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape +const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape +const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape +); +const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); +const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex +); +const DOCTYPE_NAME = seal(/^html$/i); +const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); + +var EXPRESSIONS = /*#__PURE__*/Object.freeze({ + __proto__: null, + ARIA_ATTR: ARIA_ATTR, + ATTR_WHITESPACE: ATTR_WHITESPACE, + CUSTOM_ELEMENT: CUSTOM_ELEMENT, + DATA_ATTR: DATA_ATTR, + DOCTYPE_NAME: DOCTYPE_NAME, + ERB_EXPR: ERB_EXPR, + IS_ALLOWED_URI: IS_ALLOWED_URI, + IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, + MUSTACHE_EXPR: MUSTACHE_EXPR, + TMPLIT_EXPR: TMPLIT_EXPR +}); + +/* eslint-disable @typescript-eslint/indent */ +// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType +const NODE_TYPE = { + element: 1, + attribute: 2, + text: 3, + cdataSection: 4, + entityReference: 5, + // Deprecated + entityNode: 6, + // Deprecated + progressingInstruction: 7, + comment: 8, + document: 9, + documentType: 10, + documentFragment: 11, + notation: 12 // Deprecated +}; +const getGlobal = function getGlobal() { + return typeof window === 'undefined' ? null : window; +}; +/** + * Creates a no-op policy for internal use only. + * Don't export this function outside this module! + * @param trustedTypes The policy factory. + * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). + * @return The policy created (or null, if Trusted Types + * are not supported or creating the policy failed). + */ +const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { + if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { + return null; + } + // Allow the callers to control the unique policy name + // by adding a data-tt-policy-suffix to the script element with the DOMPurify. + // Policy creation with duplicate names throws in Trusted Types. + let suffix = null; + const ATTR_NAME = 'data-tt-policy-suffix'; + if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { + suffix = purifyHostElement.getAttribute(ATTR_NAME); + } + const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); + try { + return trustedTypes.createPolicy(policyName, { + createHTML(html) { + return html; + }, + createScriptURL(scriptUrl) { + return scriptUrl; + } + }); + } catch (_) { + // Policy creation failed (most likely another DOMPurify script has + // already run). Skip creating the policy, as this will only cause errors + // if TT are enforced. + console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); + return null; + } +}; +const _createHooksMap = function _createHooksMap() { + return { + afterSanitizeAttributes: [], + afterSanitizeElements: [], + afterSanitizeShadowDOM: [], + beforeSanitizeAttributes: [], + beforeSanitizeElements: [], + beforeSanitizeShadowDOM: [], + uponSanitizeAttribute: [], + uponSanitizeElement: [], + uponSanitizeShadowNode: [] + }; +}; +function createDOMPurify() { + let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); + const DOMPurify = root => createDOMPurify(root); + DOMPurify.version = '3.2.6'; + DOMPurify.removed = []; + if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) { + // Not running in a browser, provide a factory function + // so that you can pass your own Window + DOMPurify.isSupported = false; + return DOMPurify; + } + let { + document + } = window; + const originalDocument = document; + const currentScript = originalDocument.currentScript; + const { + DocumentFragment, + HTMLTemplateElement, + Node, + Element, + NodeFilter, + NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, + HTMLFormElement, + DOMParser, + trustedTypes + } = window; + const ElementPrototype = Element.prototype; + const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); + const remove = lookupGetter(ElementPrototype, 'remove'); + const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); + const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); + const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); + // As per issue #47, the web-components registry is inherited by a + // new document created via createHTMLDocument. As per the spec + // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) + // a new empty registry is used when creating a template contents owner + // document, so we use that as our parent document to ensure nothing + // is inherited. + if (typeof HTMLTemplateElement === 'function') { + const template = document.createElement('template'); + if (template.content && template.content.ownerDocument) { + document = template.content.ownerDocument; + } + } + let trustedTypesPolicy; + let emptyHTML = ''; + const { + implementation, + createNodeIterator, + createDocumentFragment, + getElementsByTagName + } = document; + const { + importNode + } = originalDocument; + let hooks = _createHooksMap(); + /** + * Expose whether this browser supports running the full DOMPurify. + */ + DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined; + const { + MUSTACHE_EXPR, + ERB_EXPR, + TMPLIT_EXPR, + DATA_ATTR, + ARIA_ATTR, + IS_SCRIPT_OR_DATA, + ATTR_WHITESPACE, + CUSTOM_ELEMENT + } = EXPRESSIONS; + let { + IS_ALLOWED_URI: IS_ALLOWED_URI$1 + } = EXPRESSIONS; + /** + * We consider the elements and attributes below to be safe. Ideally + * don't add any new ones but feel free to remove unwanted ones. + */ + /* allowed element names */ + let ALLOWED_TAGS = null; + const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); + /* Allowed attribute names */ + let ALLOWED_ATTR = null; + const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); + /* + * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements. + * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) + * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) + * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. + */ + let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, { + tagNameCheck: { + writable: true, + configurable: false, + enumerable: true, + value: null + }, + attributeNameCheck: { + writable: true, + configurable: false, + enumerable: true, + value: null + }, + allowCustomizedBuiltInElements: { + writable: true, + configurable: false, + enumerable: true, + value: false + } + })); + /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ + let FORBID_TAGS = null; + /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ + let FORBID_ATTR = null; + /* Decide if ARIA attributes are okay */ + let ALLOW_ARIA_ATTR = true; + /* Decide if custom data attributes are okay */ + let ALLOW_DATA_ATTR = true; + /* Decide if unknown protocols are okay */ + let ALLOW_UNKNOWN_PROTOCOLS = false; + /* Decide if self-closing tags in attributes are allowed. + * Usually removed due to a mXSS issue in jQuery 3.0 */ + let ALLOW_SELF_CLOSE_IN_ATTR = true; + /* Output should be safe for common template engines. + * This means, DOMPurify removes data attributes, mustaches and ERB + */ + let SAFE_FOR_TEMPLATES = false; + /* Output should be safe even for XML used within HTML and alike. + * This means, DOMPurify removes comments when containing risky content. + */ + let SAFE_FOR_XML = true; + /* Decide if document with ... should be returned */ + let WHOLE_DOCUMENT = false; + /* Track whether config is already set on this instance of DOMPurify. */ + let SET_CONFIG = false; + /* Decide if all elements (e.g. style, script) must be children of + * document.body. By default, browsers might move them to document.head */ + let FORCE_BODY = false; + /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported). + * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead + */ + let RETURN_DOM = false; + /* Decide if a DOM `DocumentFragment` should be returned, instead of a html + * string (or a TrustedHTML object if Trusted Types are supported) */ + let RETURN_DOM_FRAGMENT = false; + /* Try to return a Trusted Type object instead of a string, return a string in + * case Trusted Types are not supported */ + let RETURN_TRUSTED_TYPE = false; + /* Output should be free from DOM clobbering attacks? + * This sanitizes markups named with colliding, clobberable built-in DOM APIs. + */ + let SANITIZE_DOM = true; + /* Achieve full DOM Clobbering protection by isolating the namespace of named + * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. + * + * HTML/DOM spec rules that enable DOM Clobbering: + * - Named Access on Window (§7.3.3) + * - DOM Tree Accessors (§3.1.5) + * - Form Element Parent-Child Relations (§4.10.3) + * - Iframe srcdoc / Nested WindowProxies (§4.8.5) + * - HTMLCollection (§4.2.10.2) + * + * Namespace isolation is implemented by prefixing `id` and `name` attributes + * with a constant string, i.e., `user-content-` + */ + let SANITIZE_NAMED_PROPS = false; + const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; + /* Keep element content when removing element? */ + let KEEP_CONTENT = true; + /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead + * of importing it into a new Document and returning a sanitized copy */ + let IN_PLACE = false; + /* Allow usage of profiles like html, svg and mathMl */ + let USE_PROFILES = {}; + /* Tags to ignore content of when KEEP_CONTENT is true */ + let FORBID_CONTENTS = null; + const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); + /* Tags that are safe for data: URIs */ + let DATA_URI_TAGS = null; + const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); + /* Attributes safe for values like "javascript:" */ + let URI_SAFE_ATTRIBUTES = null; + const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); + const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; + const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; + const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; + /* Document namespace */ + let NAMESPACE = HTML_NAMESPACE; + let IS_EMPTY_INPUT = false; + /* Allowed XHTML+XML namespaces */ + let ALLOWED_NAMESPACES = null; + const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); + let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); + let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']); + // Certain elements are allowed in both SVG and HTML + // namespace. We need to specify them explicitly + // so that they don't get erroneously deleted from + // HTML namespace. + const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']); + /* Parsing of strict XHTML documents */ + let PARSER_MEDIA_TYPE = null; + const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; + const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; + let transformCaseFunc = null; + /* Keep a reference to config to pass to hooks */ + let CONFIG = null; + /* Ideally, do not touch anything below this line */ + /* ______________________________________________ */ + const formElement = document.createElement('form'); + const isRegexOrFunction = function isRegexOrFunction(testValue) { + return testValue instanceof RegExp || testValue instanceof Function; + }; + /** + * _parseConfig + * + * @param cfg optional config literal + */ + // eslint-disable-next-line complexity + const _parseConfig = function _parseConfig() { + let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (CONFIG && CONFIG === cfg) { + return; + } + /* Shield configuration object from tampering */ + if (!cfg || typeof cfg !== 'object') { + cfg = {}; + } + /* Shield configuration object from prototype pollution */ + cfg = clone(cfg); + PARSER_MEDIA_TYPE = + // eslint-disable-next-line unicorn/prefer-includes + SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE; + // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. + transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase; + /* Set configuration parameters */ + ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; + ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; + ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; + URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES; + DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS; + FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; + FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({}); + FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({}); + USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false; + ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true + ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true + ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false + ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true + SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false + SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true + WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false + RETURN_DOM = cfg.RETURN_DOM || false; // Default false + RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false + RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false + FORCE_BODY = cfg.FORCE_BODY || false; // Default false + SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true + SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false + KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true + IN_PLACE = cfg.IN_PLACE || false; // Default false + IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; + NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; + MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS; + HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS; + CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; + if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { + CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; + } + if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { + CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; + } + if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') { + CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; + } + if (SAFE_FOR_TEMPLATES) { + ALLOW_DATA_ATTR = false; + } + if (RETURN_DOM_FRAGMENT) { + RETURN_DOM = true; + } + /* Parse profile info */ + if (USE_PROFILES) { + ALLOWED_TAGS = addToSet({}, text); + ALLOWED_ATTR = []; + if (USE_PROFILES.html === true) { + addToSet(ALLOWED_TAGS, html$1); + addToSet(ALLOWED_ATTR, html); + } + if (USE_PROFILES.svg === true) { + addToSet(ALLOWED_TAGS, svg$1); + addToSet(ALLOWED_ATTR, svg); + addToSet(ALLOWED_ATTR, xml); + } + if (USE_PROFILES.svgFilters === true) { + addToSet(ALLOWED_TAGS, svgFilters); + addToSet(ALLOWED_ATTR, svg); + addToSet(ALLOWED_ATTR, xml); + } + if (USE_PROFILES.mathMl === true) { + addToSet(ALLOWED_TAGS, mathMl$1); + addToSet(ALLOWED_ATTR, mathMl); + addToSet(ALLOWED_ATTR, xml); + } + } + /* Merge configuration parameters */ + if (cfg.ADD_TAGS) { + if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { + ALLOWED_TAGS = clone(ALLOWED_TAGS); + } + addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); + } + if (cfg.ADD_ATTR) { + if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { + ALLOWED_ATTR = clone(ALLOWED_ATTR); + } + addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); + } + if (cfg.ADD_URI_SAFE_ATTR) { + addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); + } + if (cfg.FORBID_CONTENTS) { + if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { + FORBID_CONTENTS = clone(FORBID_CONTENTS); + } + addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); + } + /* Add #text in case KEEP_CONTENT is set to true */ + if (KEEP_CONTENT) { + ALLOWED_TAGS['#text'] = true; + } + /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ + if (WHOLE_DOCUMENT) { + addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); + } + /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ + if (ALLOWED_TAGS.table) { + addToSet(ALLOWED_TAGS, ['tbody']); + delete FORBID_TAGS.tbody; + } + if (cfg.TRUSTED_TYPES_POLICY) { + if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { + throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); + } + if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { + throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); + } + // Overwrite existing TrustedTypes policy. + trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; + // Sign local variables required by `sanitize`. + emptyHTML = trustedTypesPolicy.createHTML(''); + } else { + // Uninitialized policy, attempt to initialize the internal dompurify policy. + if (trustedTypesPolicy === undefined) { + trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); + } + // If creating the internal policy succeeded sign internal variables. + if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { + emptyHTML = trustedTypesPolicy.createHTML(''); + } + } + // Prevent further manipulation of configuration. + // Not available in IE8, Safari 5, etc. + if (freeze) { + freeze(cfg); + } + CONFIG = cfg; + }; + /* Keep track of all possible SVG and MathML tags + * so that we can perform the namespace checks + * correctly. */ + const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]); + const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]); + /** + * @param element a DOM element whose namespace is being checked + * @returns Return false if the element has a + * namespace that a spec-compliant parser would never + * return. Return true otherwise. + */ + const _checkValidNamespace = function _checkValidNamespace(element) { + let parent = getParentNode(element); + // In JSDOM, if we're inside shadow DOM, then parentNode + // can be null. We just simulate parent in this case. + if (!parent || !parent.tagName) { + parent = { + namespaceURI: NAMESPACE, + tagName: 'template' + }; + } + const tagName = stringToLowerCase(element.tagName); + const parentTagName = stringToLowerCase(parent.tagName); + if (!ALLOWED_NAMESPACES[element.namespaceURI]) { + return false; + } + if (element.namespaceURI === SVG_NAMESPACE) { + // The only way to switch from HTML namespace to SVG + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'svg'; + } + // The only way to switch from MathML to SVG is via` + // svg if parent is either or MathML + // text integration points. + if (parent.namespaceURI === MATHML_NAMESPACE) { + return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); + } + // We only allow elements that are defined in SVG + // spec. All others are disallowed in SVG namespace. + return Boolean(ALL_SVG_TAGS[tagName]); + } + if (element.namespaceURI === MATHML_NAMESPACE) { + // The only way to switch from HTML namespace to MathML + // is via . If it happens via any other tag, then + // it should be killed. + if (parent.namespaceURI === HTML_NAMESPACE) { + return tagName === 'math'; + } + // The only way to switch from SVG to MathML is via + // and HTML integration points + if (parent.namespaceURI === SVG_NAMESPACE) { + return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; + } + // We only allow elements that are defined in MathML + // spec. All others are disallowed in MathML namespace. + return Boolean(ALL_MATHML_TAGS[tagName]); + } + if (element.namespaceURI === HTML_NAMESPACE) { + // The only way to switch from SVG to HTML is via + // HTML integration points, and from MathML to HTML + // is via MathML text integration points + if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { + return false; + } + if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { + return false; + } + // We disallow tags that are specific for MathML + // or SVG and should never appear in HTML namespace + return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); + } + // For XHTML and XML documents that support custom namespaces + if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) { + return true; + } + // The code should never reach this place (this means + // that the element somehow got namespace that is not + // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). + // Return false just in case. + return false; + }; + /** + * _forceRemove + * + * @param node a DOM node + */ + const _forceRemove = function _forceRemove(node) { + arrayPush(DOMPurify.removed, { + element: node + }); + try { + // eslint-disable-next-line unicorn/prefer-dom-node-remove + getParentNode(node).removeChild(node); + } catch (_) { + remove(node); + } + }; + /** + * _removeAttribute + * + * @param name an Attribute name + * @param element a DOM node + */ + const _removeAttribute = function _removeAttribute(name, element) { + try { + arrayPush(DOMPurify.removed, { + attribute: element.getAttributeNode(name), + from: element + }); + } catch (_) { + arrayPush(DOMPurify.removed, { + attribute: null, + from: element + }); + } + element.removeAttribute(name); + // We void attribute values for unremovable "is" attributes + if (name === 'is') { + if (RETURN_DOM || RETURN_DOM_FRAGMENT) { + try { + _forceRemove(element); + } catch (_) {} + } else { + try { + element.setAttribute(name, ''); + } catch (_) {} + } + } + }; + /** + * _initDocument + * + * @param dirty - a string of dirty markup + * @return a DOM, filled with the dirty markup + */ + const _initDocument = function _initDocument(dirty) { + /* Create a HTML document */ + let doc = null; + let leadingWhitespace = null; + if (FORCE_BODY) { + dirty = '' + dirty; + } else { + /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ + const matches = stringMatch(dirty, /^[\r\n\t ]+/); + leadingWhitespace = matches && matches[0]; + } + if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) { + // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) + dirty = '' + dirty + ''; + } + const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; + /* + * Use the DOMParser API by default, fallback later if needs be + * DOMParser not work for svg when has multiple root element. + */ + if (NAMESPACE === HTML_NAMESPACE) { + try { + doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); + } catch (_) {} + } + /* Use createHTMLDocument in case DOMParser is not available */ + if (!doc || !doc.documentElement) { + doc = implementation.createDocument(NAMESPACE, 'template', null); + try { + doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; + } catch (_) { + // Syntax error if dirtyPayload is invalid xml + } + } + const body = doc.body || doc.documentElement; + if (dirty && leadingWhitespace) { + body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); + } + /* Work on whole document or just its body */ + if (NAMESPACE === HTML_NAMESPACE) { + return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; + } + return WHOLE_DOCUMENT ? doc.documentElement : body; + }; + /** + * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. + * + * @param root The root element or node to start traversing on. + * @return The created NodeIterator + */ + const _createNodeIterator = function _createNodeIterator(root) { + return createNodeIterator.call(root.ownerDocument || root, root, + // eslint-disable-next-line no-bitwise + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null); + }; + /** + * _isClobbered + * + * @param element element to check for clobbering attacks + * @return true if clobbered, false if safe + */ + const _isClobbered = function _isClobbered(element) { + return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function'); + }; + /** + * Checks whether the given object is a DOM node. + * + * @param value object to check whether it's a DOM node + * @return true is object is a DOM node + */ + const _isNode = function _isNode(value) { + return typeof Node === 'function' && value instanceof Node; + }; + function _executeHooks(hooks, currentNode, data) { + arrayForEach(hooks, hook => { + hook.call(DOMPurify, currentNode, data, CONFIG); + }); + } + /** + * _sanitizeElements + * + * @protect nodeName + * @protect textContent + * @protect removeChild + * @param currentNode to check for permission to exist + * @return true if node was killed, false if left alive + */ + const _sanitizeElements = function _sanitizeElements(currentNode) { + let content = null; + /* Execute a hook if present */ + _executeHooks(hooks.beforeSanitizeElements, currentNode, null); + /* Check if element is clobbered or can clobber */ + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + return true; + } + /* Now let's check the element's type and name */ + const tagName = transformCaseFunc(currentNode.nodeName); + /* Execute a hook if present */ + _executeHooks(hooks.uponSanitizeElement, currentNode, { + tagName, + allowedTags: ALLOWED_TAGS + }); + /* Detect mXSS attempts abusing namespace confusion */ + if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) { + _forceRemove(currentNode); + return true; + } + /* Remove any occurrence of processing instructions */ + if (currentNode.nodeType === NODE_TYPE.progressingInstruction) { + _forceRemove(currentNode); + return true; + } + /* Remove any kind of possibly harmful comments */ + if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) { + _forceRemove(currentNode); + return true; + } + /* Remove element if anything forbids its presence */ + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + /* Check if we have a custom element to handle */ + if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) { + return false; + } + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) { + return false; + } + } + /* Keep content except for bad-listed elements */ + if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { + const parentNode = getParentNode(currentNode) || currentNode.parentNode; + const childNodes = getChildNodes(currentNode) || currentNode.childNodes; + if (childNodes && parentNode) { + const childCount = childNodes.length; + for (let i = childCount - 1; i >= 0; --i) { + const childClone = cloneNode(childNodes[i], true); + childClone.__removalCount = (currentNode.__removalCount || 0) + 1; + parentNode.insertBefore(childClone, getNextSibling(currentNode)); + } + } + } + _forceRemove(currentNode); + return true; + } + /* Check whether element has a valid namespace */ + if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { + _forceRemove(currentNode); + return true; + } + /* Make sure that older browsers don't get fallback-tag mXSS */ + if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { + _forceRemove(currentNode); + return true; + } + /* Sanitize element content to be template-safe */ + if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) { + /* Get the element's text content */ + content = currentNode.textContent; + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { + content = stringReplace(content, expr, ' '); + }); + if (currentNode.textContent !== content) { + arrayPush(DOMPurify.removed, { + element: currentNode.cloneNode() + }); + currentNode.textContent = content; + } + } + /* Execute a hook if present */ + _executeHooks(hooks.afterSanitizeElements, currentNode, null); + return false; + }; + /** + * _isValidAttribute + * + * @param lcTag Lowercase tag name of containing element. + * @param lcName Lowercase attribute name. + * @param value Attribute value. + * @return Returns true if `value` is valid, otherwise false. + */ + // eslint-disable-next-line complexity + const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { + /* Make sure attribute cannot clobber */ + if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { + return false; + } + /* Allow valid data-* attributes: At least one character after "-" + (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) + XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) + We don't need to check the value; it's always URI safe. */ + if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { + if ( + // First condition does a very basic check if a) it's basically a valid custom element tagname AND + // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck + _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || + // Alternative, second condition checks if it's an `is`-attribute, AND + // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck + lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else { + return false; + } + /* Check value is safe. First, is attr inert? If so, is safe */ + } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) { + return false; + } else ; + return true; + }; + /** + * _isBasicCustomElement + * checks if at least one dash is included in tagName, and it's not the first char + * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name + * + * @param tagName name of the tag of the node to sanitize + * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false. + */ + const _isBasicCustomElement = function _isBasicCustomElement(tagName) { + return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT); + }; + /** + * _sanitizeAttributes + * + * @protect attributes + * @protect nodeName + * @protect removeAttribute + * @protect setAttribute + * + * @param currentNode to sanitize + */ + const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { + /* Execute a hook if present */ + _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null); + const { + attributes + } = currentNode; + /* Check if we have attributes; if not we might have a text node */ + if (!attributes || _isClobbered(currentNode)) { + return; + } + const hookEvent = { + attrName: '', + attrValue: '', + keepAttr: true, + allowedAttributes: ALLOWED_ATTR, + forceKeepAttr: undefined + }; + let l = attributes.length; + /* Go backwards over all attributes; safely remove bad ones */ + while (l--) { + const attr = attributes[l]; + const { + name, + namespaceURI, + value: attrValue + } = attr; + const lcName = transformCaseFunc(name); + const initValue = attrValue; + let value = name === 'value' ? initValue : stringTrim(initValue); + /* Execute a hook if present */ + hookEvent.attrName = lcName; + hookEvent.attrValue = value; + hookEvent.keepAttr = true; + hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set + _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent); + value = hookEvent.attrValue; + /* Full DOM Clobbering protection via namespace isolation, + * Prefix id and name attributes with `user-content-` + */ + if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { + // Remove the attribute with this value + _removeAttribute(name, currentNode); + // Prefix the value and later re-create the attribute with the sanitized value + value = SANITIZE_NAMED_PROPS_PREFIX + value; + } + /* Work around a security issue with comments inside attributes */ + if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) { + _removeAttribute(name, currentNode); + continue; + } + /* Did the hooks approve of the attribute? */ + if (hookEvent.forceKeepAttr) { + continue; + } + /* Did the hooks approve of the attribute? */ + if (!hookEvent.keepAttr) { + _removeAttribute(name, currentNode); + continue; + } + /* Work around a security issue in jQuery 3.0 */ + if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { + _removeAttribute(name, currentNode); + continue; + } + /* Sanitize attribute content to be template-safe */ + if (SAFE_FOR_TEMPLATES) { + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { + value = stringReplace(value, expr, ' '); + }); + } + /* Is `value` valid for this attribute? */ + const lcTag = transformCaseFunc(currentNode.nodeName); + if (!_isValidAttribute(lcTag, lcName, value)) { + _removeAttribute(name, currentNode); + continue; + } + /* Handle attributes that require Trusted Types */ + if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { + if (namespaceURI) ; else { + switch (trustedTypes.getAttributeType(lcTag, lcName)) { + case 'TrustedHTML': + { + value = trustedTypesPolicy.createHTML(value); + break; + } + case 'TrustedScriptURL': + { + value = trustedTypesPolicy.createScriptURL(value); + break; + } + } + } + } + /* Handle invalid data-* attribute set by try-catching it */ + if (value !== initValue) { + try { + if (namespaceURI) { + currentNode.setAttributeNS(namespaceURI, name, value); + } else { + /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ + currentNode.setAttribute(name, value); + } + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + } else { + arrayPop(DOMPurify.removed); + } + } catch (_) { + _removeAttribute(name, currentNode); + } + } + } + /* Execute a hook if present */ + _executeHooks(hooks.afterSanitizeAttributes, currentNode, null); + }; + /** + * _sanitizeShadowDOM + * + * @param fragment to iterate over recursively + */ + const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { + let shadowNode = null; + const shadowIterator = _createNodeIterator(fragment); + /* Execute a hook if present */ + _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null); + while (shadowNode = shadowIterator.nextNode()) { + /* Execute a hook if present */ + _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null); + /* Sanitize tags and elements */ + _sanitizeElements(shadowNode); + /* Check attributes next */ + _sanitizeAttributes(shadowNode); + /* Deep shadow DOM detected */ + if (shadowNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(shadowNode.content); + } + } + /* Execute a hook if present */ + _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null); + }; + // eslint-disable-next-line complexity + DOMPurify.sanitize = function (dirty) { + let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let body = null; + let importedNode = null; + let currentNode = null; + let returnNode = null; + /* Make sure we have a string to sanitize. + DO NOT return early, as this will return the wrong type if + the user has requested a DOM object rather than a string */ + IS_EMPTY_INPUT = !dirty; + if (IS_EMPTY_INPUT) { + dirty = ''; + } + /* Stringify, in case dirty is an object */ + if (typeof dirty !== 'string' && !_isNode(dirty)) { + if (typeof dirty.toString === 'function') { + dirty = dirty.toString(); + if (typeof dirty !== 'string') { + throw typeErrorCreate('dirty is not a string, aborting'); + } + } else { + throw typeErrorCreate('toString is not a function'); + } + } + /* Return dirty HTML if DOMPurify cannot run */ + if (!DOMPurify.isSupported) { + return dirty; + } + /* Assign config vars */ + if (!SET_CONFIG) { + _parseConfig(cfg); + } + /* Clean up removed elements */ + DOMPurify.removed = []; + /* Check if dirty is correctly typed for IN_PLACE */ + if (typeof dirty === 'string') { + IN_PLACE = false; + } + if (IN_PLACE) { + /* Do some early pre-sanitization to avoid unsafe root nodes */ + if (dirty.nodeName) { + const tagName = transformCaseFunc(dirty.nodeName); + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); + } + } + } else if (dirty instanceof Node) { + /* If dirty is a DOM element, append to an empty document to avoid + elements being stripped by the parser */ + body = _initDocument(''); + importedNode = body.ownerDocument.importNode(dirty, true); + if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') { + /* Node is already a body, use as is */ + body = importedNode; + } else if (importedNode.nodeName === 'HTML') { + body = importedNode; + } else { + // eslint-disable-next-line unicorn/prefer-dom-node-append + body.appendChild(importedNode); + } + } else { + /* Exit directly if we have nothing to do */ + if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && + // eslint-disable-next-line unicorn/prefer-includes + dirty.indexOf('<') === -1) { + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; + } + /* Initialize the document to work on */ + body = _initDocument(dirty); + /* Check we have a DOM node from the data */ + if (!body) { + return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; + } + } + /* Remove first element node (ours) if FORCE_BODY is set */ + if (body && FORCE_BODY) { + _forceRemove(body.firstChild); + } + /* Get node iterator */ + const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body); + /* Now start iterating over the created document */ + while (currentNode = nodeIterator.nextNode()) { + /* Sanitize tags and elements */ + _sanitizeElements(currentNode); + /* Check attributes next */ + _sanitizeAttributes(currentNode); + /* Shadow DOM detected, sanitize it */ + if (currentNode.content instanceof DocumentFragment) { + _sanitizeShadowDOM(currentNode.content); + } + } + /* If we sanitized `dirty` in-place, return it. */ + if (IN_PLACE) { + return dirty; + } + /* Return sanitized string or DOM */ + if (RETURN_DOM) { + if (RETURN_DOM_FRAGMENT) { + returnNode = createDocumentFragment.call(body.ownerDocument); + while (body.firstChild) { + // eslint-disable-next-line unicorn/prefer-dom-node-append + returnNode.appendChild(body.firstChild); + } + } else { + returnNode = body; + } + if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { + /* + AdoptNode() is not used because internal state is not reset + (e.g. the past names map of a HTMLFormElement), this is safe + in theory but we would rather not risk another attack vector. + The state that is cloned by importNode() is explicitly defined + by the specs. + */ + returnNode = importNode.call(originalDocument, returnNode, true); + } + return returnNode; + } + let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; + /* Serialize doctype if allowed */ + if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { + serializedHTML = '\n' + serializedHTML; + } + /* Sanitize final string template-safe */ + if (SAFE_FOR_TEMPLATES) { + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { + serializedHTML = stringReplace(serializedHTML, expr, ' '); + }); + } + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; + }; + DOMPurify.setConfig = function () { + let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + _parseConfig(cfg); + SET_CONFIG = true; + }; + DOMPurify.clearConfig = function () { + CONFIG = null; + SET_CONFIG = false; + }; + DOMPurify.isValidAttribute = function (tag, attr, value) { + /* Initialize shared config vars if necessary. */ + if (!CONFIG) { + _parseConfig({}); + } + const lcTag = transformCaseFunc(tag); + const lcName = transformCaseFunc(attr); + return _isValidAttribute(lcTag, lcName, value); + }; + DOMPurify.addHook = function (entryPoint, hookFunction) { + if (typeof hookFunction !== 'function') { + return; + } + arrayPush(hooks[entryPoint], hookFunction); + }; + DOMPurify.removeHook = function (entryPoint, hookFunction) { + if (hookFunction !== undefined) { + const index = arrayLastIndexOf(hooks[entryPoint], hookFunction); + return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0]; + } + return arrayPop(hooks[entryPoint]); + }; + DOMPurify.removeHooks = function (entryPoint) { + hooks[entryPoint] = []; + }; + DOMPurify.removeAllHooks = function () { + hooks = _createHooksMap(); + }; + return DOMPurify; +} +var purify = createDOMPurify(); + +module.exports = purify; +//# sourceMappingURL=purify.cjs.js.map + + +/***/ }) + +}]); +//# sourceMappingURL=8b11be0d97d58e135d30.bundle.js.map \ No newline at end of file diff --git a/assets/js/admin.js b/assets/js/admin.js new file mode 100644 index 00000000..34ea6f59 --- /dev/null +++ b/assets/js/admin.js @@ -0,0 +1,1735 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../license/assets/js/admin.js": +/*!*************************************!*\ + !*** ../license/assets/js/admin.js ***! + \*************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class Module extends elementorModules.Module { + #actionLinks = [{ + href: 'elementor_pro_renew_license_menu_link', + external_url: 'https://go.elementor.com/wp-menu-renew/' + }, { + href: 'elementor_pro_upgrade_license_menu_link', + external_url: 'https://go.elementor.com/go-pro-advanced-elementor-menu/' + }]; + onInit() { + this.assignMenuItemActions(); + this.assignProLicenseActivateEvent(); + } + assignMenuItemActions() { + window.addEventListener('DOMContentLoaded', () => { + this.#actionLinks.forEach(item => { + const link = document.querySelector(`a[href="${item.href}"]`); + if (!link) { + return; + } + link.addEventListener('click', e => { + e.preventDefault(); + window.open(item.external_url, '_blank'); + }); + }); + }); + } + assignProLicenseActivateEvent() { + window.addEventListener('DOMContentLoaded', () => { + const activateButton = document.querySelector('.button-primary[href*="elementor-connect"]'); + if (activateButton) { + activateButton.addEventListener('click', () => { + if (!window.elementorCommon?.config?.experimentalFeatures?.editor_events) { + return; + } + const eventsManager = window.elementorCommon?.eventsManager || {}; + const dispatchEvent = eventsManager.dispatchEvent?.bind(eventsManager); + const eventName = 'pro_license_activate'; + const eventData = { + app_type: 'editor', + location: 'Elementor WP-admin pages', + secondaryLocation: 'license page', + trigger: 'click' + }; + dispatchEvent?.(eventName, eventData); + }); + } + }); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin.js": +/*!****************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _elementorFontManager = _interopRequireDefault(__webpack_require__(/*! ./admin/elementor-font-manager */ "../modules/assets-manager/assets/js/admin/elementor-font-manager.js")); +var _elementorCustomIcons = _interopRequireDefault(__webpack_require__(/*! ./admin/elementor-custom-icons */ "../modules/assets-manager/assets/js/admin/elementor-custom-icons.js")); +module.exports = function () { + const TypekitAdmin = __webpack_require__(/*! ./admin/typekit */ "../modules/assets-manager/assets/js/admin/typekit.js"), + CustomIcon = _elementorCustomIcons.default, + FontAwesomeProAdmin = (__webpack_require__(/*! ./admin/font-awesome-pro */ "../modules/assets-manager/assets/js/admin/font-awesome-pro.js")["default"]); + this.fontManager = new _elementorFontManager.default(); + this.typekit = new TypekitAdmin(); + this.fontAwesomePro = new FontAwesomeProAdmin(); + this.customIcons = new CustomIcon(); +}; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/custom-assets-base.js": +/*!***********************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/custom-assets-base.js ***! + \***********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class CustomAssetsBase extends elementorModules.ViewModule { + showAlertDialog(id, message, onConfirm = false, onHide = false) { + const alertData = { + id, + message + }; + if (onConfirm) { + alertData.onConfirm = onConfirm; + } + if (onHide) { + alertData.onHide = onHide; + } + + // Save the instance of the alert dialog to check for its visibility later + if (!this.alertWidget) { + this.alertWidget = elementorCommon.dialogsManager.createWidget('alert', alertData); + } + this.alertWidget.show(); + } + onDialogDismiss() { + // WP's publish button gets a disabled class on submit attempt + this.elements.$publishButton.removeClass('disabled'); + + // Prevent WP's publish spinner from appearing on publish attempt + this.elements.$publishButtonSpinner.removeClass('is-active'); + } + handleSubmit(event) { + // If we know there is a file already, return to continue submission normally + if (this.fileWasUploaded) { + return; + } + const hasValue = this.checkInputsForValues(); // Method exists in the child classes + + // If the file input is not empty, continue the submission process + if (hasValue) { + this.fileWasUploaded = true; + this.elements.$postForm.trigger('submit'); + return; + } + event.preventDefault(); // Prevent new asset submission + + // If no value was found, stop submission and display a notice modal + this.showAlertDialog('noData', this.getSettings('notice'), () => this.onDialogDismiss(), + // OnConfirm + () => this.onDialogDismiss() // OnHide + ); + return false; + } + bindEvents() { + this.elements.$postForm.on('submit', this.handleSubmit.bind(this)); + } +} +var _default = exports["default"] = CustomAssetsBase; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/elementor-custom-icons.js": +/*!***************************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/elementor-custom-icons.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _customAssetsBase = _interopRequireDefault(__webpack_require__(/*! ./custom-assets-base */ "../modules/assets-manager/assets/js/admin/custom-assets-base.js")); +var _elementorProDropzone = _interopRequireDefault(__webpack_require__(/*! ./fields/elementor-pro-dropzone */ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-dropzone.js")); +class CustomIcons extends _customAssetsBase.default { + getDefaultSettings() { + return { + fields: { + dropzone: _elementorProDropzone.default + }, + classes: { + editPageClass: 'post-type-elementor_icons', + editPhp: 'edit-php', + hasIcons: 'elementor--has-icons' + }, + selectors: { + editPageClass: 'post-type-elementor_icons', + title: '#title', + metaboxContainer: '#elementor-custom-icons-metabox', + metabox: '.elementor-custom-icons-metabox', + closeHandle: 'button.handlediv', + iconsTemplate: '#elementor-icons-template', + dataInput: '#elementor_custom_icon_set_config', + dropzone: '.zip_upload', + submitDelete: '.submitdelete', + dayInput: '#hidden_jj', + mmInput: '#hidden_mm', + yearInput: '#hidden_aa', + hourInput: '#hidden_hh', + minuteInput: '#hidden_mn', + publishButton: '#publish', + publishButtonSpinner: '#publishing-action > .spinner', + submitMetabox: '#postbox-container-1', + postForm: '#post', + fileInput: '#zip_upload', + iconSetConfigInput: '#elementor_custom_icon_set_config' + }, + templates: { + icon: '
  • {{label}}
  • ', + header: jQuery('#elementor-custom-icons-template-header').html(), + footer: jQuery('#elementor-custom-icons-template-footer').html(), + duplicatePrefix: jQuery('#elementor-custom-icons-template-duplicate-prefix').html() + }, + notice: __('Upload an icon set to publish.', 'elementor-pro') + }; + } + getDefaultElements() { + const elements = {}, + selectors = this.getSettings('selectors'); + jQuery.each(selectors, (element, selector) => { + elements['$' + element] = jQuery(selector); + }); + return elements; + } + bindEvents() { + super.bindEvents(); + if ('' !== this.getData()) { + this.bindOnTitleChange(); + } + } + bindOnTitleChange() { + const { + $title + } = this.elements, + onTitleInput = event => this.onTitleInput(event); + $title.on('input change', onTitleInput); + } + removeCloseHandle() { + const { + $metaboxContainer + } = this.elements; + $metaboxContainer.find('h2').remove(); + $metaboxContainer.find('button').remove(); + $metaboxContainer.removeClass('closed').removeClass('postbox'); + } + prepareIconName(icon) { + const iconName = icon.replace('_', ' ').replace('-', ' '); + return elementorCommon.helpers.upperCaseWords(iconName); + } + getCreatedOn() { + const { + $dayInput, + $mmInput, + $yearInput, + $hourInput, + $minuteInput + } = this.elements; + return { + day: $dayInput.val(), + mm: $mmInput.val(), + year: $yearInput.val(), + hour: $hourInput.val(), + minute: $minuteInput.val() + }; + } + enqueueCSS(url) { + if (!elementorCommon.elements.$document.find('link[href="' + url + '"]').length) { + elementorCommon.elements.$document.find('link').last().after(''); + } + } + setData(data) { + this.elements.$dataInput.val(JSON.stringify(data)); + } + getData() { + const value = this.elements.$dataInput.val(); + return '' === value ? '' : JSON.parse(value); + } + renderIconList(config) { + const iconTemplate = this.getSettings('templates.icon'); + return config.icons.map(icon => { + const data = { + icon: config.displayPrefix + ' ' + config.prefix + icon, + label: this.prepareIconName(icon) + }; + return elementorCommon.compileTemplate(iconTemplate, data); + }).join('\n'); + } + renderIcons(config) { + const { + $metaboxContainer, + $metabox, + $submitMetabox + } = this.elements; + const { + header, + footer + } = this.getSettings('templates'); + $metaboxContainer.addClass(this.getSettings('classes.hasIcons')); + $submitMetabox.show(); + this.setData(config); + this.enqueueCSS(config.url); + $metabox.html(''); + $metaboxContainer.prepend(elementorCommon.compileTemplate(header, config)); + $metabox.append('
      ' + this.renderIconList(config) + '
    '); + $metaboxContainer.append(elementorCommon.compileTemplate(footer, this.getCreatedOn())); + } + onTitleInput(event) { + const data = this.getData(); + data.label = event.target.value; + this.setData(data); + } + checkInputsForValues() { + // If creating new icon set - check the file input for a value + // If editing an existing icon set - check the icon set config input for a value + if ('' !== this.elements.$fileInput.val() || '' !== this.elements.$iconSetConfigInput.val()) { + return true; + } + return false; + } + onSuccess(data) { + // It is possible to add a `dropzoneElement` param to this method for implementing upload progress bar + if (data.data.errors) { + let id, message; + jQuery.each(data.data.errors, (errorId, errorMessage) => { + id = errorId; + message = errorMessage; + return false; + }); + return this.showAlertDialog(id, message); + } + if (data.data.config.duplicate_prefix) { + delete data.data.config.duplicatePrefix; + return this.showAlertDialog('duplicate-prefix', this.getSettings('templates.duplicatePrefix'), () => this.saveInitialUpload(data.data.config)); + } + this.saveInitialUpload(data.data.config); + } + saveInitialUpload(config) { + this.setData(config); + const { + $publishButton, + $title, + $submitMetabox + } = this.elements; + $submitMetabox.show(); + if ('' === $title.val()) { + $title.val(config.name); + } + this.fileWasUploaded = true; // Flag to prevent infinite loop in the handleSubmit() method + $publishButton.trigger('click'); + } + onInit() { + const { + $body + } = elementorCommon.elements, + { + editPageClass, + editPhp + } = this.getSettings('classes'); + if (!$body.hasClass(editPageClass) || $body.hasClass(editPhp)) { + return; + } + super.onInit(); + this.removeCloseHandle(); + const dropzoneFieldClass = this.getSettings('fields.dropzone'), + dropzoneField = new dropzoneFieldClass(), + config = this.getData(), + { + $dropzone, + $metaboxContainer + } = this.elements; + if ('' === config) { + $dropzone.show('fast'); + dropzoneField.setSettings('onSuccess', (...args) => this.onSuccess(...args)); + } else { + this.renderIcons(config); + } + $metaboxContainer.show('fast'); + } +} +var _default = exports["default"] = CustomIcons; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/elementor-font-manager.js": +/*!***************************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/elementor-font-manager.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _customAssetsBase = _interopRequireDefault(__webpack_require__(/*! ./custom-assets-base */ "../modules/assets-manager/assets/js/admin/custom-assets-base.js")); +var _elementorProUpload = _interopRequireDefault(__webpack_require__(/*! ./fields/elementor-pro-upload */ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-upload.js")); +var _elementorProRepeater = _interopRequireDefault(__webpack_require__(/*! ./fields/elementor-pro-repeater */ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-repeater.js")); +class CustomFontsManager extends _customAssetsBase.default { + getDefaultSettings() { + return { + fields: { + upload: _elementorProUpload.default, + repeater: _elementorProRepeater.default + }, + selectors: { + editPageClass: 'post-type-elementor_font', + title: '#title', + repeaterBlock: '.repeater-block', + repeaterTitle: '.repeater-title', + removeRowBtn: '.remove-repeater-row', + editRowBtn: '.toggle-repeater-row', + closeRowBtn: '.close-repeater-row', + styleInput: '.font_style', + weightInput: '.font_weight', + customFontsMetaBox: '#elementor-font-custommetabox', + closeHandle: 'button.handlediv', + toolbar: '.elementor-field-toolbar', + inlinePreview: '.inline-preview', + fileUrlInput: '.elementor-field-file input[type="text"]', + postForm: '#post', + publishButton: '#publish', + publishButtonSpinner: '#publishing-action > .spinner' + }, + notice: __('Choose a font to publish.', 'elementor-pro'), + fontLabelTemplate: '
      ' + '
    • {{weight}}
    • ' + '
    • {{style}}
    • ' + '
    • {{preview}}
    • ' + '{{toolbar}}' + '
    ' + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + $postForm: jQuery(selectors.postForm), + $publishButton: jQuery(selectors.publishButton), + $publishButtonSpinner: jQuery(selectors.publishButtonSpinner), + $closeHandle: jQuery(selectors.closeHandle), + $customFontsMetaBox: jQuery(selectors.customFontsMetaBox), + $title: jQuery(selectors.title) + }; + } + renderTemplate(tpl, data) { + const re = /{{([^}}]+)?}}/g; + let match; + while (match = re.exec(tpl)) { + // eslint-disable-line no-cond-assign + tpl = tpl.replace(match[0], data[match[1]]); + } + return tpl; + } + ucFirst(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + getPreviewStyle($table) { + const selectors = this.getSettings('selectors'), + fontFamily = this.elements.$title.val(), + style = $table.find('select' + selectors.styleInput).first().val(), + weight = $table.find('select' + selectors.weightInput).first().val(); + return { + style: this.ucFirst(style), + weight: this.ucFirst(weight), + styleAttribute: 'font-family: ' + fontFamily + ' ;font-style: ' + style + '; font-weight: ' + weight + ';' + }; + } + updateRowLabel(event, $table) { + const selectors = this.getSettings('selectors'), + fontLabelTemplate = this.getSettings('fontLabelTemplate'), + $block = $table.closest(selectors.repeaterBlock), + $deleteBtn = $block.find(selectors.removeRowBtn).first(), + $editBtn = $block.find(selectors.editRowBtn).first(), + $closeBtn = $block.find(selectors.closeRowBtn).first(), + $toolbar = $table.find(selectors.toolbar).last().clone(), + previewStyle = this.getPreviewStyle($table); + if ($editBtn.length > 0) { + $editBtn.not(selectors.toolbar + ' ' + selectors.editRowBtn).remove(); + } + if ($closeBtn.length > 0) { + $closeBtn.not(selectors.toolbar + ' ' + selectors.closeRowBtn).remove(); + } + if ($deleteBtn.length > 0) { + $deleteBtn.not(selectors.toolbar + ' ' + selectors.removeRowBtn).remove(); + } + const toolbarHtml = jQuery('
  • ').append($toolbar)[0].outerHTML; + return this.renderTemplate(fontLabelTemplate, { + weight: 'Weight:' + previewStyle.weight, + style: 'Style:' + previewStyle.style, + preview: 'Elementor is making the web beautiful', + toolbar: toolbarHtml + }); + } + onRepeaterToggleVisible(event, $btn, $table) { + const selectors = this.getSettings('selectors'), + $previewElement = $table.find(selectors.inlinePreview), + previewStyle = this.getPreviewStyle($table); + $previewElement.attr('style', previewStyle.styleAttribute); + } + onRepeaterNewRow(event, $btn, $block) { + const selectors = this.getSettings('selectors'); + $block.find(selectors.removeRowBtn).first().remove(); + $block.find(selectors.editRowBtn).first().remove(); + $block.find(selectors.closeRowBtn).first().remove(); + } + maybeToggle(event) { + event.preventDefault(); + const selectors = this.getSettings('selectors'); + if (jQuery(this).is(':visible') && !jQuery(event.target).hasClass(selectors.editRowBtn)) { + jQuery(this).find(selectors.editRowBtn).trigger('click'); + } + } + onInputChange(event) { + const $el = jQuery(event.target).next(), + fields = this.getSettings('fields'); + fields.upload.setFields($el); + fields.upload.setLabels($el); + fields.upload.replaceButtonClass($el); + } + bindEvents() { + const selectors = this.getSettings('selectors'); + jQuery(document).on('repeaterComputedLabel', this.updateRowLabel.bind(this)).on('onRepeaterToggleVisible', this.onRepeaterToggleVisible.bind(this)).on('onRepeaterNewRow', this.onRepeaterNewRow.bind(this)).on('click', selectors.repeaterTitle, this.maybeToggle.bind(this)).on('input', selectors.fileUrlInput, this.onInputChange.bind(this)); + super.bindEvents(); + } + checkInputsForValues() { + const selectors = this.getSettings('selectors'); + let hasValue = false; + + // Check the file inputs for a value + jQuery(selectors.fileUrlInput).each((index, element) => { + if ('' !== jQuery(element).val()) { + hasValue = true; + return false; // If a value was found, break the loop + } + }); + return hasValue; + } + removeCloseHandle() { + this.elements.$closeHandle.remove(); + this.elements.$customFontsMetaBox.removeClass('closed').removeClass('postbox'); + } + titleRequired() { + this.elements.$title.prop('required', true); + } + onInit(...args) { + const settings = this.getSettings(); + if (!jQuery('body').hasClass(settings.selectors.editPageClass)) { + return; + } + super.onInit(...args); + this.removeCloseHandle(); + this.titleRequired(); + settings.fields.upload.init(); + settings.fields.repeater.init(); + const $document = jQuery(document); + const markMetaboxIfVariableFont = this.markMetaboxIfVariableFont.bind(this); + jQuery('#add-variable-font').on('click', () => { + jQuery(document).one('onRepeaterNewRow', (event, $repeaterBtn, $repeaterBlock) => { + $repeaterBlock.find('input[name$="font_type]"]').val('variable'); + markMetaboxIfVariableFont(); + }); + jQuery('#elementor-font-custommetabox').find('.add-repeater-row').trigger('click'); + }); + $document.on('onRepeaterNewRow', markMetaboxIfVariableFont); + $document.on('onRepeaterRemoveRow', markMetaboxIfVariableFont); + $document.on('change', 'input[name$="variable_width]"], input[name$="variable_weight]"]', this.onFontVariableTypeChange); + markMetaboxIfVariableFont(); + } + markMetaboxIfVariableFont() { + const $fontType = jQuery('input[name$="font_type]"]'); + const $metaboxContent = jQuery('.elementor-metabox-content'); + $metaboxContent.removeClass('has-font-variable has-font-static'); + if (!$fontType.length) { + return; + } + const hasVariableRow = 'variable' === $fontType.val(); + if (hasVariableRow) { + $metaboxContent.addClass('has-font-variable', hasVariableRow); + } else { + $metaboxContent.addClass('has-font-static'); + } + jQuery('input[name$="variable_width]"], input[name$="variable_weight]"]').each(this.onFontVariableTypeChange); + } + onFontVariableTypeChange() { + const $this = jQuery(this); + const wrapDiv = $this.parents().eq(1); + wrapDiv.toggleClass('e-font-variable-hidden', !$this.is(':checked')); + } +} +exports["default"] = CustomFontsManager; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-dropzone.js": +/*!**********************************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/fields/elementor-pro-dropzone.js ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class DropZoneField extends elementorModules.ViewModule { + getDefaultSettings() { + const baseSelector = '.elementor-dropzone-field'; + return { + droppedFiles: false, + selectors: { + dropZone: baseSelector, + input: baseSelector + ' [type="file"]', + label: baseSelector + 'label', + errorMsg: baseSelector + '.box__error span', + restart: baseSelector + '.box__restart', + browseButton: baseSelector + ' .elementor--dropzone--upload__browse', + postId: '#post_ID' + }, + classes: { + drag: 'is-dragover', + error: 'is-error', + success: 'is-success', + upload: 'is-uploading' + }, + onSuccess: null, + onError: null + }; + } + getDefaultElements() { + const elements = {}; + const selectors = this.getSettings('selectors'); + jQuery.each(selectors, (element, selector) => { + elements['$' + element] = jQuery(selector); + }); + return elements; + } + bindEvents() { + const { + $dropZone, + $browseButton, + $input + } = this.elements; + const { + drag + } = this.getSettings('classes'); + $browseButton.on('click', () => $input.trigger('click')); + $dropZone.on('drag dragstart dragend dragover dragenter dragleave drop', event => { + event.preventDefault(); + event.stopPropagation(); + }).on('dragover dragenter', () => { + $dropZone.addClass(drag); + }).on('dragleave dragend drop', () => { + $dropZone.removeClass(drag); + }).on('drop change', event => { + if ('change' === event.type) { + this.setSettings('droppedFiles', event.originalEvent.target.files); + } else { + this.setSettings('droppedFiles', event.originalEvent.dataTransfer.files); + } + this.handleUpload(); + }); + } + handleUpload() { + const droppedFiles = this.getSettings('droppedFiles'); + if (!droppedFiles) { + return; + } + const { + $input, + $dropZone, + $postId, + $errorMsg + } = this.elements, + { + error, + success, + upload + } = this.getSettings('classes'), + { + onSuccess, + onError + } = this.getSettings(), + ajaxData = new FormData(), + fieldName = $input.attr('name'), + actionKey = 'pro_assets_manager_custom_icon_upload', + self = this; + Object.entries(droppedFiles).forEach(file => { + ajaxData.append(fieldName, file[1]); + }); + ajaxData.append('actions', JSON.stringify({ + pro_assets_manager_custom_icon_upload: { + action: actionKey, + data: { + post_id: $postId.val() + } + } + })); + $dropZone.removeClass(success).removeClass(error); + elementorCommon.ajax.send('ajax', { + data: ajaxData, + cache: false, + enctype: 'multipart/form-data', + contentType: false, + processData: false, + // TODO: Do something with upload progress + /* xhr: () => { + const xhr = jQuery.ajaxSettings.xhr(); + xhr.upload.onprogress = ( evt ) => { + if ( evt.lengthComputable ) { + const percentComplete = Math.round( ( evt.loaded * 100 / evt.total ) ); + } + }; + return xhr; + },*/ + complete: () => { + $dropZone.removeClass(upload); + }, + success: response => { + const data = response.responses[actionKey]; + $dropZone.addClass(data.success ? success : error); + if (data.success) { + if (onSuccess) { + onSuccess(data, self); + } + } else { + $errorMsg.text(data.error); + if (onError) { + onError(self, arguments); + } + } + }, + error: () => { + if ('function' === typeof onError) { + onError(self, arguments); + } + } + }); + } + onInit() { + super.onInit(); + elementorCommon.elements.$document.trigger('onDropzoneLoaded', [this]); + } +} +var _default = exports["default"] = DropZoneField; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-repeater.js": +/*!**********************************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/fields/elementor-pro-repeater.js ***! + \**********************************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = { + selectors: { + add: '.add-repeater-row', + remove: '.remove-repeater-row', + toggle: '.toggle-repeater-row', + close: '.close-repeater-row', + sort: '.sort-repeater-row', + table: '.form-table', + block: '.repeater-block', + repeaterLabel: '.repeater-title', + repeaterField: '.elementor-field-repeater' + }, + counters: [], + trigger(eventName, params) { + jQuery(document).trigger(eventName, params); + }, + triggerHandler(eventName, params) { + return jQuery(document).triggerHandler(eventName, params); + }, + countBlocks($btn) { + return $btn.closest(this.selectors.repeaterField).find(this.selectors.block).length || 0; + }, + add(btn) { + var self = this, + $btn = jQuery(btn), + id = $btn.data('template-id'), + repeaterBlock; + if (!Object.prototype.hasOwnProperty.call(self.counters, id)) { + self.counters[id] = self.countBlocks($btn); + } + self.counters[id] += 1; + repeaterBlock = jQuery('#' + id).html(); + repeaterBlock = self.replaceAll('__counter__', self.counters[id], repeaterBlock); + $btn.before(repeaterBlock); + self.trigger('onRepeaterNewRow', [$btn, $btn.prev()]); + }, + remove(btn) { + var self = this; + jQuery(btn).closest(self.selectors.block).remove(); + self.trigger('onRepeaterRemoveRow', [btn]); + }, + toggle(btn) { + var self = this, + $btn = jQuery(btn), + $table = $btn.closest(self.selectors.block).find(self.selectors.table), + $toggleLabel = $btn.closest(self.selectors.block).find(self.selectors.repeaterLabel); + $table.toggle(0, function () { + if ($table.is(':visible')) { + $table.closest(self.selectors.block).addClass('block-visible'); + self.trigger('onRepeaterToggleVisible', [$btn, $table, $toggleLabel]); + } else { + $table.closest(self.selectors.block).removeClass('block-visible'); + self.trigger('onRepeaterToggleHidden', [$btn, $table, $toggleLabel]); + } + }); + $toggleLabel.toggle(); + + // Update row label + self.updateRowLabel(btn); + }, + close(btn) { + var self = this, + $btn = jQuery(btn), + $table = $btn.closest(self.selectors.block).find(self.selectors.table), + $toggleLabel = $btn.closest(self.selectors.block).find(self.selectors.repeaterLabel); + $table.closest(self.selectors.block).removeClass('block-visible'); + $table.hide(); + self.trigger('onRepeaterToggleHidden', [$btn, $table, $toggleLabel]); + $toggleLabel.show(); + self.updateRowLabel(btn); + }, + updateRowLabel(btn) { + var self = this, + $btn = jQuery(btn), + $table = $btn.closest(self.selectors.block).find(self.selectors.table), + $toggleLabel = $btn.closest(self.selectors.block).find(self.selectors.repeaterLabel); + var selector = $toggleLabel.data('selector'); + // For some browsers, `attr` is undefined; for others, `attr` is false. Check for both. + if (typeof selector !== typeof undefined && false !== selector) { + var value = false, + std = $toggleLabel.data('default'); + if ($table.find(selector).length) { + value = $table.find(selector).val(); + } + + // Filter hook + var computedLabel = self.triggerHandler('repeaterComputedLabel', [$table, $toggleLabel, value]); + + // For some browsers, `attr` is undefined; for others, `attr` is false. Check for both. + if (undefined !== computedLabel && false !== computedLabel) { + value = computedLabel; + } + + // Fallback to default row label + if (undefined === value || false === value) { + value = std; + } + $toggleLabel.html(value); + } + }, + replaceAll(search, replace, string) { + return string.replace(new RegExp(search, 'g'), replace); + }, + init() { + var self = this; + jQuery(document).on('click', this.selectors.add, function (event) { + event.preventDefault(); + self.add(jQuery(this), event); + }).on('click', this.selectors.remove, function (event) { + event.preventDefault(); + // eslint-disable-next-line no-alert + var result = confirm(jQuery(this).data('confirm').toString()); + if (!result) { + return; + } + self.remove(jQuery(this), event); + }).on('click', this.selectors.toggle, function (event) { + event.preventDefault(); + event.stopPropagation(); + self.toggle(jQuery(this), event); + }).on('click', this.selectors.close, function (event) { + event.preventDefault(); + event.stopPropagation(); + self.close(jQuery(this), event); + }); + jQuery(this.selectors.toggle).each(function () { + self.updateRowLabel(jQuery(this)); + }); + this.trigger('onRepeaterLoaded', [this]); + } +}; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/fields/elementor-pro-upload.js": +/*!********************************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/fields/elementor-pro-upload.js ***! + \********************************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = { + $btn: null, + fileId: null, + fileUrl: null, + fileFrame: [], + selectors: { + uploadBtnClass: 'elementor-upload-btn', + clearBtnClass: 'elementor-upload-clear-btn', + uploadBtn: '.elementor-upload-btn', + clearBtn: '.elementor-upload-clear-btn', + inputURLField: '.elementor-field-file input[type="text"]' + }, + hasValue() { + return '' !== jQuery(this.fileUrl).val(); + }, + setLabels($el) { + if (!this.hasValue()) { + $el.val($el.data('upload_text')); + } else { + $el.val($el.data('remove_text')); + } + }, + setFields(el) { + const self = this; + self.fileUrl = jQuery(el).prev(); + self.fileId = jQuery(self.fileUrl).prev(); + }, + setUploadParams(ext, name) { + const uploader = this.fileFrame[name].uploader.uploader; + uploader.param('uploadType', ext); + uploader.param('uploadTypeCaller', 'elementor-admin-font-upload'); + uploader.param('post_id', this.getPostId()); + }, + setUploadMimeType(frame, ext) { + // Set {ext} as only allowed upload extensions + const oldExtensions = _wpPluploadSettings.defaults.filters.mime_types[0].extensions, + self = this; + frame.on('ready', () => { + _wpPluploadSettings.defaults.filters.mime_types[0].extensions = ext; + }); + frame.on('close', () => { + // Restore allowed upload extensions + _wpPluploadSettings.defaults.filters.mime_types[0].extensions = oldExtensions; + self.replaceButtonClass(self.$btn); + }); + }, + replaceButtonClass(el) { + if (this.hasValue()) { + jQuery(el).removeClass(this.selectors.uploadBtnClass).addClass(this.selectors.clearBtnClass); + } else { + jQuery(el).removeClass(this.selectors.clearBtnClass).addClass(this.selectors.uploadBtnClass); + } + this.setLabels(el); + }, + uploadFile(el) { + const self = this, + $el = jQuery(el), + mime = $el.attr('data-mime_type') || '', + ext = $el.attr('data-ext') || false, + name = $el.attr('id'); + // If the media frame already exists, reopen it. + if ('undefined' !== typeof self.fileFrame[name]) { + if (ext) { + self.setUploadParams(ext, name); + } + self.fileFrame[name].open(); + return; + } + + // Create the media frame. + self.fileFrame[name] = wp.media({ + library: { + type: [...mime.split(','), mime.split(',').join('')] + }, + title: $el.data('box_title'), + button: { + text: $el.data('box_action') + }, + multiple: false + }); + + // When an file is selected, run a callback. + self.fileFrame[name].on('select', function () { + // We set multiple to false so only get one image from the uploader + const attachment = self.fileFrame[name].state().get('selection').first().toJSON(); + // Do something with attachment.id and/or attachment.url here + jQuery(self.fileId).val(attachment.id); + jQuery(self.fileUrl).val(attachment.url); + self.replaceButtonClass(el); + self.updatePreview(el); + }); + self.fileFrame[name].on('open', () => { + const selectedId = this.fileId.val(); + if (!selectedId) { + return; + } + const selection = self.fileFrame[name].state().get('selection'); + selection.add(wp.media.attachment(selectedId)); + }); + self.setUploadMimeType(self.fileFrame[name], ext); + + // Finally, open the modal + self.fileFrame[name].open(); + if (ext) { + self.setUploadParams(ext, name); + } + }, + updatePreview(el) { + const self = this, + $ul = jQuery(el).parent().find('ul'), + $li = jQuery('
  • '), + showUrlType = jQuery(el).data('preview_anchor') || 'full'; + $ul.html(''); + if (self.hasValue() && 'none' !== showUrlType) { + let anchor = jQuery(self.fileUrl).val(); + if ('full' !== showUrlType) { + anchor = anchor.substring(anchor.lastIndexOf('/') + 1); + } + $li.html('' + anchor + ''); + $ul.append($li); + } + }, + setup() { + const self = this; + jQuery(self.selectors.uploadBtn + ', ' + self.selectors.clearBtn).each(function () { + self.setFields(jQuery(this)); + self.updatePreview(jQuery(this)); + self.setLabels(jQuery(this)); + self.replaceButtonClass(jQuery(this)); + }); + }, + getPostId() { + return jQuery('#post_ID').val(); + }, + handleUploadClick(event) { + event.preventDefault(); + const $element = jQuery(event.target); + if ('text' === $element.attr('type')) { + return $element.next().removeClass(this.selectors.clearBtnClass).addClass(this.selectors.uploadBtnClass).trigger('click'); + } + this.$btn = $element; + this.setFields($element); + this.uploadFile($element); + }, + init() { + const self = this, + { + uploadBtn, + inputURLField, + clearBtn + } = this.selectors, + handleUpload = event => this.handleUploadClick(event); + jQuery(document).on('click', uploadBtn, handleUpload); + jQuery(document).on('click', inputURLField, event => { + if ('' !== event.target.value) { + handleUpload(event); + } + }); + jQuery(document).on('click', clearBtn, function (event) { + event.preventDefault(); + const $element = jQuery(this); + self.setFields($element); + jQuery(self.fileUrl).val(''); + jQuery(self.fileId).val(''); + self.updatePreview($element); + self.replaceButtonClass($element); + }); + this.setup(); + jQuery(document).on('onRepeaterNewRow', function () { + self.setup(); + }); + } +}; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/font-awesome-pro.js": +/*!*********************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/font-awesome-pro.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.ViewModule { + getDefaultSettings() { + return { + selectors: { + button: '#elementor_pro_fa_pro_validate_button', + kitIdField: '#elementor_font_awesome_pro_kit_id' + } + }; + } + getDefaultElements() { + const elements = {}; + const selectors = this.getSettings('selectors'); + jQuery.each(selectors, (element, selector) => { + elements['$' + element] = jQuery(selector); + }); + return elements; + } + bindEvents() { + const { + $button, + $kitIdField + } = this.elements; + $button.on('click', event => { + event.preventDefault(); + this.testKitUrl(); + }); + $kitIdField.on('change', () => { + this.setState('clear'); + }); + } + setState(type) { + const classes = ['loading', 'success', 'error'], + { + $button + } = this.elements; + let currentClass, classIndex; + for (classIndex in classes) { + currentClass = classes[classIndex]; + if (type === currentClass) { + $button.addClass(currentClass); + } else { + $button.removeClass(currentClass); + } + } + } + testKitUrl() { + this.setState('loading'); + const self = this, + kitID = this.elements.$kitIdField.val(); + if ('' === kitID) { + this.setState('clear'); + return; + } + jQuery.ajax({ + url: 'https://kit.fontawesome.com/' + kitID + '.js', + method: 'GET', + complete: xhr => { + if (200 !== xhr.status) { + self.setState('error'); + } else { + self.setState('success'); + } + } + }); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/admin/typekit.js": +/*!************************************************************!*\ + !*** ../modules/assets-manager/assets/js/admin/typekit.js ***! + \************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function () { + var self = this; + self.cacheElements = function () { + this.cache = { + $button: jQuery('#elementor_pro_typekit_validate_button'), + $kitIdField: jQuery('#elementor_typekit-kit-id'), + $dataLabelSpan: jQuery('.elementor-pro-typekit-data') + }; + }; + self.bindEvents = function () { + this.cache.$button.on('click', function (event) { + event.preventDefault(); + self.fetchFonts(); + }); + this.cache.$kitIdField.on('change', function () { + self.setState('clear'); + }); + }; + self.fetchFonts = function () { + this.setState('loading'); + this.cache.$dataLabelSpan.addClass('hidden'); + var kitID = this.cache.$kitIdField.val(); + if ('' === kitID) { + this.setState('clear'); + return; + } + jQuery.post(ajaxurl, { + action: 'elementor_pro_admin_fetch_fonts', + kit_id: kitID, + _nonce: self.cache.$button.data('nonce') + }).done(function (data) { + if (data.success) { + var template = self.cache.$button.data('found'); + template = template.replace('{{count}}', data.data.count); + self.cache.$dataLabelSpan.html(template).removeClass('hidden'); + self.setState('success'); + } else { + self.setState('error'); + } + }).fail(function () { + self.setState(); + }); + }; + self.setState = function (type) { + var classes = ['loading', 'success', 'error'], + currentClass, + classIndex; + for (classIndex in classes) { + currentClass = classes[classIndex]; + if (type === currentClass) { + this.cache.$button.addClass(currentClass); + } else { + this.cache.$button.removeClass(currentClass); + } + } + }; + self.init = function () { + this.cacheElements(); + this.bindEvents(); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/forms/assets/js/admin.js": +/*!*******************************************!*\ + !*** ../modules/forms/assets/js/admin.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = function () { + var ApiValidations = __webpack_require__(/*! ./admin/api-validations */ "../modules/forms/assets/js/admin/api-validations.js"); + this.dripButton = new ApiValidations('drip_api_token'); + this.getResponse = new ApiValidations('getresponse_api_key'); + this.convertKit = new ApiValidations('convertkit_api_key'); + this.mailChimp = new ApiValidations('mailchimp_api_key'); + this.mailerLite = new ApiValidations('mailerlite_api_key'); + this.activeCcampaign = new ApiValidations('activecampaign_api_key', 'activecampaign_api_url'); + jQuery('.e-notice--cta.e-notice--dismissible[data-notice_id="site_mailer_forms_submissions_notice"] a.e-button--cta').on('click', function () { + elementorCommon.ajax.addRequest('elementor_site_mailer_campaign', { + data: { + source: 'sm-submission-install' + } + }); + }); + document.querySelector('.e-notice--cta.e-notice--dismissible[data-notice_id="send_app_forms_submissions_notice"] a.e-button--cta')?.addEventListener('click', function () { + elementorCommon.ajax.addRequest('elementor_send_app_campaign', { + data: { + source: 'snd-submission-install' + } + }); + }); +}; + +/***/ }), + +/***/ "../modules/forms/assets/js/admin/api-validations.js": +/*!***********************************************************!*\ + !*** ../modules/forms/assets/js/admin/api-validations.js ***! + \***********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function (key, fieldID) { + var self = this; + self.cacheElements = function () { + this.cache = { + $button: jQuery('#elementor_pro_' + key + '_button'), + $apiKeyField: jQuery('#elementor_pro_' + key), + $apiUrlField: jQuery('#elementor_pro_' + fieldID) + }; + }; + self.bindEvents = function () { + this.cache.$button.on('click', function (event) { + event.preventDefault(); + self.validateApi(); + }); + this.cache.$apiKeyField.on('change', function () { + self.setState('clear'); + }); + }; + self.validateApi = function () { + this.setState('loading'); + var apiKey = this.cache.$apiKeyField.val(); + if ('' === apiKey) { + this.setState('clear'); + return; + } + if (this.cache.$apiUrlField.length && '' === this.cache.$apiUrlField.val()) { + this.setState('clear'); + return; + } + jQuery.post(ajaxurl, { + action: self.cache.$button.data('action'), + api_key: apiKey, + api_url: this.cache.$apiUrlField.val(), + _nonce: self.cache.$button.data('nonce') + }).done(function (data) { + if (data.success) { + self.setState('success'); + } else { + self.setState('error'); + } + }).fail(function () { + self.setState(); + }); + }; + self.setState = function (type) { + var classes = ['loading', 'success', 'error'], + currentClass, + classIndex; + for (classIndex in classes) { + currentClass = classes[classIndex]; + if (type === currentClass) { + this.cache.$button.addClass(currentClass); + } else { + this.cache.$button.removeClass(currentClass); + } + } + }; + self.init = function () { + this.cacheElements(); + this.bindEvents(); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/library/assets/js/admin.js": +/*!*********************************************!*\ + !*** ../modules/library/assets/js/admin.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = function () { + var EditButton = __webpack_require__(/*! ./admin/edit-button */ "../modules/library/assets/js/admin/edit-button.js"); + this.editButton = new EditButton(); +}; + +/***/ }), + +/***/ "../modules/library/assets/js/admin/edit-button.js": +/*!*********************************************************!*\ + !*** ../modules/library/assets/js/admin/edit-button.js ***! + \*********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function () { + var self = this; + self.init = function () { + jQuery(document).on('change', '.elementor-widget-template-select', function () { + var $this = jQuery(this), + templateID = $this.val(), + $editButton = $this.parents('p').find('.elementor-edit-template'), + type = $this.find('[value="' + templateID + '"]').data('type'); + if ('page' !== type) { + // 'widget' is editable only from Elementor page + $editButton.hide(); + return; + } + var editUrl = elementorAdmin.config.home_url + '?p=' + templateID + '&elementor'; + $editButton.prop('href', editUrl).show(); + }); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/payments/assets/js/admin.js": +/*!**********************************************!*\ + !*** ../modules/payments/assets/js/admin.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = function () { + const ApiValidations = __webpack_require__(/*! ./admin/api-validations */ "../modules/payments/assets/js/admin/api-validations.js"); + this.stripeTestSecretKey = new ApiValidations('stripe_test_secret_key'); + this.stripeLiveSecretKey = new ApiValidations('stripe_live_secret_key'); +}; + +/***/ }), + +/***/ "../modules/payments/assets/js/admin/api-validations.js": +/*!**************************************************************!*\ + !*** ../modules/payments/assets/js/admin/api-validations.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function (key) { + var self = this; + self.cacheElements = function () { + this.cache = { + $button: jQuery('#elementor_pro_' + key + '_button'), + $apiKeyField: jQuery('#elementor_pro_' + key) + }; + }; + self.bindEvents = function () { + this.cache.$button.on('click', function (event) { + event.preventDefault(); + self.validateApi(); + }); + this.cache.$apiKeyField.on('change', function () { + self.setState('clear'); + }); + }; + self.validateApi = function () { + this.setState('loading'); + var apiKey = this.cache.$apiKeyField.val(); + if ('' === apiKey) { + this.setState('clear'); + return; + } + jQuery.post(ajaxurl, { + action: self.cache.$button.data('action'), + secret_key: apiKey, + _nonce: self.cache.$button.data('nonce') + }).done(function (data) { + if (data.success) { + self.setState('success'); + } else { + self.setState('error'); + } + }).fail(function () { + self.setState(); + }); + }; + self.setState = function (type) { + var classes = ['loading', 'success', 'error'], + currentClass, + classIndex; + for (classIndex in classes) { + currentClass = classes[classIndex]; + if (type === currentClass) { + this.cache.$button.addClass(currentClass); + } else { + this.cache.$button.removeClass(currentClass); + } + } + }; + self.init = function () { + this.cacheElements(); + this.bindEvents(); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/popup/assets/js/admin/admin.js": +/*!*************************************************!*\ + !*** ../modules/popup/assets/js/admin/admin.js ***! + \*************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.Module { + constructor() { + super(); + if (!elementorModules.admin?.MenuHandler) { + return; + } + new elementorModules.admin.MenuHandler({ + path: 'edit.php?post_type=elementor_library&tabs_group=popup&elementor_library_type=popup' + }); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/role-manager/assets/js/admin.js": +/*!**************************************************!*\ + !*** ../modules/role-manager/assets/js/admin.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = function () { + var AdvancedRoleManager = __webpack_require__(/*! ./admin/role-mananger */ "../modules/role-manager/assets/js/admin/role-mananger.js"); + this.advancedRoleManager = new AdvancedRoleManager(); +}; + +/***/ }), + +/***/ "../modules/role-manager/assets/js/admin/role-mananger.js": +/*!****************************************************************!*\ + !*** ../modules/role-manager/assets/js/admin/role-mananger.js ***! + \****************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function () { + var self = this; + self.cacheElements = function () { + this.cache = { + $checkBox: jQuery('input[name="elementor_exclude_user_roles[]"]'), + $advanced: jQuery('#elementor_advanced_role_manager') + }; + }; + self.bindEvents = function () { + this.cache.$checkBox.on('change', function (event) { + event.preventDefault(); + self.checkBoxUpdate(jQuery(this)); + }); + }; + self.checkBoxUpdate = function ($element) { + var role = $element.val(); + if ($element.is(':checked')) { + self.cache.$advanced.find('div.' + role).addClass('hidden'); + } else { + self.cache.$advanced.find('div.' + role).removeClass('hidden'); + } + }; + self.init = function () { + if (!jQuery('body').hasClass('elementor_page_elementor-role-manager')) { + return; + } + this.cacheElements(); + this.bindEvents(); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/admin/admin.js": +/*!*********************************************************!*\ + !*** ../modules/theme-builder/assets/js/admin/admin.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = function () { + var CreateTemplateDialog = __webpack_require__(/*! ./create-template-dialog */ "../modules/theme-builder/assets/js/admin/create-template-dialog.js"); + this.createTemplateDialog = new CreateTemplateDialog(); +}; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/admin/create-template-dialog.js": +/*!**************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/admin/create-template-dialog.js ***! + \**************************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function () { + var selectors = { + templateTypeInput: '#elementor-new-template__form__template-type', + locationWrapper: '#elementor-new-template__form__location__wrapper', + postTypeWrapper: '#elementor-new-template__form__post-type__wrapper' + }; + var elements = { + $templateTypeInput: null, + $locationWrapper: null, + $postTypeWrapper: null + }; + var setElements = function () { + jQuery.each(selectors, function (key, selector) { + key = '$' + key; + elements[key] = elementorNewTemplate.layout.getModal().getElements('content').find(selector); + }); + }; + var setLocationFieldVisibility = function () { + elements.$locationWrapper.toggle('section' === elements.$templateTypeInput.val()); + elements.$postTypeWrapper.toggle('single' === elements.$templateTypeInput.val()); + }; + const setPostType = () => { + const postTypeMap = { + 'error-404': 'not_found404' + }; + const postType = postTypeMap[elements.$templateTypeInput.val()] || ''; + elements.$postTypeWrapper.find('select').val(postType); + }; + var run = function () { + setElements(); + setLocationFieldVisibility(); + elements.$templateTypeInput.on('change', () => { + setLocationFieldVisibility(); + setPostType(); + }); + }; + this.init = function () { + if (!window.elementorNewTemplate) { + return; + } + + // Make sure the modal has already been initialized + elementorNewTemplate.layout.getModal(); + run(); + }; + jQuery(setTimeout.bind(window, this.init)); +}; + +/***/ }), + +/***/ "@wordpress/i18n": +/*!**************************!*\ + !*** external "wp.i18n" ***! + \**************************/ +/***/ ((module) => { + +"use strict"; +module.exports = wp.i18n; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js": +/*!***********************************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! + \***********************************************************************/ +/***/ ((module) => { + +function _interopRequireDefault(e) { + return e && e.__esModule ? e : { + "default": e + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!***************************************!*\ + !*** ../assets/dev/js/admin/admin.js ***! + \***************************************/ + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _admin = _interopRequireDefault(__webpack_require__(/*! modules/popup/assets/js/admin/admin */ "../modules/popup/assets/js/admin/admin.js")); +var _admin2 = _interopRequireDefault(__webpack_require__(/*! ../../../../license/assets/js/admin */ "../license/assets/js/admin.js")); +const modules = { + widget_template_edit_button: __webpack_require__(/*! modules/library/assets/js/admin */ "../modules/library/assets/js/admin.js"), + forms_integrations: __webpack_require__(/*! modules/forms/assets/js/admin */ "../modules/forms/assets/js/admin.js"), + AssetsManager: __webpack_require__(/*! modules/assets-manager/assets/js/admin */ "../modules/assets-manager/assets/js/admin.js"), + RoleManager: __webpack_require__(/*! modules/role-manager/assets/js/admin */ "../modules/role-manager/assets/js/admin.js"), + ThemeBuilder: __webpack_require__(/*! modules/theme-builder/assets/js/admin/admin */ "../modules/theme-builder/assets/js/admin/admin.js"), + StripeIntegration: __webpack_require__(/*! modules/payments/assets/js/admin */ "../modules/payments/assets/js/admin.js"), + License: _admin2.default +}; +window.elementorProAdmin = { + widget_template_edit_button: new modules.widget_template_edit_button(), + forms_integrations: new modules.forms_integrations(), + assetsManager: new modules.AssetsManager(), + roleManager: new modules.RoleManager(), + themeBuilder: new modules.ThemeBuilder(), + StripeIntegration: new modules.StripeIntegration(), + popup: new _admin.default(), + license: new modules.License() +}; +jQuery(function () { + elementorProAdmin.roleManager.advancedRoleManager.init(); +}); +})(); + +/******/ })() +; +//# sourceMappingURL=admin.js.map \ No newline at end of file diff --git a/assets/js/admin.min.js b/assets/js/admin.min.js new file mode 100644 index 00000000..b91baadf --- /dev/null +++ b/assets/js/admin.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +(()=>{var e={5310:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class Module extends elementorModules.Module{#e=[{href:"elementor_pro_renew_license_menu_link",external_url:"https://go.elementor.com/wp-menu-renew/"},{href:"elementor_pro_upgrade_license_menu_link",external_url:"https://go.elementor.com/go-pro-advanced-elementor-menu/"}];onInit(){this.assignMenuItemActions(),this.assignProLicenseActivateEvent()}assignMenuItemActions(){window.addEventListener("DOMContentLoaded",(()=>{this.#e.forEach((e=>{const t=document.querySelector(`a[href="${e.href}"]`);t&&t.addEventListener("click",(t=>{t.preventDefault(),window.open(e.external_url,"_blank")}))}))}))}assignProLicenseActivateEvent(){window.addEventListener("DOMContentLoaded",(()=>{const e=document.querySelector('.button-primary[href*="elementor-connect"]');e&&e.addEventListener("click",(()=>{if(!window.elementorCommon?.config?.experimentalFeatures?.editor_events)return;const e=window.elementorCommon?.eventsManager||{},t=e.dispatchEvent?.bind(e);t?.("pro_license_activate",{app_type:"editor",location:"Elementor WP-admin pages",secondaryLocation:"license page",trigger:"click"})}))}))}}t.default=Module},9376:(e,t,s)=>{"use strict";var n=s(6784),o=n(s(5640)),i=n(s(7959));e.exports=function(){const e=s(6036),t=i.default,n=s(2106).A;this.fontManager=new o.default,this.typekit=new e,this.fontAwesomePro=new n,this.customIcons=new t}},7796:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class CustomAssetsBase extends elementorModules.ViewModule{showAlertDialog(e,t,s=!1,n=!1){const o={id:e,message:t};s&&(o.onConfirm=s),n&&(o.onHide=n),this.alertWidget||(this.alertWidget=elementorCommon.dialogsManager.createWidget("alert",o)),this.alertWidget.show()}onDialogDismiss(){this.elements.$publishButton.removeClass("disabled"),this.elements.$publishButtonSpinner.removeClass("is-active")}handleSubmit(e){if(this.fileWasUploaded)return;return this.checkInputsForValues()?(this.fileWasUploaded=!0,void this.elements.$postForm.trigger("submit")):(e.preventDefault(),this.showAlertDialog("noData",this.getSettings("notice"),(()=>this.onDialogDismiss()),(()=>this.onDialogDismiss())),!1)}bindEvents(){this.elements.$postForm.on("submit",this.handleSubmit.bind(this))}}t.default=CustomAssetsBase},7959:(e,t,s)=>{"use strict";var n=s(2470).__,o=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=o(s(7796)),a=o(s(4484));class CustomIcons extends i.default{getDefaultSettings(){return{fields:{dropzone:a.default},classes:{editPageClass:"post-type-elementor_icons",editPhp:"edit-php",hasIcons:"elementor--has-icons"},selectors:{editPageClass:"post-type-elementor_icons",title:"#title",metaboxContainer:"#elementor-custom-icons-metabox",metabox:".elementor-custom-icons-metabox",closeHandle:"button.handlediv",iconsTemplate:"#elementor-icons-template",dataInput:"#elementor_custom_icon_set_config",dropzone:".zip_upload",submitDelete:".submitdelete",dayInput:"#hidden_jj",mmInput:"#hidden_mm",yearInput:"#hidden_aa",hourInput:"#hidden_hh",minuteInput:"#hidden_mn",publishButton:"#publish",publishButtonSpinner:"#publishing-action > .spinner",submitMetabox:"#postbox-container-1",postForm:"#post",fileInput:"#zip_upload",iconSetConfigInput:"#elementor_custom_icon_set_config"},templates:{icon:'
  • {{label}}
  • ',header:jQuery("#elementor-custom-icons-template-header").html(),footer:jQuery("#elementor-custom-icons-template-footer").html(),duplicatePrefix:jQuery("#elementor-custom-icons-template-duplicate-prefix").html()},notice:n("Upload an icon set to publish.","elementor-pro")}}getDefaultElements(){const e={},t=this.getSettings("selectors");return jQuery.each(t,((t,s)=>{e["$"+t]=jQuery(s)})),e}bindEvents(){super.bindEvents(),""!==this.getData()&&this.bindOnTitleChange()}bindOnTitleChange(){const{$title:e}=this.elements;e.on("input change",(e=>this.onTitleInput(e)))}removeCloseHandle(){const{$metaboxContainer:e}=this.elements;e.find("h2").remove(),e.find("button").remove(),e.removeClass("closed").removeClass("postbox")}prepareIconName(e){const t=e.replace("_"," ").replace("-"," ");return elementorCommon.helpers.upperCaseWords(t)}getCreatedOn(){const{$dayInput:e,$mmInput:t,$yearInput:s,$hourInput:n,$minuteInput:o}=this.elements;return{day:e.val(),mm:t.val(),year:s.val(),hour:n.val(),minute:o.val()}}enqueueCSS(e){elementorCommon.elements.$document.find('link[href="'+e+'"]').length||elementorCommon.elements.$document.find("link").last().after('')}setData(e){this.elements.$dataInput.val(JSON.stringify(e))}getData(){const e=this.elements.$dataInput.val();return""===e?"":JSON.parse(e)}renderIconList(e){const t=this.getSettings("templates.icon");return e.icons.map((s=>{const n={icon:e.displayPrefix+" "+e.prefix+s,label:this.prepareIconName(s)};return elementorCommon.compileTemplate(t,n)})).join("\n")}renderIcons(e){const{$metaboxContainer:t,$metabox:s,$submitMetabox:n}=this.elements,{header:o,footer:i}=this.getSettings("templates");t.addClass(this.getSettings("classes.hasIcons")),n.show(),this.setData(e),this.enqueueCSS(e.url),s.html(""),t.prepend(elementorCommon.compileTemplate(o,e)),s.append("
      "+this.renderIconList(e)+"
    "),t.append(elementorCommon.compileTemplate(i,this.getCreatedOn()))}onTitleInput(e){const t=this.getData();t.label=e.target.value,this.setData(t)}checkInputsForValues(){return""!==this.elements.$fileInput.val()||""!==this.elements.$iconSetConfigInput.val()}onSuccess(e){if(e.data.errors){let t,s;return jQuery.each(e.data.errors,((e,n)=>(t=e,s=n,!1))),this.showAlertDialog(t,s)}if(e.data.config.duplicate_prefix)return delete e.data.config.duplicatePrefix,this.showAlertDialog("duplicate-prefix",this.getSettings("templates.duplicatePrefix"),(()=>this.saveInitialUpload(e.data.config)));this.saveInitialUpload(e.data.config)}saveInitialUpload(e){this.setData(e);const{$publishButton:t,$title:s,$submitMetabox:n}=this.elements;n.show(),""===s.val()&&s.val(e.name),this.fileWasUploaded=!0,t.trigger("click")}onInit(){const{$body:e}=elementorCommon.elements,{editPageClass:t,editPhp:s}=this.getSettings("classes");if(!e.hasClass(t)||e.hasClass(s))return;super.onInit(),this.removeCloseHandle();const n=new(this.getSettings("fields.dropzone")),o=this.getData(),{$dropzone:i,$metaboxContainer:a}=this.elements;""===o?(i.show("fast"),n.setSettings("onSuccess",((...e)=>this.onSuccess(...e)))):this.renderIcons(o),a.show("fast")}}t.default=CustomIcons},5640:(e,t,s)=>{"use strict";var n=s(2470).__,o=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=o(s(7796)),a=o(s(1149)),r=o(s(3643));class CustomFontsManager extends i.default{getDefaultSettings(){return{fields:{upload:a.default,repeater:r.default},selectors:{editPageClass:"post-type-elementor_font",title:"#title",repeaterBlock:".repeater-block",repeaterTitle:".repeater-title",removeRowBtn:".remove-repeater-row",editRowBtn:".toggle-repeater-row",closeRowBtn:".close-repeater-row",styleInput:".font_style",weightInput:".font_weight",customFontsMetaBox:"#elementor-font-custommetabox",closeHandle:"button.handlediv",toolbar:".elementor-field-toolbar",inlinePreview:".inline-preview",fileUrlInput:'.elementor-field-file input[type="text"]',postForm:"#post",publishButton:"#publish",publishButtonSpinner:"#publishing-action > .spinner"},notice:n("Choose a font to publish.","elementor-pro"),fontLabelTemplate:'
    • {{weight}}
    • {{style}}
    • {{preview}}
    • {{toolbar}}
    '}}getDefaultElements(){const e=this.getSettings("selectors");return{$postForm:jQuery(e.postForm),$publishButton:jQuery(e.publishButton),$publishButtonSpinner:jQuery(e.publishButtonSpinner),$closeHandle:jQuery(e.closeHandle),$customFontsMetaBox:jQuery(e.customFontsMetaBox),$title:jQuery(e.title)}}renderTemplate(e,t){const s=/{{([^}}]+)?}}/g;let n;for(;n=s.exec(e);)e=e.replace(n[0],t[n[1]]);return e}ucFirst(e){return e.charAt(0).toUpperCase()+e.slice(1)}getPreviewStyle(e){const t=this.getSettings("selectors"),s=this.elements.$title.val(),n=e.find("select"+t.styleInput).first().val(),o=e.find("select"+t.weightInput).first().val();return{style:this.ucFirst(n),weight:this.ucFirst(o),styleAttribute:"font-family: "+s+" ;font-style: "+n+"; font-weight: "+o+";"}}updateRowLabel(e,t){const s=this.getSettings("selectors"),n=this.getSettings("fontLabelTemplate"),o=t.closest(s.repeaterBlock),i=o.find(s.removeRowBtn).first(),a=o.find(s.editRowBtn).first(),r=o.find(s.closeRowBtn).first(),l=t.find(s.toolbar).last().clone(),c=this.getPreviewStyle(t);a.length>0&&a.not(s.toolbar+" "+s.editRowBtn).remove(),r.length>0&&r.not(s.toolbar+" "+s.closeRowBtn).remove(),i.length>0&&i.not(s.toolbar+" "+s.removeRowBtn).remove();const u=jQuery('
  • ').append(l)[0].outerHTML;return this.renderTemplate(n,{weight:'Weight:'+c.weight,style:'Style:'+c.style,preview:'Elementor is making the web beautiful',toolbar:u})}onRepeaterToggleVisible(e,t,s){const n=this.getSettings("selectors"),o=s.find(n.inlinePreview),i=this.getPreviewStyle(s);o.attr("style",i.styleAttribute)}onRepeaterNewRow(e,t,s){const n=this.getSettings("selectors");s.find(n.removeRowBtn).first().remove(),s.find(n.editRowBtn).first().remove(),s.find(n.closeRowBtn).first().remove()}maybeToggle(e){e.preventDefault();const t=this.getSettings("selectors");jQuery(this).is(":visible")&&!jQuery(e.target).hasClass(t.editRowBtn)&&jQuery(this).find(t.editRowBtn).trigger("click")}onInputChange(e){const t=jQuery(e.target).next(),s=this.getSettings("fields");s.upload.setFields(t),s.upload.setLabels(t),s.upload.replaceButtonClass(t)}bindEvents(){const e=this.getSettings("selectors");jQuery(document).on("repeaterComputedLabel",this.updateRowLabel.bind(this)).on("onRepeaterToggleVisible",this.onRepeaterToggleVisible.bind(this)).on("onRepeaterNewRow",this.onRepeaterNewRow.bind(this)).on("click",e.repeaterTitle,this.maybeToggle.bind(this)).on("input",e.fileUrlInput,this.onInputChange.bind(this)),super.bindEvents()}checkInputsForValues(){const e=this.getSettings("selectors");let t=!1;return jQuery(e.fileUrlInput).each(((e,s)=>{if(""!==jQuery(s).val())return t=!0,!1})),t}removeCloseHandle(){this.elements.$closeHandle.remove(),this.elements.$customFontsMetaBox.removeClass("closed").removeClass("postbox")}titleRequired(){this.elements.$title.prop("required",!0)}onInit(...e){const t=this.getSettings();if(!jQuery("body").hasClass(t.selectors.editPageClass))return;super.onInit(...e),this.removeCloseHandle(),this.titleRequired(),t.fields.upload.init(),t.fields.repeater.init();const s=jQuery(document),n=this.markMetaboxIfVariableFont.bind(this);jQuery("#add-variable-font").on("click",(()=>{jQuery(document).one("onRepeaterNewRow",((e,t,s)=>{s.find('input[name$="font_type]"]').val("variable"),n()})),jQuery("#elementor-font-custommetabox").find(".add-repeater-row").trigger("click")})),s.on("onRepeaterNewRow",n),s.on("onRepeaterRemoveRow",n),s.on("change",'input[name$="variable_width]"], input[name$="variable_weight]"]',this.onFontVariableTypeChange),n()}markMetaboxIfVariableFont(){const e=jQuery('input[name$="font_type]"]'),t=jQuery(".elementor-metabox-content");if(t.removeClass("has-font-variable has-font-static"),!e.length)return;const s="variable"===e.val();s?t.addClass("has-font-variable",s):t.addClass("has-font-static"),jQuery('input[name$="variable_width]"], input[name$="variable_weight]"]').each(this.onFontVariableTypeChange)}onFontVariableTypeChange(){const e=jQuery(this);e.parents().eq(1).toggleClass("e-font-variable-hidden",!e.is(":checked"))}}t.default=CustomFontsManager},4484:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class DropZoneField extends elementorModules.ViewModule{getDefaultSettings(){const e=".elementor-dropzone-field";return{droppedFiles:!1,selectors:{dropZone:e,input:e+' [type="file"]',label:e+"label",errorMsg:e+".box__error span",restart:e+".box__restart",browseButton:e+" .elementor--dropzone--upload__browse",postId:"#post_ID"},classes:{drag:"is-dragover",error:"is-error",success:"is-success",upload:"is-uploading"},onSuccess:null,onError:null}}getDefaultElements(){const e={},t=this.getSettings("selectors");return jQuery.each(t,((t,s)=>{e["$"+t]=jQuery(s)})),e}bindEvents(){const{$dropZone:e,$browseButton:t,$input:s}=this.elements,{drag:n}=this.getSettings("classes");t.on("click",(()=>s.trigger("click"))),e.on("drag dragstart dragend dragover dragenter dragleave drop",(e=>{e.preventDefault(),e.stopPropagation()})).on("dragover dragenter",(()=>{e.addClass(n)})).on("dragleave dragend drop",(()=>{e.removeClass(n)})).on("drop change",(e=>{"change"===e.type?this.setSettings("droppedFiles",e.originalEvent.target.files):this.setSettings("droppedFiles",e.originalEvent.dataTransfer.files),this.handleUpload()}))}handleUpload(){const e=this.getSettings("droppedFiles");if(!e)return;const{$input:t,$dropZone:s,$postId:n,$errorMsg:o}=this.elements,{error:i,success:a,upload:r}=this.getSettings("classes"),{onSuccess:l,onError:c}=this.getSettings(),u=new FormData,d=t.attr("name"),p="pro_assets_manager_custom_icon_upload",m=this;Object.entries(e).forEach((e=>{u.append(d,e[1])})),u.append("actions",JSON.stringify({pro_assets_manager_custom_icon_upload:{action:p,data:{post_id:n.val()}}})),s.removeClass(a).removeClass(i),elementorCommon.ajax.send("ajax",{data:u,cache:!1,enctype:"multipart/form-data",contentType:!1,processData:!1,complete:()=>{s.removeClass(r)},success:e=>{const t=e.responses[p];s.addClass(t.success?a:i),t.success?l&&l(t,m):(o.text(t.error),c&&c(m,arguments))},error:()=>{"function"==typeof c&&c(m,arguments)}})}onInit(){super.onInit(),elementorCommon.elements.$document.trigger("onDropzoneLoaded",[this])}}t.default=DropZoneField},3643:e=>{"use strict";e.exports={selectors:{add:".add-repeater-row",remove:".remove-repeater-row",toggle:".toggle-repeater-row",close:".close-repeater-row",sort:".sort-repeater-row",table:".form-table",block:".repeater-block",repeaterLabel:".repeater-title",repeaterField:".elementor-field-repeater"},counters:[],trigger(e,t){jQuery(document).trigger(e,t)},triggerHandler:(e,t)=>jQuery(document).triggerHandler(e,t),countBlocks(e){return e.closest(this.selectors.repeaterField).find(this.selectors.block).length||0},add(e){var t,s=this,n=jQuery(e),o=n.data("template-id");Object.prototype.hasOwnProperty.call(s.counters,o)||(s.counters[o]=s.countBlocks(n)),s.counters[o]+=1,t=jQuery("#"+o).html(),t=s.replaceAll("__counter__",s.counters[o],t),n.before(t),s.trigger("onRepeaterNewRow",[n,n.prev()])},remove(e){jQuery(e).closest(this.selectors.block).remove(),this.trigger("onRepeaterRemoveRow",[e])},toggle(e){var t=this,s=jQuery(e),n=s.closest(t.selectors.block).find(t.selectors.table),o=s.closest(t.selectors.block).find(t.selectors.repeaterLabel);n.toggle(0,(function(){n.is(":visible")?(n.closest(t.selectors.block).addClass("block-visible"),t.trigger("onRepeaterToggleVisible",[s,n,o])):(n.closest(t.selectors.block).removeClass("block-visible"),t.trigger("onRepeaterToggleHidden",[s,n,o]))})),o.toggle(),t.updateRowLabel(e)},close(e){var t=this,s=jQuery(e),n=s.closest(t.selectors.block).find(t.selectors.table),o=s.closest(t.selectors.block).find(t.selectors.repeaterLabel);n.closest(t.selectors.block).removeClass("block-visible"),n.hide(),t.trigger("onRepeaterToggleHidden",[s,n,o]),o.show(),t.updateRowLabel(e)},updateRowLabel(e){var t=this,s=jQuery(e),n=s.closest(t.selectors.block).find(t.selectors.table),o=s.closest(t.selectors.block).find(t.selectors.repeaterLabel),i=o.data("selector");if(void 0!==i&&!1!==i){var a=!1,r=o.data("default");n.find(i).length&&(a=n.find(i).val());var l=t.triggerHandler("repeaterComputedLabel",[n,o,a]);void 0!==l&&!1!==l&&(a=l),void 0!==a&&!1!==a||(a=r),o.html(a)}},replaceAll:(e,t,s)=>s.replace(new RegExp(e,"g"),t),init(){var e=this;jQuery(document).on("click",this.selectors.add,(function(t){t.preventDefault(),e.add(jQuery(this),t)})).on("click",this.selectors.remove,(function(t){t.preventDefault(),confirm(jQuery(this).data("confirm").toString())&&e.remove(jQuery(this),t)})).on("click",this.selectors.toggle,(function(t){t.preventDefault(),t.stopPropagation(),e.toggle(jQuery(this),t)})).on("click",this.selectors.close,(function(t){t.preventDefault(),t.stopPropagation(),e.close(jQuery(this),t)})),jQuery(this.selectors.toggle).each((function(){e.updateRowLabel(jQuery(this))})),this.trigger("onRepeaterLoaded",[this])}}},1149:e=>{"use strict";e.exports={$btn:null,fileId:null,fileUrl:null,fileFrame:[],selectors:{uploadBtnClass:"elementor-upload-btn",clearBtnClass:"elementor-upload-clear-btn",uploadBtn:".elementor-upload-btn",clearBtn:".elementor-upload-clear-btn",inputURLField:'.elementor-field-file input[type="text"]'},hasValue(){return""!==jQuery(this.fileUrl).val()},setLabels(e){this.hasValue()?e.val(e.data("remove_text")):e.val(e.data("upload_text"))},setFields(e){const t=this;t.fileUrl=jQuery(e).prev(),t.fileId=jQuery(t.fileUrl).prev()},setUploadParams(e,t){const s=this.fileFrame[t].uploader.uploader;s.param("uploadType",e),s.param("uploadTypeCaller","elementor-admin-font-upload"),s.param("post_id",this.getPostId())},setUploadMimeType(e,t){const s=_wpPluploadSettings.defaults.filters.mime_types[0].extensions,n=this;e.on("ready",(()=>{_wpPluploadSettings.defaults.filters.mime_types[0].extensions=t})),e.on("close",(()=>{_wpPluploadSettings.defaults.filters.mime_types[0].extensions=s,n.replaceButtonClass(n.$btn)}))},replaceButtonClass(e){this.hasValue()?jQuery(e).removeClass(this.selectors.uploadBtnClass).addClass(this.selectors.clearBtnClass):jQuery(e).removeClass(this.selectors.clearBtnClass).addClass(this.selectors.uploadBtnClass),this.setLabels(e)},uploadFile(e){const t=this,s=jQuery(e),n=s.attr("data-mime_type")||"",o=s.attr("data-ext")||!1,i=s.attr("id");if(void 0!==t.fileFrame[i])return o&&t.setUploadParams(o,i),void t.fileFrame[i].open();t.fileFrame[i]=wp.media({library:{type:[...n.split(","),n.split(",").join("")]},title:s.data("box_title"),button:{text:s.data("box_action")},multiple:!1}),t.fileFrame[i].on("select",(function(){const s=t.fileFrame[i].state().get("selection").first().toJSON();jQuery(t.fileId).val(s.id),jQuery(t.fileUrl).val(s.url),t.replaceButtonClass(e),t.updatePreview(e)})),t.fileFrame[i].on("open",(()=>{const e=this.fileId.val();if(!e)return;t.fileFrame[i].state().get("selection").add(wp.media.attachment(e))})),t.setUploadMimeType(t.fileFrame[i],o),t.fileFrame[i].open(),o&&t.setUploadParams(o,i)},updatePreview(e){const t=this,s=jQuery(e).parent().find("ul"),n=jQuery("
  • "),o=jQuery(e).data("preview_anchor")||"full";if(s.html(""),t.hasValue()&&"none"!==o){let e=jQuery(t.fileUrl).val();"full"!==o&&(e=e.substring(e.lastIndexOf("/")+1)),n.html(''+e+""),s.append(n)}},setup(){const e=this;jQuery(e.selectors.uploadBtn+", "+e.selectors.clearBtn).each((function(){e.setFields(jQuery(this)),e.updatePreview(jQuery(this)),e.setLabels(jQuery(this)),e.replaceButtonClass(jQuery(this))}))},getPostId:()=>jQuery("#post_ID").val(),handleUploadClick(e){e.preventDefault();const t=jQuery(e.target);if("text"===t.attr("type"))return t.next().removeClass(this.selectors.clearBtnClass).addClass(this.selectors.uploadBtnClass).trigger("click");this.$btn=t,this.setFields(t),this.uploadFile(t)},init(){const e=this,{uploadBtn:t,inputURLField:s,clearBtn:n}=this.selectors,handleUpload=e=>this.handleUploadClick(e);jQuery(document).on("click",t,handleUpload),jQuery(document).on("click",s,(e=>{""!==e.target.value&&handleUpload(e)})),jQuery(document).on("click",n,(function(t){t.preventDefault();const s=jQuery(this);e.setFields(s),jQuery(e.fileUrl).val(""),jQuery(e.fileId).val(""),e.updatePreview(s),e.replaceButtonClass(s)})),this.setup(),jQuery(document).on("onRepeaterNewRow",(function(){e.setup()}))}}},2106:(e,t)=>{"use strict";t.A=void 0;class _default extends elementorModules.ViewModule{getDefaultSettings(){return{selectors:{button:"#elementor_pro_fa_pro_validate_button",kitIdField:"#elementor_font_awesome_pro_kit_id"}}}getDefaultElements(){const e={},t=this.getSettings("selectors");return jQuery.each(t,((t,s)=>{e["$"+t]=jQuery(s)})),e}bindEvents(){const{$button:e,$kitIdField:t}=this.elements;e.on("click",(e=>{e.preventDefault(),this.testKitUrl()})),t.on("change",(()=>{this.setState("clear")}))}setState(e){const t=["loading","success","error"],{$button:s}=this.elements;let n,o;for(o in t)n=t[o],e===n?s.addClass(n):s.removeClass(n)}testKitUrl(){this.setState("loading");const e=this,t=this.elements.$kitIdField.val();""!==t?jQuery.ajax({url:"https://kit.fontawesome.com/"+t+".js",method:"GET",complete:t=>{200!==t.status?e.setState("error"):e.setState("success")}}):this.setState("clear")}}t.A=_default},6036:e=>{"use strict";e.exports=function(){var e=this;e.cacheElements=function(){this.cache={$button:jQuery("#elementor_pro_typekit_validate_button"),$kitIdField:jQuery("#elementor_typekit-kit-id"),$dataLabelSpan:jQuery(".elementor-pro-typekit-data")}},e.bindEvents=function(){this.cache.$button.on("click",(function(t){t.preventDefault(),e.fetchFonts()})),this.cache.$kitIdField.on("change",(function(){e.setState("clear")}))},e.fetchFonts=function(){this.setState("loading"),this.cache.$dataLabelSpan.addClass("hidden");var t=this.cache.$kitIdField.val();""!==t?jQuery.post(ajaxurl,{action:"elementor_pro_admin_fetch_fonts",kit_id:t,_nonce:e.cache.$button.data("nonce")}).done((function(t){if(t.success){var s=e.cache.$button.data("found");s=s.replace("{{count}}",t.data.count),e.cache.$dataLabelSpan.html(s).removeClass("hidden"),e.setState("success")}else e.setState("error")})).fail((function(){e.setState()})):this.setState("clear")},e.setState=function(e){var t,s,n=["loading","success","error"];for(s in n)e===(t=n[s])?this.cache.$button.addClass(t):this.cache.$button.removeClass(t)},e.init=function(){this.cacheElements(),this.bindEvents()},e.init()}},1128:(e,t,s)=>{"use strict";e.exports=function(){var e=s(2390);this.dripButton=new e("drip_api_token"),this.getResponse=new e("getresponse_api_key"),this.convertKit=new e("convertkit_api_key"),this.mailChimp=new e("mailchimp_api_key"),this.mailerLite=new e("mailerlite_api_key"),this.activeCcampaign=new e("activecampaign_api_key","activecampaign_api_url"),jQuery('.e-notice--cta.e-notice--dismissible[data-notice_id="site_mailer_forms_submissions_notice"] a.e-button--cta').on("click",(function(){elementorCommon.ajax.addRequest("elementor_site_mailer_campaign",{data:{source:"sm-submission-install"}})})),document.querySelector('.e-notice--cta.e-notice--dismissible[data-notice_id="send_app_forms_submissions_notice"] a.e-button--cta')?.addEventListener("click",(function(){elementorCommon.ajax.addRequest("elementor_send_app_campaign",{data:{source:"snd-submission-install"}})}))}},2390:e=>{"use strict";e.exports=function(e,t){var s=this;s.cacheElements=function(){this.cache={$button:jQuery("#elementor_pro_"+e+"_button"),$apiKeyField:jQuery("#elementor_pro_"+e),$apiUrlField:jQuery("#elementor_pro_"+t)}},s.bindEvents=function(){this.cache.$button.on("click",(function(e){e.preventDefault(),s.validateApi()})),this.cache.$apiKeyField.on("change",(function(){s.setState("clear")}))},s.validateApi=function(){this.setState("loading");var e=this.cache.$apiKeyField.val();""!==e?this.cache.$apiUrlField.length&&""===this.cache.$apiUrlField.val()?this.setState("clear"):jQuery.post(ajaxurl,{action:s.cache.$button.data("action"),api_key:e,api_url:this.cache.$apiUrlField.val(),_nonce:s.cache.$button.data("nonce")}).done((function(e){e.success?s.setState("success"):s.setState("error")})).fail((function(){s.setState()})):this.setState("clear")},s.setState=function(e){var t,s,n=["loading","success","error"];for(s in n)e===(t=n[s])?this.cache.$button.addClass(t):this.cache.$button.removeClass(t)},s.init=function(){this.cacheElements(),this.bindEvents()},s.init()}},408:(e,t,s)=>{"use strict";e.exports=function(){var e=s(4196);this.editButton=new e}},4196:e=>{"use strict";e.exports=function(){this.init=function(){jQuery(document).on("change",".elementor-widget-template-select",(function(){var e=jQuery(this),t=e.val(),s=e.parents("p").find(".elementor-edit-template");if("page"===e.find('[value="'+t+'"]').data("type")){var n=elementorAdmin.config.home_url+"?p="+t+"&elementor";s.prop("href",n).show()}else s.hide()}))},this.init()}},1564:(e,t,s)=>{"use strict";e.exports=function(){const e=s(2602);this.stripeTestSecretKey=new e("stripe_test_secret_key"),this.stripeLiveSecretKey=new e("stripe_live_secret_key")}},2602:e=>{"use strict";e.exports=function(e){var t=this;t.cacheElements=function(){this.cache={$button:jQuery("#elementor_pro_"+e+"_button"),$apiKeyField:jQuery("#elementor_pro_"+e)}},t.bindEvents=function(){this.cache.$button.on("click",(function(e){e.preventDefault(),t.validateApi()})),this.cache.$apiKeyField.on("change",(function(){t.setState("clear")}))},t.validateApi=function(){this.setState("loading");var e=this.cache.$apiKeyField.val();""!==e?jQuery.post(ajaxurl,{action:t.cache.$button.data("action"),secret_key:e,_nonce:t.cache.$button.data("nonce")}).done((function(e){e.success?t.setState("success"):t.setState("error")})).fail((function(){t.setState()})):this.setState("clear")},t.setState=function(e){var t,s,n=["loading","success","error"];for(s in n)e===(t=n[s])?this.cache.$button.addClass(t):this.cache.$button.removeClass(t)},t.init=function(){this.cacheElements(),this.bindEvents()},t.init()}},6553:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class _default extends elementorModules.Module{constructor(){super(),elementorModules.admin?.MenuHandler&&new elementorModules.admin.MenuHandler({path:"edit.php?post_type=elementor_library&tabs_group=popup&elementor_library_type=popup"})}}t.default=_default},7093:(e,t,s)=>{"use strict";e.exports=function(){var e=s(774);this.advancedRoleManager=new e}},774:e=>{"use strict";e.exports=function(){var e=this;e.cacheElements=function(){this.cache={$checkBox:jQuery('input[name="elementor_exclude_user_roles[]"]'),$advanced:jQuery("#elementor_advanced_role_manager")}},e.bindEvents=function(){this.cache.$checkBox.on("change",(function(t){t.preventDefault(),e.checkBoxUpdate(jQuery(this))}))},e.checkBoxUpdate=function(t){var s=t.val();t.is(":checked")?e.cache.$advanced.find("div."+s).addClass("hidden"):e.cache.$advanced.find("div."+s).removeClass("hidden")},e.init=function(){jQuery("body").hasClass("elementor_page_elementor-role-manager")&&(this.cacheElements(),this.bindEvents())},e.init()}},7488:(e,t,s)=>{"use strict";e.exports=function(){var e=s(5231);this.createTemplateDialog=new e}},5231:e=>{"use strict";e.exports=function(){var e={templateTypeInput:"#elementor-new-template__form__template-type",locationWrapper:"#elementor-new-template__form__location__wrapper",postTypeWrapper:"#elementor-new-template__form__post-type__wrapper"},t={$templateTypeInput:null,$locationWrapper:null,$postTypeWrapper:null},setLocationFieldVisibility=function(){t.$locationWrapper.toggle("section"===t.$templateTypeInput.val()),t.$postTypeWrapper.toggle("single"===t.$templateTypeInput.val())};var run=function(){jQuery.each(e,(function(e,s){t[e="$"+e]=elementorNewTemplate.layout.getModal().getElements("content").find(s)})),setLocationFieldVisibility(),t.$templateTypeInput.on("change",(()=>{setLocationFieldVisibility(),(()=>{const e={"error-404":"not_found404"}[t.$templateTypeInput.val()]||"";t.$postTypeWrapper.find("select").val(e)})()}))};this.init=function(){window.elementorNewTemplate&&(elementorNewTemplate.layout.getModal(),run())},jQuery(setTimeout.bind(window,this.init))}},2470:e=>{"use strict";e.exports=wp.i18n},6784:e=>{e.exports=function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports}},t={};function __webpack_require__(s){var n=t[s];if(void 0!==n)return n.exports;var o=t[s]={exports:{}};return e[s](o,o.exports,__webpack_require__),o.exports}(()=>{"use strict";var e=__webpack_require__(6784),t=e(__webpack_require__(6553)),s=e(__webpack_require__(5310));const n={widget_template_edit_button:__webpack_require__(408),forms_integrations:__webpack_require__(1128),AssetsManager:__webpack_require__(9376),RoleManager:__webpack_require__(7093),ThemeBuilder:__webpack_require__(7488),StripeIntegration:__webpack_require__(1564),License:s.default};window.elementorProAdmin={widget_template_edit_button:new n.widget_template_edit_button,forms_integrations:new n.forms_integrations,assetsManager:new n.AssetsManager,roleManager:new n.RoleManager,themeBuilder:new n.ThemeBuilder,StripeIntegration:new n.StripeIntegration,popup:new t.default,license:new n.License},jQuery((function(){elementorProAdmin.roleManager.advancedRoleManager.init()}))})()})(); \ No newline at end of file diff --git a/assets/js/ajax-pagination.2090b5f4906bcda1dcc2.bundle.min.js b/assets/js/ajax-pagination.2090b5f4906bcda1dcc2.bundle.min.js new file mode 100644 index 00000000..ef89b53b --- /dev/null +++ b/assets/js/ajax-pagination.2090b5f4906bcda1dcc2.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[550],{4734:(e,t,n)=>{var s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=s(n(4921)),r=s(n(5012));class AjaxPagination extends elementorModules.frontend.handlers.Base{getDefaultSettings(){return{selectors:{links:"a.page-numbers:not(.current)",widgetContainer:".elementor-widget-container",postWrapperTag:".e-loop-item"}}}getDefaultElements(){const e=this.getSettings("selectors");return{links:this.$element[0].querySelectorAll(e.links),widgetContainer:this.$element[0].querySelector(e.widgetContainer)}}bindEvents(){super.bindEvents(),this.linksEventListeners()}linksEventListeners(){this.elements.links.length&&"ajax"===this.getElementSettings("pagination_load_type")&&this.elements.links.forEach((e=>{e.addEventListener("click",(e=>{this.handleLinkClick(e)}))}))}handleLinkClick(e){if(e.preventDefault(),this.isLoading)return;this.removeLinksListeners(),this.handleUiBeforeLoading();const t=e?.target.getAttribute("href");return this.updateURLQueryString(t),fetch(t).then((e=>e.text())).then((e=>{const t=(new DOMParser).parseFromString(e,"text/html");this.handleSuccessFetch(t)}))}removeLinksListeners(){this.elements.links.length&&this.elements.links.forEach((e=>{e.removeEventListener("click",this.handleLinkClick)}))}updateURLQueryString(e){const t=new URL(window.location.href),n=t.searchParams,s=new URL(e).searchParams;s.forEach(((e,t)=>{n.set(t,e)})),s.has("e-page-"+this.elementId)||n.delete("e-page-"+this.elementId),history.pushState(null,"",t.href)}handleUiBeforeLoading(){this.setLoading(!0),this.ajaxHelper.addLoadingAnimationOverlay(this.elementId),this.maybeScrollToTop()}setLoading(e){this.isLoading=e}maybeScrollToTop(){if("yes"!==this.getElementSettings("auto_scroll"))return;const e=document.querySelector(`.elementor-element-${this.elementId}`);e&&e.scrollIntoView({behavior:"smooth"})}handleUiAfterLoading(){this.setLoading(!1),this.ajaxHelper.removeLoadingAnimationOverlay(this.elementId)}handleSuccessFetch(e){this.handleUiAfterLoading();const t=this.getSettings("selectors"),n=e.querySelector(`[data-id="${this.elementId}"] ${t.widgetContainer}`),s=this.elements.widgetContainer;this.$element[0].replaceChild(n,s),this.afterInsertPosts()}afterInsertPosts(){const e=this.getSettings("selectors"),t=document.querySelectorAll(`[data-id="${this.elementId}"] ${e.postWrapperTag}`);elementorFrontend.elementsHandler.runReadyTrigger(this.$element[0]),(0,r.default)(t),ElementorProFrontendConfig.settings.lazy_load_background_images&&document.dispatchEvent(new Event("elementor/lazyload/observe"))}onInit(){super.onInit(),this.setLoading(!1),this.elementId=this.getID(),this.ajaxHelper=new i.default}}t.default=AjaxPagination}}]); \ No newline at end of file diff --git a/assets/js/ajax-pagination.2390838f542f1a8d5ed4.bundle.js b/assets/js/ajax-pagination.2390838f542f1a8d5ed4.bundle.js new file mode 100644 index 00000000..59ce1a47 --- /dev/null +++ b/assets/js/ajax-pagination.2390838f542f1a8d5ed4.bundle.js @@ -0,0 +1,146 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["ajax-pagination"],{ + +/***/ "../modules/loop-builder/assets/js/frontend/handlers/ajax-pagination.js": +/*!******************************************************************************!*\ + !*** ../modules/loop-builder/assets/js/frontend/handlers/ajax-pagination.js ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _ajaxHelper = _interopRequireDefault(__webpack_require__(/*! elementor-pro/frontend/utils/ajax-helper */ "../assets/dev/js/frontend/utils/ajax-helper.js")); +var _runElementHandlers = _interopRequireDefault(__webpack_require__(/*! elementor-pro/frontend/utils/run-element-handlers */ "../assets/dev/js/frontend/utils/run-element-handlers.js")); +class AjaxPagination extends elementorModules.frontend.handlers.Base { + getDefaultSettings() { + return { + selectors: { + links: 'a.page-numbers:not(.current)', + widgetContainer: '.elementor-widget-container', + postWrapperTag: '.e-loop-item' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + links: this.$element[0].querySelectorAll(selectors.links), + widgetContainer: this.$element[0].querySelector(selectors.widgetContainer) + }; + } + bindEvents() { + super.bindEvents(); + this.linksEventListeners(); + } + linksEventListeners() { + if (!this.elements.links.length) { + return; + } + if ('ajax' !== this.getElementSettings('pagination_load_type')) { + return; + } + this.elements.links.forEach(link => { + link.addEventListener('click', event => { + this.handleLinkClick(event); + }); + }); + } + handleLinkClick(event) { + event.preventDefault(); + if (this.isLoading) { + return; + } + this.removeLinksListeners(); + this.handleUiBeforeLoading(); + const nextPageUrl = event?.target.getAttribute('href'); + this.updateURLQueryString(nextPageUrl); + return fetch(nextPageUrl).then(response => response.text()).then(html => { + // Convert the HTML string into a document object + const parser = new DOMParser(); + const doc = parser.parseFromString(html, 'text/html'); + this.handleSuccessFetch(doc); + }); + } + removeLinksListeners() { + if (!this.elements.links.length) { + return; + } + this.elements.links.forEach(link => { + link.removeEventListener('click', this.handleLinkClick); + }); + } + updateURLQueryString(nextPageUrl) { + const currentUrl = new URL(window.location.href); + const currentParams = currentUrl.searchParams; + const targetUrl = new URL(nextPageUrl); + const targetParams = targetUrl.searchParams; + targetParams.forEach((value, key) => { + currentParams.set(key, value); + }); + + // Clicked on page 1. + if (!targetParams.has('e-page-' + this.elementId)) { + currentParams.delete('e-page-' + this.elementId); + } + history.pushState(null, '', currentUrl.href); + } + handleUiBeforeLoading() { + this.setLoading(true); + this.ajaxHelper.addLoadingAnimationOverlay(this.elementId); + this.maybeScrollToTop(); + } + setLoading(loadng) { + this.isLoading = loadng; + } + maybeScrollToTop() { + if ('yes' !== this.getElementSettings('auto_scroll')) { + return; + } + const widget = document.querySelector(`.elementor-element-${this.elementId}`); + if (!widget) { + return; + } + widget.scrollIntoView({ + behavior: 'smooth' + }); + } + handleUiAfterLoading() { + this.setLoading(false); + this.ajaxHelper.removeLoadingAnimationOverlay(this.elementId); + } + handleSuccessFetch(result) { + this.handleUiAfterLoading(); + const selectors = this.getSettings('selectors'); + const newWidgetContainer = result.querySelector(`[data-id="${this.elementId}"] ${selectors.widgetContainer}`); + const existingWidgetContainer = this.elements.widgetContainer; + this.$element[0].replaceChild(newWidgetContainer, existingWidgetContainer); + this.afterInsertPosts(); + } + afterInsertPosts() { + const selectors = this.getSettings('selectors'), + postsElements = document.querySelectorAll(`[data-id="${this.elementId}"] ${selectors.postWrapperTag}`); + elementorFrontend.elementsHandler.runReadyTrigger(this.$element[0]); + (0, _runElementHandlers.default)(postsElements); + if (ElementorProFrontendConfig.settings.lazy_load_background_images) { + document.dispatchEvent(new Event('elementor/lazyload/observe')); + } + } + onInit() { + super.onInit(); + this.setLoading(false); + this.elementId = this.getID(); + this.ajaxHelper = new _ajaxHelper.default(); + } +} +exports["default"] = AjaxPagination; + +/***/ }) + +}]); +//# sourceMappingURL=ajax-pagination.2390838f542f1a8d5ed4.bundle.js.map \ No newline at end of file diff --git a/assets/js/animated-headline.32baaa2ad2ea939224d5.bundle.js b/assets/js/animated-headline.32baaa2ad2ea939224d5.bundle.js new file mode 100644 index 00000000..542a031a --- /dev/null +++ b/assets/js/animated-headline.32baaa2ad2ea939224d5.bundle.js @@ -0,0 +1,299 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["animated-headline"],{ + +/***/ "../modules/animated-headline/assets/js/frontend/handlers/animated-headlines.js": +/*!**************************************************************************************!*\ + !*** ../modules/animated-headline/assets/js/frontend/handlers/animated-headlines.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = exports["default"] = elementorModules.frontend.handlers.Base.extend({ + svgPaths: { + circle: ['M325,18C228.7-8.3,118.5,8.3,78,21C22.4,38.4,4.6,54.6,5.6,77.6c1.4,32.4,52.2,54,142.6,63.7 c66.2,7.1,212.2,7.5,273.5-8.3c64.4-16.6,104.3-57.6,33.8-98.2C386.7-4.9,179.4-1.4,126.3,20.7'], + underline_zigzag: ['M9.3,127.3c49.3-3,150.7-7.6,199.7-7.4c121.9,0.4,189.9,0.4,282.3,7.2C380.1,129.6,181.2,130.6,70,139 c82.6-2.9,254.2-1,335.9,1.3c-56,1.4-137.2-0.3-197.1,9'], + x: ['M497.4,23.9C301.6,40,155.9,80.6,4,144.4', 'M14.1,27.6c204.5,20.3,393.8,74,467.3,111.7'], + strikethrough: ['M3,75h493.5'], + curly: ['M3,146.1c17.1-8.8,33.5-17.8,51.4-17.8c15.6,0,17.1,18.1,30.2,18.1c22.9,0,36-18.6,53.9-18.6 c17.1,0,21.3,18.5,37.5,18.5c21.3,0,31.8-18.6,49-18.6c22.1,0,18.8,18.8,36.8,18.8c18.8,0,37.5-18.6,49-18.6c20.4,0,17.1,19,36.8,19 c22.9,0,36.8-20.6,54.7-18.6c17.7,1.4,7.1,19.5,33.5,18.8c17.1,0,47.2-6.5,61.1-15.6'], + diagonal: ['M13.5,15.5c131,13.7,289.3,55.5,475,125.5'], + double: ['M8.4,143.1c14.2-8,97.6-8.8,200.6-9.2c122.3-0.4,287.5,7.2,287.5,7.2', 'M8,19.4c72.3-5.3,162-7.8,216-7.8c54,0,136.2,0,267,7.8'], + double_underline: ['M5,125.4c30.5-3.8,137.9-7.6,177.3-7.6c117.2,0,252.2,4.7,312.7,7.6', 'M26.9,143.8c55.1-6.1,126-6.3,162.2-6.1c46.5,0.2,203.9,3.2,268.9,6.4'], + underline: ['M7.7,145.6C109,125,299.9,116.2,401,121.3c42.1,2.2,87.6,11.8,87.3,25.7'] + }, + getDefaultSettings() { + const iterationDelay = this.getElementSettings('rotate_iteration_delay'), + settings = { + animationDelay: iterationDelay || 2500, + // Letters effect + lettersDelay: iterationDelay * 0.02 || 50, + // Typing effect + typeLettersDelay: iterationDelay * 0.06 || 150, + selectionDuration: iterationDelay * 0.2 || 500, + // Clip effect + revealDuration: iterationDelay * 0.24 || 600, + revealAnimationDelay: iterationDelay * 0.6 || 1500, + // Highlighted headline + highlightAnimationDuration: this.getElementSettings('highlight_animation_duration') || 1200, + highlightAnimationDelay: this.getElementSettings('highlight_iteration_delay') || 8000 + }; + settings.typeAnimationDelay = settings.selectionDuration + 800; + settings.selectors = { + headline: '.elementor-headline', + dynamicWrapper: '.elementor-headline-dynamic-wrapper', + dynamicText: '.elementor-headline-dynamic-text' + }; + settings.classes = { + dynamicText: 'elementor-headline-dynamic-text', + dynamicLetter: 'elementor-headline-dynamic-letter', + textActive: 'elementor-headline-text-active', + textInactive: 'elementor-headline-text-inactive', + letters: 'elementor-headline-letters', + animationIn: 'elementor-headline-animation-in', + typeSelected: 'elementor-headline-typing-selected', + activateHighlight: 'e-animated', + hideHighlight: 'e-hide-highlight' + }; + return settings; + }, + getDefaultElements() { + var selectors = this.getSettings('selectors'); + return { + $headline: this.$element.find(selectors.headline), + $dynamicWrapper: this.$element.find(selectors.dynamicWrapper), + $dynamicText: this.$element.find(selectors.dynamicText) + }; + }, + getNextWord($word) { + return $word.is(':last-child') ? $word.parent().children().eq(0) : $word.next(); + }, + switchWord($oldWord, $newWord) { + $oldWord.removeClass('elementor-headline-text-active').addClass('elementor-headline-text-inactive'); + $newWord.removeClass('elementor-headline-text-inactive').addClass('elementor-headline-text-active'); + this.setDynamicWrapperWidth($newWord); + }, + singleLetters() { + var classes = this.getSettings('classes'); + this.elements.$dynamicText.each(function () { + var $word = jQuery(this), + letters = $word.text().split(''), + isActive = $word.hasClass(classes.textActive); + $word.empty(); + letters.forEach(function (letter) { + var $letter = jQuery('', { + class: classes.dynamicLetter + }).text(letter); + if (isActive) { + $letter.addClass(classes.animationIn); + } + $word.append($letter); + }); + $word.css('opacity', 1); + }); + }, + showLetter($letter, $word, bool, duration) { + var self = this, + classes = this.getSettings('classes'); + $letter.addClass(classes.animationIn); + if (!$letter.is(':last-child')) { + setTimeout(function () { + self.showLetter($letter.next(), $word, bool, duration); + }, duration); + } else if (!bool) { + setTimeout(function () { + self.hideWord($word); + }, self.getSettings('animationDelay')); + } + }, + hideLetter($letter, $word, bool, duration) { + var self = this, + settings = this.getSettings(); + $letter.removeClass(settings.classes.animationIn); + if (!$letter.is(':last-child')) { + setTimeout(function () { + self.hideLetter($letter.next(), $word, bool, duration); + }, duration); + } else if (bool) { + setTimeout(function () { + self.hideWord(self.getNextWord($word)); + }, self.getSettings('animationDelay')); + } + }, + showWord($word, $duration) { + var self = this, + settings = self.getSettings(), + animationType = self.getElementSettings('animation_type'); + if ('typing' === animationType) { + self.showLetter($word.find('.' + settings.classes.dynamicLetter).eq(0), $word, false, $duration); + $word.addClass(settings.classes.textActive).removeClass(settings.classes.textInactive); + } else if ('clip' === animationType) { + self.elements.$dynamicWrapper.animate({ + width: $word.width() + 10 + }, settings.revealDuration, function () { + setTimeout(function () { + self.hideWord($word); + }, settings.revealAnimationDelay); + }); + } + }, + hideWord($word) { + var self = this, + settings = self.getSettings(), + classes = settings.classes, + letterSelector = '.' + classes.dynamicLetter; + if (!this.isLoopMode && $word.is(':last-child')) { + return; + } + var animationType = self.getElementSettings('animation_type'), + nextWord = self.getNextWord($word); + if ('typing' === animationType) { + self.elements.$dynamicWrapper.addClass(classes.typeSelected); + setTimeout(function () { + self.elements.$dynamicWrapper.removeClass(classes.typeSelected); + $word.addClass(settings.classes.textInactive).removeClass(classes.textActive).children(letterSelector).removeClass(classes.animationIn); + }, settings.selectionDuration); + setTimeout(function () { + self.showWord(nextWord, settings.typeLettersDelay); + }, settings.typeAnimationDelay); + } else if (self.elements.$headline.hasClass(classes.letters)) { + var bool = $word.children(letterSelector).length >= nextWord.children(letterSelector).length; + self.hideLetter($word.find(letterSelector).eq(0), $word, bool, settings.lettersDelay); + self.showLetter(nextWord.find(letterSelector).eq(0), nextWord, bool, settings.lettersDelay); + self.setDynamicWrapperWidth(nextWord); + } else if ('clip' === animationType) { + self.elements.$dynamicWrapper.animate({ + width: '2px' + }, settings.revealDuration, function () { + self.switchWord($word, nextWord); + self.showWord(nextWord); + }); + } else { + self.switchWord($word, nextWord); + setTimeout(function () { + self.hideWord(nextWord); + }, settings.animationDelay); + } + }, + setDynamicWrapperWidth($word) { + const animationType = this.getElementSettings('animation_type'); + if ('clip' !== animationType && 'typing' !== animationType) { + this.elements.$dynamicWrapper.css('width', $word.width()); + } + }, + animateHeadline() { + var self = this, + animationType = self.getElementSettings('animation_type'), + $dynamicWrapper = self.elements.$dynamicWrapper; + if ('clip' === animationType) { + $dynamicWrapper.width($dynamicWrapper.width() + 10); + } else if ('typing' !== animationType) { + self.setDynamicWrapperWidth(self.elements.$dynamicText); + } + + // Trigger animation + setTimeout(function () { + self.hideWord(self.elements.$dynamicText.eq(0)); + }, self.getSettings('animationDelay')); + }, + getSvgPaths(pathName) { + var pathsInfo = this.svgPaths[pathName], + $paths = jQuery(); + pathsInfo.forEach(function (pathInfo) { + $paths = $paths.add(jQuery('', { + d: pathInfo + })); + }); + return $paths; + }, + addHighlight() { + const elementSettings = this.getElementSettings(), + $svg = jQuery('', { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 500 150', + preserveAspectRatio: 'none', + 'aria-hidden': 'true' + }).html(this.getSvgPaths(elementSettings.marker)); + this.elements.$dynamicWrapper.append($svg[0].outerHTML); + }, + rotateHeadline() { + var settings = this.getSettings(); + + // Insert for each letter of a changing word + if (this.elements.$headline.hasClass(settings.classes.letters)) { + this.singleLetters(); + } + + // Initialise headline animation + this.animateHeadline(); + }, + initHeadline() { + const headlineStyle = this.getElementSettings('headline_style'); + if ('rotate' === headlineStyle) { + this.rotateHeadline(); + } else if ('highlight' === headlineStyle) { + this.addHighlight(); + this.activateHighlightAnimation(); + } + this.deactivateScrollListener(); + }, + activateHighlightAnimation() { + const settings = this.getSettings(), + classes = settings.classes, + $headline = this.elements.$headline; + if (!this.prefersReducedMotion) { + this.prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); + } + const prefersReducedMotion = this.prefersReducedMotion.matches; + if (prefersReducedMotion) { + $headline.addClass(classes.activateHighlight); + return; + } + $headline.removeClass(classes.hideHighlight).addClass(classes.activateHighlight); + if (!this.isLoopMode) { + return; + } + setTimeout(() => { + $headline.removeClass(classes.activateHighligh).addClass(classes.hideHighlight); + }, settings.highlightAnimationDuration + settings.highlightAnimationDelay * .8); + setTimeout(() => { + this.activateHighlightAnimation(false); + }, settings.highlightAnimationDuration + settings.highlightAnimationDelay); + }, + activateScrollListener() { + const scrollBuffer = -100; + this.intersectionObservers.startAnimation.observer = elementorModules.utils.Scroll.scrollObserver({ + offset: `0px 0px ${scrollBuffer}px`, + callback: event => { + if (event.isInViewport) { + this.initHeadline(); + } + } + }); + this.intersectionObservers.startAnimation.element = this.elements.$headline[0]; + this.intersectionObservers.startAnimation.observer.observe(this.intersectionObservers.startAnimation.element); + }, + deactivateScrollListener() { + this.intersectionObservers.startAnimation.observer.unobserve(this.intersectionObservers.startAnimation.element); + }, + onInit() { + elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments); + this.intersectionObservers = { + startAnimation: { + observer: null, + element: null + } + }; + this.isLoopMode = 'yes' === this.getElementSettings('loop'); + this.activateScrollListener(); + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=animated-headline.32baaa2ad2ea939224d5.bundle.js.map \ No newline at end of file diff --git a/assets/js/animated-headline.c009d6fa482515df23f8.bundle.min.js b/assets/js/animated-headline.c009d6fa482515df23f8.bundle.min.js new file mode 100644 index 00000000..99a6fed2 --- /dev/null +++ b/assets/js/animated-headline.c009d6fa482515df23f8.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[961],{2590:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default=elementorModules.frontend.handlers.Base.extend({svgPaths:{circle:["M325,18C228.7-8.3,118.5,8.3,78,21C22.4,38.4,4.6,54.6,5.6,77.6c1.4,32.4,52.2,54,142.6,63.7 c66.2,7.1,212.2,7.5,273.5-8.3c64.4-16.6,104.3-57.6,33.8-98.2C386.7-4.9,179.4-1.4,126.3,20.7"],underline_zigzag:["M9.3,127.3c49.3-3,150.7-7.6,199.7-7.4c121.9,0.4,189.9,0.4,282.3,7.2C380.1,129.6,181.2,130.6,70,139 c82.6-2.9,254.2-1,335.9,1.3c-56,1.4-137.2-0.3-197.1,9"],x:["M497.4,23.9C301.6,40,155.9,80.6,4,144.4","M14.1,27.6c204.5,20.3,393.8,74,467.3,111.7"],strikethrough:["M3,75h493.5"],curly:["M3,146.1c17.1-8.8,33.5-17.8,51.4-17.8c15.6,0,17.1,18.1,30.2,18.1c22.9,0,36-18.6,53.9-18.6 c17.1,0,21.3,18.5,37.5,18.5c21.3,0,31.8-18.6,49-18.6c22.1,0,18.8,18.8,36.8,18.8c18.8,0,37.5-18.6,49-18.6c20.4,0,17.1,19,36.8,19 c22.9,0,36.8-20.6,54.7-18.6c17.7,1.4,7.1,19.5,33.5,18.8c17.1,0,47.2-6.5,61.1-15.6"],diagonal:["M13.5,15.5c131,13.7,289.3,55.5,475,125.5"],double:["M8.4,143.1c14.2-8,97.6-8.8,200.6-9.2c122.3-0.4,287.5,7.2,287.5,7.2","M8,19.4c72.3-5.3,162-7.8,216-7.8c54,0,136.2,0,267,7.8"],double_underline:["M5,125.4c30.5-3.8,137.9-7.6,177.3-7.6c117.2,0,252.2,4.7,312.7,7.6","M26.9,143.8c55.1-6.1,126-6.3,162.2-6.1c46.5,0.2,203.9,3.2,268.9,6.4"],underline:["M7.7,145.6C109,125,299.9,116.2,401,121.3c42.1,2.2,87.6,11.8,87.3,25.7"]},getDefaultSettings(){const e=this.getElementSettings("rotate_iteration_delay"),t={animationDelay:e||2500,lettersDelay:.02*e||50,typeLettersDelay:.06*e||150,selectionDuration:.2*e||500,revealDuration:.24*e||600,revealAnimationDelay:.6*e||1500,highlightAnimationDuration:this.getElementSettings("highlight_animation_duration")||1200,highlightAnimationDelay:this.getElementSettings("highlight_iteration_delay")||8e3};return t.typeAnimationDelay=t.selectionDuration+800,t.selectors={headline:".elementor-headline",dynamicWrapper:".elementor-headline-dynamic-wrapper",dynamicText:".elementor-headline-dynamic-text"},t.classes={dynamicText:"elementor-headline-dynamic-text",dynamicLetter:"elementor-headline-dynamic-letter",textActive:"elementor-headline-text-active",textInactive:"elementor-headline-text-inactive",letters:"elementor-headline-letters",animationIn:"elementor-headline-animation-in",typeSelected:"elementor-headline-typing-selected",activateHighlight:"e-animated",hideHighlight:"e-hide-highlight"},t},getDefaultElements(){var e=this.getSettings("selectors");return{$headline:this.$element.find(e.headline),$dynamicWrapper:this.$element.find(e.dynamicWrapper),$dynamicText:this.$element.find(e.dynamicText)}},getNextWord:e=>e.is(":last-child")?e.parent().children().eq(0):e.next(),switchWord(e,t){e.removeClass("elementor-headline-text-active").addClass("elementor-headline-text-inactive"),t.removeClass("elementor-headline-text-inactive").addClass("elementor-headline-text-active"),this.setDynamicWrapperWidth(t)},singleLetters(){var e=this.getSettings("classes");this.elements.$dynamicText.each((function(){var t=jQuery(this),i=t.text().split(""),n=t.hasClass(e.textActive);t.empty(),i.forEach((function(i){var s=jQuery("",{class:e.dynamicLetter}).text(i);n&&s.addClass(e.animationIn),t.append(s)})),t.css("opacity",1)}))},showLetter(e,t,i,n){var s=this,a=this.getSettings("classes");e.addClass(a.animationIn),e.is(":last-child")?i||setTimeout((function(){s.hideWord(t)}),s.getSettings("animationDelay")):setTimeout((function(){s.showLetter(e.next(),t,i,n)}),n)},hideLetter(e,t,i,n){var s=this,a=this.getSettings();e.removeClass(a.classes.animationIn),e.is(":last-child")?i&&setTimeout((function(){s.hideWord(s.getNextWord(t))}),s.getSettings("animationDelay")):setTimeout((function(){s.hideLetter(e.next(),t,i,n)}),n)},showWord(e,t){var i=this,n=i.getSettings(),s=i.getElementSettings("animation_type");"typing"===s?(i.showLetter(e.find("."+n.classes.dynamicLetter).eq(0),e,!1,t),e.addClass(n.classes.textActive).removeClass(n.classes.textInactive)):"clip"===s&&i.elements.$dynamicWrapper.animate({width:e.width()+10},n.revealDuration,(function(){setTimeout((function(){i.hideWord(e)}),n.revealAnimationDelay)}))},hideWord(e){var t=this,i=t.getSettings(),n=i.classes,s="."+n.dynamicLetter;if(this.isLoopMode||!e.is(":last-child")){var a=t.getElementSettings("animation_type"),l=t.getNextWord(e);if("typing"===a)t.elements.$dynamicWrapper.addClass(n.typeSelected),setTimeout((function(){t.elements.$dynamicWrapper.removeClass(n.typeSelected),e.addClass(i.classes.textInactive).removeClass(n.textActive).children(s).removeClass(n.animationIn)}),i.selectionDuration),setTimeout((function(){t.showWord(l,i.typeLettersDelay)}),i.typeAnimationDelay);else if(t.elements.$headline.hasClass(n.letters)){var r=e.children(s).length>=l.children(s).length;t.hideLetter(e.find(s).eq(0),e,r,i.lettersDelay),t.showLetter(l.find(s).eq(0),l,r,i.lettersDelay),t.setDynamicWrapperWidth(l)}else"clip"===a?t.elements.$dynamicWrapper.animate({width:"2px"},i.revealDuration,(function(){t.switchWord(e,l),t.showWord(l)})):(t.switchWord(e,l),setTimeout((function(){t.hideWord(l)}),i.animationDelay))}},setDynamicWrapperWidth(e){const t=this.getElementSettings("animation_type");"clip"!==t&&"typing"!==t&&this.elements.$dynamicWrapper.css("width",e.width())},animateHeadline(){var e=this,t=e.getElementSettings("animation_type"),i=e.elements.$dynamicWrapper;"clip"===t?i.width(i.width()+10):"typing"!==t&&e.setDynamicWrapperWidth(e.elements.$dynamicText),setTimeout((function(){e.hideWord(e.elements.$dynamicText.eq(0))}),e.getSettings("animationDelay"))},getSvgPaths(e){var t=this.svgPaths[e],i=jQuery();return t.forEach((function(e){i=i.add(jQuery("",{d:e}))})),i},addHighlight(){const e=this.getElementSettings(),t=jQuery("",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 500 150",preserveAspectRatio:"none","aria-hidden":"true"}).html(this.getSvgPaths(e.marker));this.elements.$dynamicWrapper.append(t[0].outerHTML)},rotateHeadline(){var e=this.getSettings();this.elements.$headline.hasClass(e.classes.letters)&&this.singleLetters(),this.animateHeadline()},initHeadline(){const e=this.getElementSettings("headline_style");"rotate"===e?this.rotateHeadline():"highlight"===e&&(this.addHighlight(),this.activateHighlightAnimation()),this.deactivateScrollListener()},activateHighlightAnimation(){const e=this.getSettings(),t=e.classes,i=this.elements.$headline;this.prefersReducedMotion||(this.prefersReducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)"));this.prefersReducedMotion.matches?i.addClass(t.activateHighlight):(i.removeClass(t.hideHighlight).addClass(t.activateHighlight),this.isLoopMode&&(setTimeout((()=>{i.removeClass(t.activateHighligh).addClass(t.hideHighlight)}),e.highlightAnimationDuration+.8*e.highlightAnimationDelay),setTimeout((()=>{this.activateHighlightAnimation(!1)}),e.highlightAnimationDuration+e.highlightAnimationDelay)))},activateScrollListener(){this.intersectionObservers.startAnimation.observer=elementorModules.utils.Scroll.scrollObserver({offset:"0px 0px -100px",callback:e=>{e.isInViewport&&this.initHeadline()}}),this.intersectionObservers.startAnimation.element=this.elements.$headline[0],this.intersectionObservers.startAnimation.observer.observe(this.intersectionObservers.startAnimation.element)},deactivateScrollListener(){this.intersectionObservers.startAnimation.observer.unobserve(this.intersectionObservers.startAnimation.element)},onInit(){elementorModules.frontend.handlers.Base.prototype.onInit.apply(this,arguments),this.intersectionObservers={startAnimation:{observer:null,element:null}},this.isLoopMode="yes"===this.getElementSettings("loop"),this.activateScrollListener()}})}}]); \ No newline at end of file diff --git a/assets/js/app.js b/assets/js/app.js new file mode 100644 index 00000000..6018a292 --- /dev/null +++ b/assets/js/app.js @@ -0,0 +1,10192 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.scss": +/*!*****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.scss ***! + \*****************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/atoms/preview-iframe.scss": +/*!***************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/atoms/preview-iframe.scss ***! + \***************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/back-button.scss": +/*!****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/back-button.scss ***! + \****************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template.scss": +/*!******************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template.scss ***! + \******************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/add-new.scss": +/*!********************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/add-new.scss ***! + \********************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions.scss": +/*!**********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/conditions.scss ***! + \**********************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/template-type.scss": +/*!**************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/template-type.scss ***! + \**************************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/site-editor.scss": +/*!******************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/site-editor.scss ***! + \******************************************************************/ +/***/ (() => { + + + +/***/ }), + +/***/ "../node_modules/@reach/router/es/index.js": +/*!*************************************************!*\ + !*** ../node_modules/@reach/router/es/index.js ***! + \*************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Link: () => (/* binding */ Link), +/* harmony export */ Location: () => (/* binding */ Location), +/* harmony export */ LocationProvider: () => (/* binding */ LocationProvider), +/* harmony export */ Match: () => (/* binding */ Match), +/* harmony export */ Redirect: () => (/* binding */ Redirect), +/* harmony export */ Router: () => (/* binding */ Router), +/* harmony export */ ServerLocation: () => (/* binding */ ServerLocation), +/* harmony export */ createHistory: () => (/* reexport safe */ _lib_history__WEBPACK_IMPORTED_MODULE_5__.createHistory), +/* harmony export */ createMemorySource: () => (/* reexport safe */ _lib_history__WEBPACK_IMPORTED_MODULE_5__.createMemorySource), +/* harmony export */ globalHistory: () => (/* reexport safe */ _lib_history__WEBPACK_IMPORTED_MODULE_5__.globalHistory), +/* harmony export */ isRedirect: () => (/* binding */ isRedirect), +/* harmony export */ matchPath: () => (/* reexport safe */ _lib_utils__WEBPACK_IMPORTED_MODULE_4__.match), +/* harmony export */ navigate: () => (/* reexport safe */ _lib_history__WEBPACK_IMPORTED_MODULE_5__.navigate), +/* harmony export */ redirectTo: () => (/* binding */ redirectTo), +/* harmony export */ useLocation: () => (/* binding */ useLocation), +/* harmony export */ useMatch: () => (/* binding */ useMatch), +/* harmony export */ useNavigate: () => (/* binding */ useNavigate), +/* harmony export */ useParams: () => (/* binding */ useParams) +/* harmony export */ }); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! invariant */ "../node_modules/invariant/browser.js"); +/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(invariant__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var create_react_context__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! create-react-context */ "../node_modules/@reach/router/node_modules/create-react-context/lib/index.js"); +/* harmony import */ var create_react_context__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(create_react_context__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var react_lifecycles_compat__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-lifecycles-compat */ "../node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js"); +/* harmony import */ var _lib_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lib/utils */ "../node_modules/@reach/router/es/lib/utils.js"); +/* harmony import */ var _lib_history__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lib/history */ "../node_modules/@reach/router/es/lib/history.js"); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/* eslint-disable jsx-a11y/anchor-has-content */ + + + + + + + + +//////////////////////////////////////////////////////////////////////////////// + +var createNamedContext = function createNamedContext(name, defaultValue) { + var Ctx = create_react_context__WEBPACK_IMPORTED_MODULE_2___default()(defaultValue); + Ctx.displayName = name; + return Ctx; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Location Context/Provider +var LocationContext = createNamedContext("Location"); + +// sets up a listener if there isn't one already so apps don't need to be +// wrapped in some top level provider +var Location = function Location(_ref) { + var children = _ref.children; + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + LocationContext.Consumer, + null, + function (context) { + return context ? children(context) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + LocationProvider, + null, + children + ); + } + ); +}; + +var LocationProvider = function (_React$Component) { + _inherits(LocationProvider, _React$Component); + + function LocationProvider() { + var _temp, _this, _ret; + + _classCallCheck(this, LocationProvider); + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = { + context: _this.getContext(), + refs: { unlisten: null } + }, _temp), _possibleConstructorReturn(_this, _ret); + } + + LocationProvider.prototype.getContext = function getContext() { + var _props$history = this.props.history, + navigate = _props$history.navigate, + location = _props$history.location; + + return { navigate: navigate, location: location }; + }; + + LocationProvider.prototype.componentDidCatch = function componentDidCatch(error, info) { + if (isRedirect(error)) { + var _navigate = this.props.history.navigate; + + _navigate(error.uri, { replace: true }); + } else { + throw error; + } + }; + + LocationProvider.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { + if (prevState.context.location !== this.state.context.location) { + this.props.history._onTransitionComplete(); + } + }; + + LocationProvider.prototype.componentDidMount = function componentDidMount() { + var _this2 = this; + + var refs = this.state.refs, + history = this.props.history; + + history._onTransitionComplete(); + refs.unlisten = history.listen(function () { + Promise.resolve().then(function () { + // TODO: replace rAF with react deferred update API when it's ready https://github.com/facebook/react/issues/13306 + requestAnimationFrame(function () { + if (!_this2.unmounted) { + _this2.setState(function () { + return { context: _this2.getContext() }; + }); + } + }); + }); + }); + }; + + LocationProvider.prototype.componentWillUnmount = function componentWillUnmount() { + var refs = this.state.refs; + + this.unmounted = true; + refs.unlisten(); + }; + + LocationProvider.prototype.render = function render() { + var context = this.state.context, + children = this.props.children; + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + LocationContext.Provider, + { value: context }, + typeof children === "function" ? children(context) : children || null + ); + }; + + return LocationProvider; +}((react__WEBPACK_IMPORTED_MODULE_0___default().Component)); + +//////////////////////////////////////////////////////////////////////////////// + + +LocationProvider.defaultProps = { + history: _lib_history__WEBPACK_IMPORTED_MODULE_5__.globalHistory +}; + true ? LocationProvider.propTypes = { + history: (prop_types__WEBPACK_IMPORTED_MODULE_6___default().object).isRequired +} : 0; +var ServerLocation = function ServerLocation(_ref2) { + var url = _ref2.url, + children = _ref2.children; + + var searchIndex = url.indexOf("?"); + var searchExists = searchIndex > -1; + var pathname = void 0; + var search = ""; + var hash = ""; + + if (searchExists) { + pathname = url.substring(0, searchIndex); + search = url.substring(searchIndex); + } else { + pathname = url; + } + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + LocationContext.Provider, + { + value: { + location: { + pathname: pathname, + search: search, + hash: hash + }, + navigate: function navigate() { + throw new Error("You can't call navigate on the server."); + } + } + }, + children + ); +}; +//////////////////////////////////////////////////////////////////////////////// +// Sets baseuri and basepath for nested routers and links +var BaseContext = createNamedContext("Base", { baseuri: "/", basepath: "/" }); + +//////////////////////////////////////////////////////////////////////////////// +// The main event, welcome to the show everybody. +var Router = function Router(props) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + BaseContext.Consumer, + null, + function (baseContext) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Location, + null, + function (locationContext) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(RouterImpl, _extends({}, baseContext, locationContext, props)); + } + ); + } + ); +}; + +var RouterImpl = function (_React$PureComponent) { + _inherits(RouterImpl, _React$PureComponent); + + function RouterImpl() { + _classCallCheck(this, RouterImpl); + + return _possibleConstructorReturn(this, _React$PureComponent.apply(this, arguments)); + } + + RouterImpl.prototype.render = function render() { + var _props = this.props, + location = _props.location, + _navigate2 = _props.navigate, + basepath = _props.basepath, + primary = _props.primary, + children = _props.children, + baseuri = _props.baseuri, + _props$component = _props.component, + component = _props$component === undefined ? "div" : _props$component, + domProps = _objectWithoutProperties(_props, ["location", "navigate", "basepath", "primary", "children", "baseuri", "component"]); + + var routes = react__WEBPACK_IMPORTED_MODULE_0___default().Children.toArray(children).reduce(function (array, child) { + var routes = createRoute(basepath)(child); + return array.concat(routes); + }, []); + var pathname = location.pathname; + + + var match = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.pick)(routes, pathname); + + if (match) { + var params = match.params, + uri = match.uri, + route = match.route, + element = match.route.value; + + // remove the /* from the end for child routes relative paths + + basepath = route.default ? basepath : route.path.replace(/\*$/, ""); + + var props = _extends({}, params, { + uri: uri, + location: location, + navigate: function navigate(to, options) { + return _navigate2((0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(to, uri), options); + } + }); + + var clone = react__WEBPACK_IMPORTED_MODULE_0___default().cloneElement(element, props, element.props.children ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Router, + { location: location, primary: primary }, + element.props.children + ) : undefined); + + // using 'div' for < 16.3 support + var FocusWrapper = primary ? FocusHandler : component; + // don't pass any props to 'div' + var wrapperProps = primary ? _extends({ uri: uri, location: location, component: component }, domProps) : domProps; + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + BaseContext.Provider, + { value: { baseuri: uri, basepath: basepath } }, + react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + FocusWrapper, + wrapperProps, + clone + ) + ); + } else { + // Not sure if we want this, would require index routes at every level + // warning( + // false, + // `\n\nNothing matched:\n\t${ + // location.pathname + // }\n\nPaths checked: \n\t${routes + // .map(route => route.path) + // .join( + // "\n\t" + // )}\n\nTo get rid of this warning, add a default NotFound component as child of Router: + // \n\tlet NotFound = () =>
    Not Found!
    + // \n\t\n\t \n\t {/* ... */}\n\t` + // ); + return null; + } + }; + + return RouterImpl; +}((react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent)); + +RouterImpl.defaultProps = { + primary: true +}; + + +var FocusContext = createNamedContext("Focus"); + +var FocusHandler = function FocusHandler(_ref3) { + var uri = _ref3.uri, + location = _ref3.location, + component = _ref3.component, + domProps = _objectWithoutProperties(_ref3, ["uri", "location", "component"]); + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + FocusContext.Consumer, + null, + function (requestFocus) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(FocusHandlerImpl, _extends({}, domProps, { + component: component, + requestFocus: requestFocus, + uri: uri, + location: location + })); + } + ); +}; + +// don't focus on initial render +var initialRender = true; +var focusHandlerCount = 0; + +var FocusHandlerImpl = function (_React$Component2) { + _inherits(FocusHandlerImpl, _React$Component2); + + function FocusHandlerImpl() { + var _temp2, _this4, _ret2; + + _classCallCheck(this, FocusHandlerImpl); + + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return _ret2 = (_temp2 = (_this4 = _possibleConstructorReturn(this, _React$Component2.call.apply(_React$Component2, [this].concat(args))), _this4), _this4.state = {}, _this4.requestFocus = function (node) { + if (!_this4.state.shouldFocus && node) { + node.focus(); + } + }, _temp2), _possibleConstructorReturn(_this4, _ret2); + } + + FocusHandlerImpl.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) { + var initial = prevState.uri == null; + if (initial) { + return _extends({ + shouldFocus: true + }, nextProps); + } else { + var myURIChanged = nextProps.uri !== prevState.uri; + var navigatedUpToMe = prevState.location.pathname !== nextProps.location.pathname && nextProps.location.pathname === nextProps.uri; + return _extends({ + shouldFocus: myURIChanged || navigatedUpToMe + }, nextProps); + } + }; + + FocusHandlerImpl.prototype.componentDidMount = function componentDidMount() { + focusHandlerCount++; + this.focus(); + }; + + FocusHandlerImpl.prototype.componentWillUnmount = function componentWillUnmount() { + focusHandlerCount--; + if (focusHandlerCount === 0) { + initialRender = true; + } + }; + + FocusHandlerImpl.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { + if (prevProps.location !== this.props.location && this.state.shouldFocus) { + this.focus(); + } + }; + + FocusHandlerImpl.prototype.focus = function focus() { + if (false) {} + + var requestFocus = this.props.requestFocus; + + + if (requestFocus) { + requestFocus(this.node); + } else { + if (initialRender) { + initialRender = false; + } else if (this.node) { + // React polyfills [autofocus] and it fires earlier than cDM, + // so we were stealing focus away, this line prevents that. + if (!this.node.contains(document.activeElement)) { + this.node.focus(); + } + } + } + }; + + FocusHandlerImpl.prototype.render = function render() { + var _this5 = this; + + var _props2 = this.props, + children = _props2.children, + style = _props2.style, + requestFocus = _props2.requestFocus, + _props2$component = _props2.component, + Comp = _props2$component === undefined ? "div" : _props2$component, + uri = _props2.uri, + location = _props2.location, + domProps = _objectWithoutProperties(_props2, ["children", "style", "requestFocus", "component", "uri", "location"]); + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Comp, + _extends({ + style: _extends({ outline: "none" }, style), + tabIndex: "-1", + ref: function ref(n) { + return _this5.node = n; + } + }, domProps), + react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + FocusContext.Provider, + { value: this.requestFocus }, + this.props.children + ) + ); + }; + + return FocusHandlerImpl; +}((react__WEBPACK_IMPORTED_MODULE_0___default().Component)); + +(0,react_lifecycles_compat__WEBPACK_IMPORTED_MODULE_3__.polyfill)(FocusHandlerImpl); + +var k = function k() {}; + +//////////////////////////////////////////////////////////////////////////////// +var forwardRef = (react__WEBPACK_IMPORTED_MODULE_0___default().forwardRef); + +if (typeof forwardRef === "undefined") { + forwardRef = function forwardRef(C) { + return C; + }; +} + +var Link = forwardRef(function (_ref4, ref) { + var innerRef = _ref4.innerRef, + props = _objectWithoutProperties(_ref4, ["innerRef"]); + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + BaseContext.Consumer, + null, + function (_ref5) { + var basepath = _ref5.basepath, + baseuri = _ref5.baseuri; + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Location, + null, + function (_ref6) { + var location = _ref6.location, + navigate = _ref6.navigate; + + var to = props.to, + state = props.state, + replace = props.replace, + _props$getProps = props.getProps, + getProps = _props$getProps === undefined ? k : _props$getProps, + anchorProps = _objectWithoutProperties(props, ["to", "state", "replace", "getProps"]); + + var href = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(to, baseuri); + var encodedHref = encodeURI(href); + var isCurrent = location.pathname === encodedHref; + var isPartiallyCurrent = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.startsWith)(location.pathname, encodedHref); + + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", _extends({ + ref: ref || innerRef, + "aria-current": isCurrent ? "page" : undefined + }, anchorProps, getProps({ isCurrent: isCurrent, isPartiallyCurrent: isPartiallyCurrent, href: href, location: location }), { + href: href, + onClick: function onClick(event) { + if (anchorProps.onClick) anchorProps.onClick(event); + if (shouldNavigate(event)) { + event.preventDefault(); + var shouldReplace = replace; + if (typeof replace !== "boolean" && isCurrent) { + var _location$state = _extends({}, location.state), + key = _location$state.key, + restState = _objectWithoutProperties(_location$state, ["key"]); + + shouldReplace = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.shallowCompare)(_extends({}, state), restState); + } + navigate(href, { + state: state, + replace: shouldReplace + }); + } + } + })); + } + ); + } + ); +}); + +Link.displayName = "Link"; + + true ? Link.propTypes = { + to: (prop_types__WEBPACK_IMPORTED_MODULE_6___default().string).isRequired +} : 0; + +//////////////////////////////////////////////////////////////////////////////// +function RedirectRequest(uri) { + this.uri = uri; +} + +var isRedirect = function isRedirect(o) { + return o instanceof RedirectRequest; +}; + +var redirectTo = function redirectTo(to) { + throw new RedirectRequest(to); +}; + +var RedirectImpl = function (_React$Component3) { + _inherits(RedirectImpl, _React$Component3); + + function RedirectImpl() { + _classCallCheck(this, RedirectImpl); + + return _possibleConstructorReturn(this, _React$Component3.apply(this, arguments)); + } + + // Support React < 16 with this hook + RedirectImpl.prototype.componentDidMount = function componentDidMount() { + var _props3 = this.props, + navigate = _props3.navigate, + to = _props3.to, + from = _props3.from, + _props3$replace = _props3.replace, + replace = _props3$replace === undefined ? true : _props3$replace, + state = _props3.state, + noThrow = _props3.noThrow, + baseuri = _props3.baseuri, + props = _objectWithoutProperties(_props3, ["navigate", "to", "from", "replace", "state", "noThrow", "baseuri"]); + + Promise.resolve().then(function () { + var resolvedTo = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(to, baseuri); + navigate((0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.insertParams)(resolvedTo, props), { replace: replace, state: state }); + }); + }; + + RedirectImpl.prototype.render = function render() { + var _props4 = this.props, + navigate = _props4.navigate, + to = _props4.to, + from = _props4.from, + replace = _props4.replace, + state = _props4.state, + noThrow = _props4.noThrow, + baseuri = _props4.baseuri, + props = _objectWithoutProperties(_props4, ["navigate", "to", "from", "replace", "state", "noThrow", "baseuri"]); + + var resolvedTo = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(to, baseuri); + if (!noThrow) redirectTo((0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.insertParams)(resolvedTo, props)); + return null; + }; + + return RedirectImpl; +}((react__WEBPACK_IMPORTED_MODULE_0___default().Component)); + +var Redirect = function Redirect(props) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + BaseContext.Consumer, + null, + function (_ref7) { + var baseuri = _ref7.baseuri; + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Location, + null, + function (locationContext) { + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement(RedirectImpl, _extends({}, locationContext, { baseuri: baseuri }, props)); + } + ); + } + ); +}; + + true ? Redirect.propTypes = { + from: (prop_types__WEBPACK_IMPORTED_MODULE_6___default().string), + to: (prop_types__WEBPACK_IMPORTED_MODULE_6___default().string).isRequired +} : 0; + +//////////////////////////////////////////////////////////////////////////////// +var Match = function Match(_ref8) { + var path = _ref8.path, + children = _ref8.children; + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + BaseContext.Consumer, + null, + function (_ref9) { + var baseuri = _ref9.baseuri; + return react__WEBPACK_IMPORTED_MODULE_0___default().createElement( + Location, + null, + function (_ref10) { + var navigate = _ref10.navigate, + location = _ref10.location; + + var resolvedPath = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(path, baseuri); + var result = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.match)(resolvedPath, location.pathname); + return children({ + navigate: navigate, + location: location, + match: result ? _extends({}, result.params, { + uri: result.uri, + path: path + }) : null + }); + } + ); + } + ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// Hooks + +var useLocation = function useLocation() { + var context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(LocationContext); + + if (!context) { + throw new Error("useLocation hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router"); + } + + return context.location; +}; + +var useNavigate = function useNavigate() { + var context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(LocationContext); + + if (!context) { + throw new Error("useNavigate hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router"); + } + + return context.navigate; +}; + +var useParams = function useParams() { + var context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(BaseContext); + + if (!context) { + throw new Error("useParams hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router"); + } + + var location = useLocation(); + + var results = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.match)(context.basepath, location.pathname); + + return results ? results.params : null; +}; + +var useMatch = function useMatch(path) { + if (!path) { + throw new Error("useMatch(path: string) requires an argument of a string to match against"); + } + var context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(BaseContext); + + if (!context) { + throw new Error("useMatch hook was used but a LocationContext.Provider was not found in the parent tree. Make sure this is used in a component that is a child of Router"); + } + + var location = useLocation(); + + var resolvedPath = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.resolve)(path, context.baseuri); + var result = (0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.match)(resolvedPath, location.pathname); + return result ? _extends({}, result.params, { + uri: result.uri, + path: path + }) : null; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Junk +var stripSlashes = function stripSlashes(str) { + return str.replace(/(^\/+|\/+$)/g, ""); +}; + +var createRoute = function createRoute(basepath) { + return function (element) { + if (!element) { + return null; + } + + if (element.type === (react__WEBPACK_IMPORTED_MODULE_0___default().Fragment) && element.props.children) { + return react__WEBPACK_IMPORTED_MODULE_0___default().Children.map(element.props.children, createRoute(basepath)); + } + !(element.props.path || element.props.default || element.type === Redirect) ? true ? invariant__WEBPACK_IMPORTED_MODULE_1___default()(false, ": Children of must have a `path` or `default` prop, or be a ``. None found on element type `" + element.type + "`") : 0 : void 0; + + !!(element.type === Redirect && (!element.props.from || !element.props.to)) ? true ? invariant__WEBPACK_IMPORTED_MODULE_1___default()(false, " requires both \"from\" and \"to\" props when inside a .") : 0 : void 0; + + !!(element.type === Redirect && !(0,_lib_utils__WEBPACK_IMPORTED_MODULE_4__.validateRedirect)(element.props.from, element.props.to)) ? true ? invariant__WEBPACK_IMPORTED_MODULE_1___default()(false, " has mismatched dynamic segments, ensure both paths have the exact same dynamic segments.") : 0 : void 0; + + if (element.props.default) { + return { value: element, default: true }; + } + + var elementPath = element.type === Redirect ? element.props.from : element.props.path; + + var path = elementPath === "/" ? basepath : stripSlashes(basepath) + "/" + stripSlashes(elementPath); + + return { + value: element, + default: element.props.default, + path: element.props.children ? stripSlashes(path) + "/*" : path + }; + }; +}; + +var shouldNavigate = function shouldNavigate(event) { + return !event.defaultPrevented && event.button === 0 && !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); +}; + +//////////////////////////////////////////////////////////////////////// + + +/***/ }), + +/***/ "../node_modules/@reach/router/es/lib/history.js": +/*!*******************************************************!*\ + !*** ../node_modules/@reach/router/es/lib/history.js ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ createHistory: () => (/* binding */ createHistory), +/* harmony export */ createMemorySource: () => (/* binding */ createMemorySource), +/* harmony export */ globalHistory: () => (/* binding */ globalHistory), +/* harmony export */ navigate: () => (/* binding */ navigate) +/* harmony export */ }); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var getLocation = function getLocation(source) { + var _source$location = source.location, + search = _source$location.search, + hash = _source$location.hash, + href = _source$location.href, + origin = _source$location.origin, + protocol = _source$location.protocol, + host = _source$location.host, + hostname = _source$location.hostname, + port = _source$location.port; + var pathname = source.location.pathname; + + + if (!pathname && href && canUseDOM) { + var url = new URL(href); + pathname = url.pathname; + } + + return { + pathname: encodeURI(decodeURI(pathname)), + search: search, + hash: hash, + href: href, + origin: origin, + protocol: protocol, + host: host, + hostname: hostname, + port: port, + state: source.history.state, + key: source.history.state && source.history.state.key || "initial" + }; +}; + +var createHistory = function createHistory(source, options) { + var listeners = []; + var location = getLocation(source); + var transitioning = false; + var resolveTransition = function resolveTransition() {}; + + return { + get location() { + return location; + }, + + get transitioning() { + return transitioning; + }, + + _onTransitionComplete: function _onTransitionComplete() { + transitioning = false; + resolveTransition(); + }, + listen: function listen(listener) { + listeners.push(listener); + + var popstateListener = function popstateListener() { + location = getLocation(source); + listener({ location: location, action: "POP" }); + }; + + source.addEventListener("popstate", popstateListener); + + return function () { + source.removeEventListener("popstate", popstateListener); + listeners = listeners.filter(function (fn) { + return fn !== listener; + }); + }; + }, + navigate: function navigate(to) { + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + state = _ref.state, + _ref$replace = _ref.replace, + replace = _ref$replace === undefined ? false : _ref$replace; + + if (typeof to === "number") { + source.history.go(to); + } else { + state = _extends({}, state, { key: Date.now() + "" }); + // try...catch iOS Safari limits to 100 pushState calls + try { + if (transitioning || replace) { + source.history.replaceState(state, null, to); + } else { + source.history.pushState(state, null, to); + } + } catch (e) { + source.location[replace ? "replace" : "assign"](to); + } + } + + location = getLocation(source); + transitioning = true; + var transition = new Promise(function (res) { + return resolveTransition = res; + }); + listeners.forEach(function (listener) { + return listener({ location: location, action: "PUSH" }); + }); + return transition; + } + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Stores history entries in memory for testing or other platforms like Native +var createMemorySource = function createMemorySource() { + var initialPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "/"; + + var searchIndex = initialPath.indexOf("?"); + var initialLocation = { + pathname: searchIndex > -1 ? initialPath.substr(0, searchIndex) : initialPath, + search: searchIndex > -1 ? initialPath.substr(searchIndex) : "" + }; + var index = 0; + var stack = [initialLocation]; + var states = [null]; + + return { + get location() { + return stack[index]; + }, + addEventListener: function addEventListener(name, fn) {}, + removeEventListener: function removeEventListener(name, fn) {}, + + history: { + get entries() { + return stack; + }, + get index() { + return index; + }, + get state() { + return states[index]; + }, + pushState: function pushState(state, _, uri) { + var _uri$split = uri.split("?"), + pathname = _uri$split[0], + _uri$split$ = _uri$split[1], + search = _uri$split$ === undefined ? "" : _uri$split$; + + index++; + stack.push({ pathname: pathname, search: search.length ? "?" + search : search }); + states.push(state); + }, + replaceState: function replaceState(state, _, uri) { + var _uri$split2 = uri.split("?"), + pathname = _uri$split2[0], + _uri$split2$ = _uri$split2[1], + search = _uri$split2$ === undefined ? "" : _uri$split2$; + + stack[index] = { pathname: pathname, search: search }; + states[index] = state; + }, + go: function go(to) { + var newIndex = index + to; + + if (newIndex < 0 || newIndex > states.length - 1) { + return; + } + + index = newIndex; + } + } + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// global history - uses window.history as the source if available, otherwise a +// memory history +var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement); +var getSource = function getSource() { + return canUseDOM ? window : createMemorySource(); +}; + +var globalHistory = createHistory(getSource()); +var navigate = globalHistory.navigate; + +//////////////////////////////////////////////////////////////////////////////// + + + +/***/ }), + +/***/ "../node_modules/@reach/router/es/lib/utils.js": +/*!*****************************************************!*\ + !*** ../node_modules/@reach/router/es/lib/utils.js ***! + \*****************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ insertParams: () => (/* binding */ insertParams), +/* harmony export */ match: () => (/* binding */ match), +/* harmony export */ pick: () => (/* binding */ pick), +/* harmony export */ resolve: () => (/* binding */ resolve), +/* harmony export */ shallowCompare: () => (/* binding */ shallowCompare), +/* harmony export */ startsWith: () => (/* binding */ startsWith), +/* harmony export */ validateRedirect: () => (/* binding */ validateRedirect) +/* harmony export */ }); +/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! invariant */ "../node_modules/invariant/browser.js"); +/* harmony import */ var invariant__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(invariant__WEBPACK_IMPORTED_MODULE_0__); + + +//////////////////////////////////////////////////////////////////////////////// +// startsWith(string, search) - Check if `string` starts with `search` +var startsWith = function startsWith(string, search) { + return string.substr(0, search.length) === search; +}; + +//////////////////////////////////////////////////////////////////////////////// +// pick(routes, uri) +// +// Ranks and picks the best route to match. Each segment gets the highest +// amount of points, then the type of segment gets an additional amount of +// points where +// +// static > dynamic > splat > root +// +// This way we don't have to worry about the order of our routes, let the +// computers do it. +// +// A route looks like this +// +// { path, default, value } +// +// And a returned match looks like: +// +// { route, params, uri } +// +// I know, I should use TypeScript not comments for these types. +var pick = function pick(routes, uri) { + var match = void 0; + var default_ = void 0; + + var _uri$split = uri.split("?"), + uriPathname = _uri$split[0]; + + var uriSegments = segmentize(uriPathname); + var isRootUri = uriSegments[0] === ""; + var ranked = rankRoutes(routes); + + for (var i = 0, l = ranked.length; i < l; i++) { + var missed = false; + var route = ranked[i].route; + + if (route.default) { + default_ = { + route: route, + params: {}, + uri: uri + }; + continue; + } + + var routeSegments = segmentize(route.path); + var params = {}; + var max = Math.max(uriSegments.length, routeSegments.length); + var index = 0; + + for (; index < max; index++) { + var routeSegment = routeSegments[index]; + var uriSegment = uriSegments[index]; + + if (isSplat(routeSegment)) { + // Hit a splat, just grab the rest, and return a match + // uri: /files/documents/work + // route: /files/* + var param = routeSegment.slice(1) || "*"; + params[param] = uriSegments.slice(index).map(decodeURIComponent).join("/"); + break; + } + + if (uriSegment === undefined) { + // URI is shorter than the route, no match + // uri: /users + // route: /users/:userId + missed = true; + break; + } + + var dynamicMatch = paramRe.exec(routeSegment); + + if (dynamicMatch && !isRootUri) { + var matchIsNotReserved = reservedNames.indexOf(dynamicMatch[1]) === -1; + !matchIsNotReserved ? true ? invariant__WEBPACK_IMPORTED_MODULE_0___default()(false, " dynamic segment \"" + dynamicMatch[1] + "\" is a reserved name. Please use a different name in path \"" + route.path + "\".") : 0 : void 0; + var value = decodeURIComponent(uriSegment); + params[dynamicMatch[1]] = value; + } else if (routeSegment !== uriSegment) { + // Current segments don't match, not dynamic, not splat, so no match + // uri: /users/123/settings + // route: /users/:id/profile + missed = true; + break; + } + } + + if (!missed) { + match = { + route: route, + params: params, + uri: "/" + uriSegments.slice(0, index).join("/") + }; + break; + } + } + + return match || default_ || null; +}; + +//////////////////////////////////////////////////////////////////////////////// +// match(path, uri) - Matches just one path to a uri, also lol +var match = function match(path, uri) { + return pick([{ path: path }], uri); +}; + +//////////////////////////////////////////////////////////////////////////////// +// resolve(to, basepath) +// +// Resolves URIs as though every path is a directory, no files. Relative URIs +// in the browser can feel awkward because not only can you be "in a directory" +// you can be "at a file", too. For example +// +// browserSpecResolve('foo', '/bar/') => /bar/foo +// browserSpecResolve('foo', '/bar') => /foo +// +// But on the command line of a file system, it's not as complicated, you can't +// `cd` from a file, only directories. This way, links have to know less about +// their current path. To go deeper you can do this: +// +// +// // instead of +// +// +// Just like `cd`, if you want to go deeper from the command line, you do this: +// +// cd deeper +// # not +// cd $(pwd)/deeper +// +// By treating every path as a directory, linking to relative paths should +// require less contextual information and (fingers crossed) be more intuitive. +var resolve = function resolve(to, base) { + // /foo/bar, /baz/qux => /foo/bar + if (startsWith(to, "/")) { + return to; + } + + var _to$split = to.split("?"), + toPathname = _to$split[0], + toQuery = _to$split[1]; + + var _base$split = base.split("?"), + basePathname = _base$split[0]; + + var toSegments = segmentize(toPathname); + var baseSegments = segmentize(basePathname); + + // ?a=b, /users?b=c => /users?a=b + if (toSegments[0] === "") { + return addQuery(basePathname, toQuery); + } + + // profile, /users/789 => /users/789/profile + if (!startsWith(toSegments[0], ".")) { + var pathname = baseSegments.concat(toSegments).join("/"); + return addQuery((basePathname === "/" ? "" : "/") + pathname, toQuery); + } + + // ./ /users/123 => /users/123 + // ../ /users/123 => /users + // ../.. /users/123 => / + // ../../one /a/b/c/d => /a/b/one + // .././one /a/b/c/d => /a/b/c/one + var allSegments = baseSegments.concat(toSegments); + var segments = []; + for (var i = 0, l = allSegments.length; i < l; i++) { + var segment = allSegments[i]; + if (segment === "..") segments.pop();else if (segment !== ".") segments.push(segment); + } + + return addQuery("/" + segments.join("/"), toQuery); +}; + +//////////////////////////////////////////////////////////////////////////////// +// insertParams(path, params) + +var insertParams = function insertParams(path, params) { + var _path$split = path.split("?"), + pathBase = _path$split[0], + _path$split$ = _path$split[1], + query = _path$split$ === undefined ? "" : _path$split$; + + var segments = segmentize(pathBase); + var constructedPath = "/" + segments.map(function (segment) { + var match = paramRe.exec(segment); + return match ? params[match[1]] : segment; + }).join("/"); + var _params$location = params.location; + _params$location = _params$location === undefined ? {} : _params$location; + var _params$location$sear = _params$location.search, + search = _params$location$sear === undefined ? "" : _params$location$sear; + + var searchSplit = search.split("?")[1] || ""; + constructedPath = addQuery(constructedPath, query, searchSplit); + return constructedPath; +}; + +var validateRedirect = function validateRedirect(from, to) { + var filter = function filter(segment) { + return isDynamic(segment); + }; + var fromString = segmentize(from).filter(filter).sort().join("/"); + var toString = segmentize(to).filter(filter).sort().join("/"); + return fromString === toString; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Junk +var paramRe = /^:(.+)/; + +var SEGMENT_POINTS = 4; +var STATIC_POINTS = 3; +var DYNAMIC_POINTS = 2; +var SPLAT_PENALTY = 1; +var ROOT_POINTS = 1; + +var isRootSegment = function isRootSegment(segment) { + return segment === ""; +}; +var isDynamic = function isDynamic(segment) { + return paramRe.test(segment); +}; +var isSplat = function isSplat(segment) { + return segment && segment[0] === "*"; +}; + +var rankRoute = function rankRoute(route, index) { + var score = route.default ? 0 : segmentize(route.path).reduce(function (score, segment) { + score += SEGMENT_POINTS; + if (isRootSegment(segment)) score += ROOT_POINTS;else if (isDynamic(segment)) score += DYNAMIC_POINTS;else if (isSplat(segment)) score -= SEGMENT_POINTS + SPLAT_PENALTY;else score += STATIC_POINTS; + return score; + }, 0); + return { route: route, score: score, index: index }; +}; + +var rankRoutes = function rankRoutes(routes) { + return routes.map(rankRoute).sort(function (a, b) { + return a.score < b.score ? 1 : a.score > b.score ? -1 : a.index - b.index; + }); +}; + +var segmentize = function segmentize(uri) { + return uri + // strip starting/ending slashes + .replace(/(^\/+|\/+$)/g, "").split("/"); +}; + +var addQuery = function addQuery(pathname) { + for (var _len = arguments.length, query = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + query[_key - 1] = arguments[_key]; + } + + query = query.filter(function (q) { + return q && q.length > 0; + }); + return pathname + (query && query.length > 0 ? "?" + query.join("&") : ""); +}; + +var reservedNames = ["uri", "path"]; + +/** + * Shallow compares two objects. + * @param {Object} obj1 The first object to compare. + * @param {Object} obj2 The second object to compare. + */ +var shallowCompare = function shallowCompare(obj1, obj2) { + var obj1Keys = Object.keys(obj1); + return obj1Keys.length === Object.keys(obj2).length && obj1Keys.every(function (key) { + return obj2.hasOwnProperty(key) && obj1[key] === obj2[key]; + }); +}; + +//////////////////////////////////////////////////////////////////////////////// + + +/***/ }), + +/***/ "../node_modules/@reach/router/node_modules/create-react-context/lib/implementation.js": +/*!*********************************************************************************************!*\ + !*** ../node_modules/@reach/router/node_modules/create-react-context/lib/implementation.js ***! + \*********************************************************************************************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +exports.__esModule = true; + +var _react = __webpack_require__(/*! react */ "react"); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _gud = __webpack_require__(/*! gud */ "../node_modules/gud/index.js"); + +var _gud2 = _interopRequireDefault(_gud); + +var _warning = __webpack_require__(/*! warning */ "../node_modules/warning/warning.js"); + +var _warning2 = _interopRequireDefault(_warning); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var MAX_SIGNED_31_BIT_INT = 1073741823; + +// Inlined Object.is polyfill. +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is +function objectIs(x, y) { + if (x === y) { + return x !== 0 || 1 / x === 1 / y; + } else { + return x !== x && y !== y; + } +} + +function createEventEmitter(value) { + var handlers = []; + return { + on: function on(handler) { + handlers.push(handler); + }, + off: function off(handler) { + handlers = handlers.filter(function (h) { + return h !== handler; + }); + }, + get: function get() { + return value; + }, + set: function set(newValue, changedBits) { + value = newValue; + handlers.forEach(function (handler) { + return handler(value, changedBits); + }); + } + }; +} + +function onlyChild(children) { + return Array.isArray(children) ? children[0] : children; +} + +function createReactContext(defaultValue, calculateChangedBits) { + var _Provider$childContex, _Consumer$contextType; + + var contextProp = '__create-react-context-' + (0, _gud2.default)() + '__'; + + var Provider = function (_Component) { + _inherits(Provider, _Component); + + function Provider() { + var _temp, _this, _ret; + + _classCallCheck(this, Provider); + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.emitter = createEventEmitter(_this.props.value), _temp), _possibleConstructorReturn(_this, _ret); + } + + Provider.prototype.getChildContext = function getChildContext() { + var _ref; + + return _ref = {}, _ref[contextProp] = this.emitter, _ref; + }; + + Provider.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + if (this.props.value !== nextProps.value) { + var oldValue = this.props.value; + var newValue = nextProps.value; + var changedBits = void 0; + + if (objectIs(oldValue, newValue)) { + changedBits = 0; // No change + } else { + changedBits = typeof calculateChangedBits === 'function' ? calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT; + if (true) { + (0, _warning2.default)((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits); + } + + changedBits |= 0; + + if (changedBits !== 0) { + this.emitter.set(nextProps.value, changedBits); + } + } + } + }; + + Provider.prototype.render = function render() { + return this.props.children; + }; + + return Provider; + }(_react.Component); + + Provider.childContextTypes = (_Provider$childContex = {}, _Provider$childContex[contextProp] = _propTypes2.default.object.isRequired, _Provider$childContex); + + var Consumer = function (_Component2) { + _inherits(Consumer, _Component2); + + function Consumer() { + var _temp2, _this2, _ret2; + + _classCallCheck(this, Consumer); + + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return _ret2 = (_temp2 = (_this2 = _possibleConstructorReturn(this, _Component2.call.apply(_Component2, [this].concat(args))), _this2), _this2.state = { + value: _this2.getValue() + }, _this2.onUpdate = function (newValue, changedBits) { + var observedBits = _this2.observedBits | 0; + if ((observedBits & changedBits) !== 0) { + _this2.setState({ value: _this2.getValue() }); + } + }, _temp2), _possibleConstructorReturn(_this2, _ret2); + } + + Consumer.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var observedBits = nextProps.observedBits; + + this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default + : observedBits; + }; + + Consumer.prototype.componentDidMount = function componentDidMount() { + if (this.context[contextProp]) { + this.context[contextProp].on(this.onUpdate); + } + var observedBits = this.props.observedBits; + + this.observedBits = observedBits === undefined || observedBits === null ? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default + : observedBits; + }; + + Consumer.prototype.componentWillUnmount = function componentWillUnmount() { + if (this.context[contextProp]) { + this.context[contextProp].off(this.onUpdate); + } + }; + + Consumer.prototype.getValue = function getValue() { + if (this.context[contextProp]) { + return this.context[contextProp].get(); + } else { + return defaultValue; + } + }; + + Consumer.prototype.render = function render() { + return onlyChild(this.props.children)(this.state.value); + }; + + return Consumer; + }(_react.Component); + + Consumer.contextTypes = (_Consumer$contextType = {}, _Consumer$contextType[contextProp] = _propTypes2.default.object, _Consumer$contextType); + + + return { + Provider: Provider, + Consumer: Consumer + }; +} + +exports["default"] = createReactContext; +module.exports = exports['default']; + +/***/ }), + +/***/ "../node_modules/@reach/router/node_modules/create-react-context/lib/index.js": +/*!************************************************************************************!*\ + !*** ../node_modules/@reach/router/node_modules/create-react-context/lib/index.js ***! + \************************************************************************************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +exports.__esModule = true; + +var _react = __webpack_require__(/*! react */ "react"); + +var _react2 = _interopRequireDefault(_react); + +var _implementation = __webpack_require__(/*! ./implementation */ "../node_modules/@reach/router/node_modules/create-react-context/lib/implementation.js"); + +var _implementation2 = _interopRequireDefault(_implementation); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports["default"] = _react2.default.createContext || _implementation2.default; +module.exports = exports['default']; + +/***/ }), + +/***/ "../core/app/assets/js/hooks/use-feature-lock.js": +/*!*******************************************************!*\ + !*** ../core/app/assets/js/hooks/use-feature-lock.js ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = useFeatureLock; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _connectButton = _interopRequireDefault(__webpack_require__(/*! ../ui/connect-button */ "../core/app/assets/js/ui/connect-button.js")); +var _utils = __webpack_require__(/*! ../utils */ "../core/app/assets/js/utils.js"); +function useFeatureLock(featureName) { + const appConfig = elementorAppProConfig[featureName] ?? {}, + isLocked = appConfig.lock?.is_locked ?? false; + const buttonText = (0, _utils.htmlDecodeTextContent)(appConfig.lock?.button.text); + const buttonLink = (0, _utils.replaceUtmPlaceholders)(appConfig.lock?.button.url ?? '', appConfig.utms ?? {}); + const ConnectButton = () => /*#__PURE__*/_react.default.createElement(_connectButton.default, { + text: buttonText, + url: buttonLink + }); + return { + isLocked, + ConnectButton + }; +} + +/***/ }), + +/***/ "../core/app/assets/js/ui/connect-button.js": +/*!**************************************************!*\ + !*** ../core/app/assets/js/ui/connect-button.js ***! + \**************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _utils = __webpack_require__(/*! ../utils.js */ "../core/app/assets/js/utils.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConnectButton = props => { + const className = (0, _utils.arrayToClassName)(['e-app-connect-button', props.className]); + const buttonRef = (0, _react.useRef)(null); + (0, _react.useEffect)(() => { + if (!buttonRef.current) { + return; + } + jQuery(buttonRef.current).elementorConnect(); + }, []); + return /*#__PURE__*/React.createElement(_appUi.Button, (0, _extends2.default)({}, props, { + elRef: buttonRef, + className: className + })); +}; +ConnectButton.propTypes = { + ..._appUi.Button.propTypes, + text: PropTypes.string.isRequired, + url: PropTypes.string.isRequired, + className: PropTypes.string +}; +ConnectButton.defaultProps = { + className: '', + variant: 'contained', + size: 'sm', + color: 'cta', + target: '_blank', + rel: 'noopener noreferrer', + text: __('Connect & Activate', 'elementor-pro') +}; +var _default = exports["default"] = React.memo(ConnectButton); + +/***/ }), + +/***/ "../core/app/assets/js/utils.js": +/*!**************************************!*\ + !*** ../core/app/assets/js/utils.js ***! + \**************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.replaceUtmPlaceholders = exports.htmlDecodeTextContent = exports.arrayToClassName = void 0; +// Copied from Core. +const arrayToClassName = (array, action) => { + return array.filter(item => 'object' === typeof item ? Object.entries(item)[0][1] : item).map(item => { + const value = 'object' === typeof item ? Object.entries(item)[0][0] : item; + return action ? action(value) : value; + }).join(' '); +}; +exports.arrayToClassName = arrayToClassName; +const htmlDecodeTextContent = input => { + const doc = new DOMParser().parseFromString(input, 'text/html'); + return doc.documentElement.textContent; +}; +exports.htmlDecodeTextContent = htmlDecodeTextContent; +const replaceUtmPlaceholders = (link = '', utms = {}) => { + if (!link || !utms) { + return link; + } + Object.keys(utms).forEach(key => { + const match = new RegExp(`%%${key}%%`, 'g'); + link = link.replace(match, utms[key]); + }); + return link; +}; +exports.replaceUtmPlaceholders = replaceUtmPlaceholders; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/customization-list-setting-section.js": +/*!******************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/customization-list-setting-section.js ***! + \******************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ListSettingSection = ListSettingSection; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _utils = __webpack_require__(/*! elementor-pro-app/utils */ "../core/app/assets/js/utils.js"); +var _upgradeTooltip = __webpack_require__(/*! ./upgrade-tooltip */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const DEFAULT_VISIBLE_ITEMS_COUNT = 16; +function ListSettingSection({ + items, + title, + loading, + settings, + onSettingChange, + settingKey, + disabled = false, + tooltip = false +}) { + const [showMore, setShowMore] = (0, _react.useState)(false); + return /*#__PURE__*/_react.default.createElement(_ui.Box, { + key: settingKey, + sx: { + mb: 3, + border: 1, + borderRadius: 1, + borderColor: 'action.focus', + p: 2.5 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + spacing: 2 + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "h6" + }, title), /*#__PURE__*/_react.default.createElement(_ui.Grid, { + container: true, + spacing: 1, + alignItems: "start" + }, loading ? /*#__PURE__*/_react.default.createElement(_ui.Grid, { + item: true, + xs: 12, + sx: { + p: 1, + alignItems: 'center', + textAlign: 'center' + } + }, /*#__PURE__*/_react.default.createElement(_ui.CircularProgress, { + size: 30 + })) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Grid, { + key: 'all', + item: true, + xs: 12, + sx: { + py: 1, + px: 0 + } + }, /*#__PURE__*/_react.default.createElement(_upgradeTooltip.UpgradeTooltip, { + disabled: disabled && settings.length === items.length, + tooltip: tooltip + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + pointerEvents: 'auto', + ...(settings.length === items.length && disabled && { + cursor: 'pointer' + }) + } + }, /*#__PURE__*/_react.default.createElement(_ui.FormControlLabel, { + control: /*#__PURE__*/_react.default.createElement(_ui.Checkbox, { + color: "info", + checked: settings.length === items.length, + indeterminate: settings.length > 0 && settings.length !== items.length, + onChange: (e, checked) => { + if (checked) { + onSettingChange(items.map(({ + value + }) => value), true); + } else { + onSettingChange([], true); + } + }, + sx: { + p: 0 + }, + disabled: disabled + }), + sx: { + gap: 1, + ...(settings.length === items.length && disabled && { + cursor: 'pointer' + }) + }, + slotProps: { + typography: { + sx: { + fontWeight: 500, + ...(settings.length === items.length && disabled && { + cursor: 'pointer' + }) + } + } + }, + label: `${(0, _i18n.__)('All', 'elementor-pro')} ${title.toLowerCase()}` + })))), (showMore ? items : items.slice(0, DEFAULT_VISIBLE_ITEMS_COUNT)).map(item => { + return /*#__PURE__*/_react.default.createElement(_ui.Grid, { + key: item.value, + item: true, + xs: 3, + sx: { + py: 1, + px: 0 + } + }, /*#__PURE__*/_react.default.createElement(_upgradeTooltip.UpgradeTooltip, { + disabled: disabled && settings.includes(item.value), + tooltip: tooltip + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + pointerEvents: 'auto', + ...(settings.includes(item.value) && disabled && { + cursor: 'pointer' + }) + } + }, /*#__PURE__*/_react.default.createElement(_ui.FormControlLabel, { + control: /*#__PURE__*/_react.default.createElement(_ui.Checkbox, { + color: "info", + checked: settings.includes(item.value), + onChange: (e, checked) => { + if (checked) { + onSettingChange([...settings, item.value]); + } else { + onSettingChange(settings.filter(setting => setting !== item.value)); + } + }, + sx: { + p: 0, + ...(settings.includes(item.value) && disabled && { + cursor: 'pointer' + }) + }, + disabled: disabled + }), + sx: { + maxWidth: '100%', + gap: 1, + ...(settings.includes(item.value) && disabled && { + cursor: 'pointer' + }) + }, + slotProps: { + typography: { + sx: { + fontWeight: 400, + maxWidth: '100%', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + ...(settings.includes(item.value) && disabled && { + cursor: 'pointer' + }) + } + } + }, + label: (0, _utils.htmlDecodeTextContent)(item.label) + })))); + })))), items.length > DEFAULT_VISIBLE_ITEMS_COUNT && /*#__PURE__*/_react.default.createElement(_ui.Button, { + variant: "text", + color: "info", + onClick: () => setShowMore(!showMore) + }, showMore ? (0, _i18n.__)('Show less', 'elementor') : (0, _i18n.__)('Show more', 'elementor'))); +} +ListSettingSection.propTypes = { + title: PropTypes.string.isRequired, + children: PropTypes.node, + loading: PropTypes.bool, + disabled: PropTypes.bool, + checked: PropTypes.bool, + settingKey: PropTypes.string, + onSettingChange: PropTypes.func.isRequired, + tooltip: PropTypes.bool, + items: PropTypes.arrayOf(PropTypes.shape({ + label: PropTypes.string.isRequired, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + })), + settings: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])) +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js": +/*!*************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js ***! + \*************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SettingSection = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _upgradeTooltip = __webpack_require__(/*! ./upgrade-tooltip */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const SettingSection = ({ + checked = false, + title, + description, + children, + settingKey, + onSettingChange, + hasToggle = true, + disabled = false, + notExported = false, + tooltip = false +}) => { + const getToggle = () => { + if (notExported) { + return /*#__PURE__*/_react.default.createElement(_ui.Typography, { + "data-testid": `${settingKey}-description`, + variant: "body1", + color: "text.secondary" + }, __('Not exported', 'elementor')); + } + if (!hasToggle) { + return null; + } + const switchElement = /*#__PURE__*/_react.default.createElement(_ui.Switch, { + "data-testid": `${settingKey}-switch`, + checked: checked, + onChange: (_, isChecked) => onSettingChange && onSettingChange(settingKey, isChecked), + color: "info", + size: "medium", + sx: { + alignSelf: 'center', + ...(disabled && tooltip && { + cursor: 'pointer' + }) + }, + disabled: disabled + }); + return /*#__PURE__*/_react.default.createElement(_upgradeTooltip.UpgradeTooltip, { + disabled: disabled, + tooltip: tooltip + }, switchElement); + }; + return /*#__PURE__*/_react.default.createElement(_ui.Box, { + key: settingKey, + sx: { + mb: 3, + border: 1, + borderRadius: 1, + borderColor: 'action.focus', + p: 2.5 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + spacing: 1 + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "h6" + }, title), description && /*#__PURE__*/_react.default.createElement(_ui.Typography, { + "data-testid": `${settingKey}-description`, + variant: "body1", + color: "text.secondary" + }, description)), getToggle()), children && /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + mt: 1 + } + }, children)); +}; +exports.SettingSection = SettingSection; +SettingSection.propTypes = { + title: PropTypes.string.isRequired, + description: PropTypes.string, + children: PropTypes.node, + hasToggle: PropTypes.bool, + checked: PropTypes.bool, + disabled: PropTypes.bool, + settingKey: PropTypes.string, + onSettingChange: PropTypes.func, + notExported: PropTypes.bool, + tooltip: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/customization-sub-setting.js": +/*!*********************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/customization-sub-setting.js ***! + \*********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SubSetting = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _upgradeTooltip = __webpack_require__(/*! ./upgrade-tooltip */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const SubSetting = ({ + label, + settingKey, + onSettingChange, + checked = false, + disabled = false, + notExported = false, + tooltip = false +}) => { + const getToggle = () => { + if (notExported) { + return /*#__PURE__*/_react.default.createElement(_ui.Typography, { + "data-testid": `${settingKey}-description`, + variant: "body1", + color: "text.secondary", + sx: { + fontWeight: 400, + alignSelf: 'center' + } + }, __('Not exported', 'elementor')); + } + const switchElement = /*#__PURE__*/_react.default.createElement(_ui.Switch, { + "data-testid": `${settingKey}-switch`, + checked: checked, + disabled: disabled, + onChange: (_, isChecked) => onSettingChange && onSettingChange(settingKey, isChecked), + color: "info", + size: "medium", + sx: { + alignSelf: 'center', + ...(disabled && tooltip && { + cursor: 'pointer' + }) + } + }); + return /*#__PURE__*/_react.default.createElement(_upgradeTooltip.UpgradeTooltip, { + disabled: disabled, + tooltip: tooltip + }, switchElement); + }; + return /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' + } + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + "data-testid": `${settingKey}-label`, + variant: "body1" + }, label), getToggle()); +}; +exports.SubSetting = SubSetting; +SubSetting.propTypes = { + checked: PropTypes.bool, + disabled: PropTypes.bool, + notExported: PropTypes.bool, + label: PropTypes.string.isRequired, + settingKey: PropTypes.string.isRequired, + onSettingChange: PropTypes.func, + tooltip: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/kit-content-customization-dialog.js": +/*!****************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/kit-content-customization-dialog.js ***! + \****************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.KitContentCustomizationDialog = KitContentCustomizationDialog; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _kitCustomizationDialog = __webpack_require__(/*! ./kit-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js"); +var _customizationListSettingSection = __webpack_require__(/*! ./customization-list-setting-section */ "../core/app/modules/import-export-customization/assets/js/components/customization-list-setting-section.js"); +var _customizationSettingSection = __webpack_require__(/*! ./customization-setting-section */ "../core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js"); +var _customizationSubSetting = __webpack_require__(/*! ./customization-sub-setting */ "../core/app/modules/import-export-customization/assets/js/components/customization-sub-setting.js"); +var _upgradeNoticeBanner = __webpack_require__(/*! ./upgrade-notice-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js"); +var _useKitCustomizationPages = __webpack_require__(/*! ../hooks/use-kit-customization-pages */ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-pages.js"); +var _useKitCustomizationTaxonomies = __webpack_require__(/*! ../hooks/use-kit-customization-taxonomies */ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-taxonomies.js"); +var _useKitCustomizationCustomPostTypes = __webpack_require__(/*! ../hooks/use-kit-customization-custom-post-types */ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-custom-post-types.js"); +var _useTier = __webpack_require__(/*! ../hooks/use-tier */ "../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js"); +var _upgradeVersionBanner = __webpack_require__(/*! ./upgrade-version-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js"); +var _analyticsTransformer = __webpack_require__(/*! ../utils/analytics-transformer */ "../core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const MEDIA_FORMAT_OPTIONS = { + LINK: 'link', + CLOUD: 'cloud' +}; +const MEDIA_FORMAT_CONFIG = [{ + value: MEDIA_FORMAT_OPTIONS.LINK, + title: (0, _i18n.__)('Link to media', 'elementor-pro'), + description: (0, _i18n.__)('Stores only the URLs. The export stays light, but files load only while the original site is online.', 'elementor-pro') +}, { + value: MEDIA_FORMAT_OPTIONS.CLOUD, + title: (0, _i18n.__)('Save media to the cloud', 'elementor-pro'), + description: (0, _i18n.__)('All images and files are stored with the template. Keeps everything intact, but the file is larger.', 'elementor-pro') +}]; +const transformAnalyticsData = (payload, pageOptions, taxonomyOptions, customPostTypes) => { + const optionsArray = [{ + key: 'pages', + options: pageOptions + }, { + key: 'taxonomies', + options: taxonomyOptions + }, { + key: 'customPostTypes', + options: customPostTypes + }]; + const transformed = {}; + for (const [key, value] of Object.entries(payload)) { + transformed[key] = (0, _analyticsTransformer.transformValueForAnalytics)(key, value, optionsArray); + } + return transformed; +}; +function KitContentCustomizationDialog({ + open, + handleClose, + handleSaveChanges, + data, + isImport, + isOldExport, + isOldElementorVersion, + isCloudKitsEligible = false, + showMediaFormatValidation = false +}) { + const initialState = data.includes.includes('content'); + const { + isLoading: isPagesLoading, + pageOptions, + isLoaded: isPagesLoaded + } = (0, _useKitCustomizationPages.useKitCustomizationPages)({ + open, + data + }); + const { + isLoading: isTaxonomiesLoading, + taxonomyOptions, + isLoaded: isTaxonomiesLoaded + } = (0, _useKitCustomizationTaxonomies.useKitCustomizationTaxonomies)({ + open, + data + }); + const { + customPostTypes + } = (0, _useKitCustomizationCustomPostTypes.useKitCustomizationCustomPostTypes)({ + data + }); + const alertRef = (0, _react.useRef)(null); + const mediaFormatSectionRef = (0, _react.useRef)(null); + const [settings, setSettings] = (0, _react.useState)(() => { + if (data.customization.content) { + return data.customization.content; + } + return { + pages: [], + menus: initialState, + taxonomies: [], + customPostTypes: [], + mediaFormat: MEDIA_FORMAT_OPTIONS.LINK + }; + }); + (0, _react.useEffect)(() => { + if (!open || data.includes.includes('content')) { + return; + } + setSettings({ + pages: [], + menus: false, + taxonomies: [], + customPostTypes: [], + mediaFormat: MEDIA_FORMAT_OPTIONS.LINK + }); + }, [open, data.includes]); + (0, _react.useEffect)(() => { + if (!open || !data.includes.includes('content')) { + return; + } + setSettings(prevSettings => ({ + ...prevSettings, + pages: isPagesLoaded || isImport ? data.customization.content?.pages || pageOptions.map(({ + value + }) => value) : prevSettings.pages + })); + }, [open, data.includes, data.customization.content?.pages, isPagesLoaded, isImport, pageOptions]); + (0, _react.useEffect)(() => { + if (!open || !data.includes.includes('content')) { + return; + } + setSettings(prevSettings => ({ + ...prevSettings, + taxonomies: isTaxonomiesLoaded || isImport ? data.customization.content?.taxonomies || taxonomyOptions.map(({ + value + }) => value) : prevSettings.taxonomies + })); + }, [open, data.includes, data.customization.content?.taxonomies, isTaxonomiesLoaded, isImport, taxonomyOptions]); + (0, _react.useEffect)(() => { + if (!open || !data.includes.includes('content')) { + return; + } + setSettings(prevSettings => ({ + ...prevSettings, + customPostTypes: customPostTypes ? data.customization.content?.customPostTypes || customPostTypes.map(({ + value + }) => value) : prevSettings.customPostTypes + })); + }, [open, data.includes, data.customization.content?.customPostTypes, customPostTypes]); + (0, _react.useEffect)(() => { + if (!open || !data.includes.includes('content')) { + return; + } + setSettings(prevSettings => ({ + ...prevSettings, + menus: isImport ? data.customization.content?.menus || Object.keys(data?.uploadedData?.manifest['wp-content']?.nav_menu_item || {}).length > 0 : data.customization.content?.menus ?? initialState + })); + }, [open, data.includes, data.customization.content?.menus, data.uploadedData?.manifest, isImport]); + (0, _react.useEffect)(() => { + if (!open || !data.includes.includes('content')) { + return; + } + setSettings(prevSettings => ({ + ...prevSettings, + mediaFormat: data.customization.content?.mediaFormat || MEDIA_FORMAT_OPTIONS.LINK + })); + }, [open, data.includes, data.customization.content?.mediaFormat]); + (0, _react.useEffect)(() => { + if (open) { + window.elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit); + } + }, [open]); + (0, _react.useEffect)(() => { + if (showMediaFormatValidation) { + setTimeout(() => { + const targetElement = alertRef.current || mediaFormatSectionRef.current; + if (targetElement) { + targetElement.scrollIntoView({ + behavior: 'smooth', + block: 'center' + }); + } + }); + } + }, [showMediaFormatValidation]); + const handleSettingsChange = (settingKey, payload) => { + setSettings(prev => ({ + ...prev, + [settingKey]: payload + })); + }; + const isTaxonomiesExported = () => { + return isImport && taxonomyOptions?.length > 0; + }; + const isPagesExported = () => { + const content = data?.uploadedData?.manifest?.content; + const wpContent = data?.uploadedData?.manifest?.['wp-content']; + const isSomeContentExported = Object.keys(content?.page || {})?.length; + const isSomeWPContentExported = Object.keys(wpContent?.page || {})?.length; + return Boolean(isSomeContentExported || isSomeWPContentExported); + }; + const isMenusExported = () => { + return Object.keys(data?.uploadedData?.manifest?.['wp-content']?.nav_menu_item || {}).length > 0 || customPostTypes?.find(cpt => cpt.value.includes('nav_menu')); + }; + const isCustomPostTypesExported = () => { + return isImport && customPostTypes?.length > 0; + }; + const renderPagesSection = () => { + if (isImport && isOldExport) { + return null; + } + return isImport && !isPagesExported() ? /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + title: (0, _i18n.__)('Site pages', 'elementor-pro'), + settingKey: "pages", + notExported: true + }) : /*#__PURE__*/_react.default.createElement(_customizationListSettingSection.ListSettingSection, { + settingKey: "pages", + title: (0, _i18n.__)('Site pages', 'elementor-pro'), + onSettingChange: selectedPages => { + handleSettingsChange('pages', selectedPages); + }, + settings: settings.pages, + items: pageOptions, + loading: isPagesLoading, + disabled: !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }); + }; + const renderMenusSection = () => { + if (isImport && isOldExport) { + return null; + } + return /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: settings.menus, + disabled: isImport && !isMenusExported() || !(0, _useTier.isHighTier)(), + title: (0, _i18n.__)('Menus', 'elementor-pro'), + settingKey: "menus", + tooltip: !(0, _useTier.isHighTier)(), + onSettingChange: (key, isChecked) => { + handleSettingsChange(key, isChecked); + } + }); + }; + const renderMediaFormatSection = () => { + if (isImport) { + return /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + title: (0, _i18n.__)('Media format', 'elementor-pro'), + settingKey: "mediaFormat", + hasToggle: false + }, /*#__PURE__*/_react.default.createElement(_ui.Alert, { + icon: /*#__PURE__*/_react.default.createElement(_ui.SvgIcon, { + color: "info", + viewBox: "0 0 24 24" + }, /*#__PURE__*/_react.default.createElement("path", { + d: "M11.8623 14.7549C12.3665 14.8061 12.7598 15.2322 12.7598 15.75C12.7598 16.2678 12.3665 16.6939 11.8623 16.7451L11.7598 16.75H11.75C11.1977 16.75 10.75 16.3023 10.75 15.75C10.75 15.1977 11.1977 14.75 11.75 14.75H11.7598L11.8623 14.7549Z", + fill: "currentColor" + }), /*#__PURE__*/_react.default.createElement("path", { + d: "M11.75 7C12.1642 7 12.5 7.33579 12.5 7.75V12.75C12.5 13.1642 12.1642 13.5 11.75 13.5C11.3358 13.5 11 13.1642 11 12.75V7.75C11 7.33579 11.3358 7 11.75 7Z", + fill: "currentColor" + }), /*#__PURE__*/_react.default.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M11.75 2C17.1348 2 21.5 6.36522 21.5 11.75C21.5 17.1348 17.1348 21.5 11.75 21.5C6.36522 21.5 2 17.1348 2 11.75C2 6.36522 6.36522 2 11.75 2ZM11.75 3.5C7.19365 3.5 3.5 7.19365 3.5 11.75C3.5 16.3063 7.19365 20 11.75 20C16.3063 20 20 16.3063 20 11.75C20 7.19365 16.3063 3.5 11.75 3.5Z", + fill: "currentColor" + })), + sx: { + backgroundColor: 'transparent', + p: 0 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + color: "text.primary" + }, /*#__PURE__*/_react.default.createElement("strong", null, (0, _i18n.__)('Note:', 'elementor-pro')), " ", (0, _i18n.__)('The media will be uploaded automatically, just as it was saved during export', 'elementor-pro')))); + } + if (!isImport && !isCloudKitsEligible) { + return null; + } + return /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + ref: mediaFormatSectionRef, + description: (0, _i18n.__)('Select how do you want to save & export the media files.', 'elementor-pro'), + title: (0, _i18n.__)('Media format', 'elementor-pro'), + settingKey: "mediaFormat", + hasToggle: false, + disabled: !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + pt: 2.5 + } + }, /*#__PURE__*/_react.default.createElement(_ui.FormControl, { + component: "fieldset", + disabled: !(0, _useTier.isHighTier)(), + sx: { + width: '100%' + } + }, /*#__PURE__*/_react.default.createElement(_ui.RadioGroup, { + value: settings.mediaFormat, + onChange: event => { + handleSettingsChange('mediaFormat', event.target.value); + }, + sx: { + width: '100%' + } + }, MEDIA_FORMAT_CONFIG.map((option, index) => /*#__PURE__*/_react.default.createElement(_ui.Box, { + key: option.value, + sx: { + border: 1, + borderColor: settings.mediaFormat === option.value ? 'info.light' : 'divider', + borderRadius: 2, + p: 1, + mb: index < MEDIA_FORMAT_CONFIG.length - 1 ? 1.5 : 0, + width: '100%' + } + }, /*#__PURE__*/_react.default.createElement(_ui.FormControlLabel, { + value: option.value, + control: /*#__PURE__*/_react.default.createElement(_ui.Radio, { + color: "info", + "data-testid": `media-format-${option.value}` + }), + label: /*#__PURE__*/_react.default.createElement(_ui.Box, null, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + sx: { + mb: 0.25 + } + }, option.title), /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + color: "text.secondary" + }, option.description)), + sx: { + alignItems: 'flex-start', + m: 0, + width: '100%' + } + }))))), showMediaFormatValidation && /*#__PURE__*/_react.default.createElement(_ui.Alert, { + ref: alertRef, + icon: /*#__PURE__*/_react.default.createElement(_ui.SvgIcon, { + color: "error", + viewBox: "0 0 24 24" + }, /*#__PURE__*/_react.default.createElement("path", { + d: "M11.8623 14.7549C12.3665 14.8061 12.7598 15.2322 12.7598 15.75C12.7598 16.2678 12.3665 16.6939 11.8623 16.7451L11.7598 16.75H11.75C11.1977 16.75 10.75 16.3023 10.75 15.75C10.75 15.1977 11.1977 14.75 11.75 14.75H11.7598L11.8623 14.7549Z", + fill: "currentColor" + }), /*#__PURE__*/_react.default.createElement("path", { + d: "M11.75 7C12.1642 7 12.5 7.33579 12.5 7.75V12.75C12.5 13.1642 12.1642 13.5 11.75 13.5C11.3358 13.5 11 13.1642 11 12.75V7.75C11 7.33579 11.3358 7 11.75 7Z", + fill: "currentColor" + }), /*#__PURE__*/_react.default.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M11.75 2C17.1348 2 21.5 6.36522 21.5 11.75C21.5 17.1348 17.1348 21.5 11.75 21.5C6.36522 21.5 2 17.1348 2 11.75C2 6.36522 6.36522 2 11.75 2ZM11.75 3.5C7.19365 3.5 3.5 7.19365 3.5 11.75C3.5 16.3063 7.19365 20 11.75 20C16.3063 20 20 16.3063 20 11.75C20 7.19365 16.3063 3.5 11.75 3.5Z", + fill: "currentColor" + })), + sx: { + mt: 2, + ml: 1, + backgroundColor: 'transparent', + p: 0 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + color: "text.primary" + }, /*#__PURE__*/_react.default.createElement("strong", null, (0, _i18n.__)('Note:', 'elementor-pro')), " ", (0, _i18n.__)('To export a ZIP, go to Edit Content, choose \'Link to Media\', then Export as ZIP.', 'elementor-pro'), /*#__PURE__*/_react.default.createElement("br", null), (0, _i18n.__)('Or, save this template to the cloud instead.', 'elementor-pro'))))); + }; + const renderTaxonomiesSection = () => { + if (isImport && isOldExport) { + return null; + } + return /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + description: (0, _i18n.__)('Group your content by type, topic, or any structure you choose.', 'elementor-pro'), + title: (0, _i18n.__)('Taxonomies', 'elementor-pro'), + settingKey: "taxonomies", + notExported: isImport && !isTaxonomiesExported(), + hasToggle: false + }, isTaxonomiesLoading ? /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + p: 1, + alignItems: 'center', + textAlign: 'center' + } + }, /*#__PURE__*/_react.default.createElement(_ui.CircularProgress, { + size: 30 + })) : taxonomyOptions.map(taxonomy => { + return /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + key: taxonomy.value, + label: taxonomy.label, + settingKey: "taxonomies", + checked: settings.taxonomies.includes(taxonomy.value), + disabled: !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)(), + onSettingChange: (key, isChecked) => { + setSettings(prevState => { + const selectedTaxonomies = isChecked ? [...prevState.taxonomies, taxonomy.value] : prevState.taxonomies.filter(value => value !== taxonomy.value); + return { + ...prevState, + taxonomies: selectedTaxonomies + }; + }); + } + }); + })); + }; + return /*#__PURE__*/_react.default.createElement(_kitCustomizationDialog.KitCustomizationDialog, { + open: open, + title: (0, _i18n.__)('Edit content', 'elementor-pro'), + handleClose: handleClose, + handleSaveChanges: () => { + const hasEnabledCustomization = settings.pages.length > 0 || settings.menus || settings.customPostTypes.length > 0 || settings.taxonomies.length > 0 || settings.mediaFormat !== MEDIA_FORMAT_OPTIONS.LINK; + const transformedAnalytics = transformAnalyticsData(settings, pageOptions, taxonomyOptions, customPostTypes); + handleSaveChanges('content', settings, hasEnabledCustomization, transformedAnalytics); + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + sx: { + position: 'relative' + }, + gap: 2 + }, isOldElementorVersion && /*#__PURE__*/_react.default.createElement(_upgradeVersionBanner.UpgradeVersionBanner, null), /*#__PURE__*/_react.default.createElement(_ui.Stack, null, renderPagesSection(), isImport && !isCustomPostTypesExported() ? /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + title: (0, _i18n.__)('Custom post types', 'elementor-pro'), + settingKey: "customPostTypes", + notExported: true + }) : /*#__PURE__*/_react.default.createElement(_customizationListSettingSection.ListSettingSection, { + settingKey: "customPostTypes", + title: (0, _i18n.__)('Custom post types', 'elementor-pro'), + onSettingChange: selectedCustomPostTypes => { + handleSettingsChange('customPostTypes', selectedCustomPostTypes); + }, + settings: settings.customPostTypes, + items: customPostTypes, + disabled: isImport && undefined === data?.uploadedData?.manifest['custom-post-type-title'] || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), renderMediaFormatSection(), renderMenusSection(), renderTaxonomiesSection()), /*#__PURE__*/_react.default.createElement(_upgradeNoticeBanner.UpgradeNoticeBanner, null))); +} +KitContentCustomizationDialog.propTypes = { + open: PropTypes.bool.isRequired, + isImport: PropTypes.bool, + isOldExport: PropTypes.bool, + isOldElementorVersion: PropTypes.bool, + handleClose: PropTypes.func.isRequired, + handleSaveChanges: PropTypes.func.isRequired, + data: PropTypes.object.isRequired, + isCloudKitsEligible: PropTypes.bool, + showMediaFormatValidation: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js": +/*!********************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js ***! + \********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.KitCustomizationDialog = KitCustomizationDialog; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +function KitCustomizationDialog({ + open, + title, + handleClose, + handleSaveChanges, + children, + saveDisabled = false +}) { + return /*#__PURE__*/_react.default.createElement(_ui.Dialog, { + open: open, + onClose: handleClose, + maxWidth: "md", + fullWidth: true + }, /*#__PURE__*/_react.default.createElement(_ui.DialogHeader, { + onClose: handleClose + }, /*#__PURE__*/_react.default.createElement(_ui.DialogTitle, null, title)), /*#__PURE__*/_react.default.createElement(_ui.DialogContent, { + dividers: true, + sx: { + pt: 3, + px: 3, + pb: 0 + } + }, children), /*#__PURE__*/_react.default.createElement(_ui.DialogActions, null, /*#__PURE__*/_react.default.createElement(_ui.Button, { + onClick: handleClose, + color: "secondary" + }, (0, _i18n.__)('Cancel', 'elementor')), /*#__PURE__*/_react.default.createElement(_ui.Button, { + disabled: saveDisabled, + onClick: () => { + handleSaveChanges(); + handleClose(); + }, + variant: "contained", + color: "primary" + }, (0, _i18n.__)('Save changes', 'elementor')))); +} +KitCustomizationDialog.propTypes = { + open: PropTypes.bool.isRequired, + handleClose: PropTypes.func.isRequired, + handleSaveChanges: PropTypes.func.isRequired, + children: PropTypes.node.isRequired, + title: PropTypes.string.isRequired, + saveDisabled: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/kit-settings-customization-dialog.js": +/*!*****************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/kit-settings-customization-dialog.js ***! + \*****************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.KitSettingsCustomizationDialog = KitSettingsCustomizationDialog; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _customizationSettingSection = __webpack_require__(/*! ./customization-setting-section */ "../core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js"); +var _customizationSubSetting = __webpack_require__(/*! ./customization-sub-setting */ "../core/app/modules/import-export-customization/assets/js/components/customization-sub-setting.js"); +var _kitCustomizationDialog = __webpack_require__(/*! ./kit-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js"); +var _upgradeNoticeBanner = __webpack_require__(/*! ./upgrade-notice-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js"); +var _useTier = __webpack_require__(/*! ../hooks/use-tier */ "../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js"); +var _upgradeVersionBanner = __webpack_require__(/*! ./upgrade-version-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js"); +var _analyticsTransformer = __webpack_require__(/*! ../utils/analytics-transformer */ "../core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const transformAnalyticsData = payload => { + const transformed = {}; + for (const [key, value] of Object.entries(payload)) { + transformed[key] = (0, _analyticsTransformer.transformValueForAnalytics)(key, value, []); + } + return transformed; +}; +function KitSettingsCustomizationDialog({ + open, + handleClose, + handleSaveChanges, + data, + isImport, + isOldExport, + isOldElementorVersion +}) { + const getState = (0, _react.useCallback)(initialState => { + if (!data.includes.includes('settings')) { + return { + theme: initialState, + globalColors: initialState, + globalFonts: initialState, + themeStyleSettings: initialState, + generalSettings: initialState, + experiments: initialState, + customFonts: initialState, + customIcons: initialState, + customCode: initialState + }; + } + if (isImport) { + const manifestData = data?.uploadedData?.manifest?.['site-settings']; + let themeState = false; + if (isOldExport) { + themeState = !initialState ? false : data?.uploadedData?.manifest?.theme; + } else { + themeState = manifestData?.theme ?? initialState; + } + return { + theme: themeState, + globalColors: isOldExport ? true : manifestData?.globalColors ?? initialState, + globalFonts: isOldExport ? true : manifestData?.globalFonts ?? initialState, + themeStyleSettings: isOldExport ? true : manifestData?.themeStyleSettings ?? initialState, + generalSettings: isOldExport ? true : manifestData?.generalSettings ?? initialState, + experiments: isOldExport ? true : manifestData?.experiments ?? initialState, + customFonts: isOldExport ? true : manifestData?.customFonts ?? initialState, + customIcons: isOldExport ? true : manifestData?.customIcons ?? initialState, + customCode: isOldExport ? true : manifestData?.customCode ?? initialState + }; + } + const customization = data?.customization?.settings; + return { + theme: customization?.theme ?? initialState, + globalColors: customization?.globalColors ?? initialState, + globalFonts: customization?.globalFonts ?? initialState, + themeStyleSettings: customization?.themeStyleSettings ?? initialState, + generalSettings: customization?.generalSettings ?? initialState, + experiments: customization?.experiments ?? initialState, + customFonts: customization?.customFonts ?? initialState, + customIcons: customization?.customIcons ?? initialState, + customCode: customization?.customCode ?? initialState + }; + }, [data.includes, data?.uploadedData?.manifest, data?.customization?.settings, isImport, isOldExport]); + const initialState = data.includes.includes('settings'); + const [settings, setSettings] = (0, _react.useState)(() => { + if (data.customization.settings) { + return data.customization.settings; + } + return getState(initialState); + }); + (0, _react.useEffect)(() => { + if (open) { + if (data.customization.settings) { + setSettings(data.customization.settings); + } else { + const state = getState(initialState); + setSettings(state); + } + } + }, [open, data.customization.settings, data?.uploadedData, initialState, getState]); + (0, _react.useEffect)(() => { + if (open) { + window.elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit); + } + }, [open]); + const handleToggleChange = settingKey => { + setSettings(prev => ({ + ...prev, + [settingKey]: !prev[settingKey] + })); + }; + return /*#__PURE__*/_react.default.createElement(_kitCustomizationDialog.KitCustomizationDialog, { + open: open, + title: (0, _i18n.__)('Edit settings & configurations', 'elementor'), + handleClose: handleClose, + handleSaveChanges: () => { + const hasEnabledCustomization = settings.theme || settings.globalColors || settings.globalFonts || settings.themeStyleSettings || settings.generalSettings || settings.experiments || settings.customFonts || settings.customIcons || settings.customCode; + const transformedAnalytics = transformAnalyticsData(settings); + handleSaveChanges('settings', settings, hasEnabledCustomization, transformedAnalytics); + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + sx: { + position: 'relative' + }, + gap: 2 + }, isOldElementorVersion && /*#__PURE__*/_react.default.createElement(_upgradeVersionBanner.UpgradeVersionBanner, null), /*#__PURE__*/_react.default.createElement(_ui.Stack, null, /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: settings.theme, + title: (0, _i18n.__)('Theme', 'elementor'), + description: (0, _i18n.__)('Only public WordPress themes are supported', 'elementor'), + settingKey: "theme", + onSettingChange: handleToggleChange, + notExported: isImport && !data?.uploadedData?.manifest.theme + }), !isOldExport && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + title: (0, _i18n.__)('Site settings', 'elementor'), + hasToggle: false + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, null, /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Global colors', 'elementor'), + settingKey: "globalColors", + onSettingChange: handleToggleChange, + checked: settings.globalColors, + disabled: isImport && !data?.uploadedData?.manifest?.['site-settings']?.globalColors || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Global fonts', 'elementor'), + settingKey: "globalFonts", + onSettingChange: handleToggleChange, + checked: settings.globalFonts, + disabled: isImport && !data?.uploadedData?.manifest?.['site-settings']?.globalFonts || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Theme style settings', 'elementor'), + settingKey: "themeStyleSettings", + onSettingChange: handleToggleChange, + checked: settings.themeStyleSettings, + disabled: isImport && !data?.uploadedData?.manifest?.['site-settings']?.themeStyleSettings || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }))), /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: settings.generalSettings, + title: (0, _i18n.__)('Settings', 'elementor'), + description: (0, _i18n.__)('Include site identity, background, layout, Lightbox, page transitions, and custom CSS', 'elementor'), + settingKey: "generalSettings", + onSettingChange: handleToggleChange, + disabled: isImport && !data?.uploadedData?.manifest?.['site-settings']?.generalSettings || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: settings.experiments, + title: (0, _i18n.__)('Experiments', 'elementor'), + description: (0, _i18n.__)('This will apply all experiments that are still active during import', 'elementor'), + settingKey: "experiments", + onSettingChange: handleToggleChange, + disabled: isImport && !data?.uploadedData?.manifest?.experiments || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + title: (0, _i18n.__)('Custom files', 'elementor'), + hasToggle: false + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, null, /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Custom fonts', 'elementor'), + settingKey: "customFonts", + onSettingChange: handleToggleChange, + checked: settings.customFonts, + disabled: isImport && !data?.uploadedData?.manifest?.['custom-fonts'] || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Custom icons', 'elementor'), + settingKey: "customIcons", + onSettingChange: handleToggleChange, + checked: settings.customIcons, + disabled: isImport && !data?.uploadedData?.manifest?.['custom-icons'] || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_customizationSubSetting.SubSetting, { + label: (0, _i18n.__)('Custom code', 'elementor'), + settingKey: "customCode", + onSettingChange: handleToggleChange, + checked: settings.customCode, + disabled: isImport && !data?.uploadedData?.manifest?.['custom-code'] || !(0, _useTier.isHighTier)(), + tooltip: !(0, _useTier.isHighTier)() + }))))), /*#__PURE__*/_react.default.createElement(_upgradeNoticeBanner.UpgradeNoticeBanner, null))); +} +KitSettingsCustomizationDialog.propTypes = { + open: PropTypes.bool.isRequired, + isImport: PropTypes.bool, + isOldExport: PropTypes.bool, + isOldElementorVersion: PropTypes.bool, + handleClose: PropTypes.func.isRequired, + handleSaveChanges: PropTypes.func.isRequired, + data: PropTypes.object.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/kit-templates-customization-dialog.js": +/*!******************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/kit-templates-customization-dialog.js ***! + \******************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.KitTemplatesCustomizationDialog = KitTemplatesCustomizationDialog; +exports.hasTemplatesForExportGroup = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _customizationSettingSection = __webpack_require__(/*! ./customization-setting-section */ "../core/app/modules/import-export-customization/assets/js/components/customization-setting-section.js"); +var _kitCustomizationDialog = __webpack_require__(/*! ./kit-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-customization-dialog.js"); +var _upgradeNoticeBanner = __webpack_require__(/*! ./upgrade-notice-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js"); +var _useTier = __webpack_require__(/*! ../hooks/use-tier */ "../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js"); +var _themeBuilderCustomization = __webpack_require__(/*! ./theme-builder-customization */ "../core/app/modules/import-export-customization/assets/js/components/theme-builder-customization.js"); +var _upgradeVersionBanner = __webpack_require__(/*! ./upgrade-version-banner */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js"); +var _analyticsTransformer = __webpack_require__(/*! ../utils/analytics-transformer */ "../core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const transformAnalyticsData = payload => { + const transformed = {}; + for (const [key, value] of Object.entries(payload)) { + transformed[key] = (0, _analyticsTransformer.transformValueForAnalytics)(key, value, []); + } + return transformed; +}; +const hasTemplatesForExportGroup = (exportGroup, manifest) => { + if (!manifest?.templates) { + return false; + } + const exportGroups = elementorAppConfig?.['import-export-customization']?.exportGroups || {}; + return Object.values(manifest.templates).some(template => { + if (!template || typeof template !== 'object' || !template.doc_type) { + return false; + } + const templateExportGroup = exportGroups[template.doc_type]; + return templateExportGroup === exportGroup; + }); +}; +exports.hasTemplatesForExportGroup = hasTemplatesForExportGroup; +function KitTemplatesCustomizationDialog({ + open, + handleClose, + handleSaveChanges, + data, + isImport, + isOldExport, + isOldElementorVersion +}) { + const initialState = data.includes.includes('templates'); + const getState = (0, _react.useCallback)(parentInitialState => { + if (!data.includes.includes('templates')) { + return { + siteTemplates: { + enabled: parentInitialState + }, + themeBuilder: { + enabled: parentInitialState + }, + globalWidgets: { + enabled: parentInitialState + } + }; + } + if (isImport) { + return { + siteTemplates: { + enabled: isImport && isOldExport ? true : hasTemplatesForExportGroup('site-templates', data?.uploadedData?.manifest) ?? parentInitialState + }, + themeBuilder: { + enabled: isImport && isOldExport ? true : hasTemplatesForExportGroup('theme-builder', data?.uploadedData?.manifest) ?? parentInitialState + }, + globalWidgets: { + enabled: isImport && isOldExport ? true : hasTemplatesForExportGroup('global-widget', data?.uploadedData?.manifest) ?? parentInitialState + } + }; + } + return { + siteTemplates: { + enabled: data?.customization?.templates?.siteTemplates?.enabled ?? parentInitialState + }, + themeBuilder: { + enabled: data?.customization?.templates?.themeBuilder?.enabled ?? parentInitialState + }, + globalWidgets: { + enabled: data?.customization?.templates?.globalWidgets?.enabled ?? parentInitialState + } + }; + }, [data.includes, data?.uploadedData?.manifest, data?.customization?.templates, isImport, isOldExport]); + const [templates, setTemplates] = (0, _react.useState)({}); + (0, _react.useEffect)(() => { + if (open) { + if (data.customization.templates) { + setTemplates(data.customization.templates); + } else { + const state = getState(initialState); + setTemplates(state); + } + } + }, [open, data.customization.templates, data?.uploadedData, initialState, getState]); + (0, _react.useEffect)(() => { + if (open) { + elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit); + } + }, [open]); + const handleToggleChange = (settingKey, isChecked) => { + setTemplates(prev => ({ + ...prev, + [settingKey]: { + ...prev[settingKey], + enabled: isChecked + } + })); + }; + return /*#__PURE__*/_react.default.createElement(_kitCustomizationDialog.KitCustomizationDialog, { + open: open, + title: (0, _i18n.__)('Edit templates', 'elementor'), + handleClose: handleClose, + handleSaveChanges: () => { + const hasEnabledCustomization = templates.siteTemplates?.enabled || templates.themeBuilder?.enabled || templates.globalWidgets?.enabled; + const transformedAnalytics = transformAnalyticsData(templates); + handleSaveChanges('templates', templates, hasEnabledCustomization, transformedAnalytics); + }, + minHeight: "auto" + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + sx: { + position: 'relative' + }, + gap: 2 + }, isOldElementorVersion && /*#__PURE__*/_react.default.createElement(_upgradeVersionBanner.UpgradeVersionBanner, null), /*#__PURE__*/_react.default.createElement(_ui.Stack, null, !isOldExport && /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: templates.siteTemplates?.enabled || false, + title: (0, _i18n.__)('Site Templates', 'elementor'), + settingKey: "siteTemplates", + onSettingChange: handleToggleChange, + disabled: !(0, _useTier.isHighTier)() || isImport && !hasTemplatesForExportGroup('site-templates', data?.uploadedData?.manifest), + tooltip: !(0, _useTier.isHighTier)() + }), /*#__PURE__*/_react.default.createElement(_themeBuilderCustomization.ThemeBuilderCustomization, { + state: templates.themeBuilder, + settingKey: "themeBuilder", + onStateChange: (key, newState, mergeMode = false) => { + setTemplates(prev => { + if (mergeMode) { + return { + ...prev, + [key]: { + ...prev[key], + ...newState + } + }; + } + return { + ...prev, + [key]: newState + }; + }); + }, + data: data, + disabled: !(0, _useTier.isHighTier)() || isImport && !hasTemplatesForExportGroup('theme-builder', data?.uploadedData?.manifest), + tooltip: !(0, _useTier.isHighTier)() + }), !isOldExport && /*#__PURE__*/_react.default.createElement(_customizationSettingSection.SettingSection, { + checked: templates.globalWidgets?.enabled || false, + title: "Global Widgets", + settingKey: "globalWidgets", + onSettingChange: handleToggleChange, + disabled: !(0, _useTier.isHighTier)() || isImport && !hasTemplatesForExportGroup('global-widget', data?.uploadedData?.manifest), + tooltip: !(0, _useTier.isHighTier)() + })), /*#__PURE__*/_react.default.createElement(_upgradeNoticeBanner.UpgradeNoticeBanner, null))); +} +KitTemplatesCustomizationDialog.propTypes = { + open: PropTypes.bool.isRequired, + isImport: PropTypes.bool, + isOldExport: PropTypes.bool, + isOldElementorVersion: PropTypes.bool, + handleClose: PropTypes.func.isRequired, + handleSaveChanges: PropTypes.func.isRequired, + data: PropTypes.object.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/theme-builder-customization.js": +/*!***********************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/theme-builder-customization.js ***! + \***********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ThemeBuilderCustomization = ThemeBuilderCustomization; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _upgradeTooltip = __webpack_require__(/*! ./upgrade-tooltip */ "../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ExternalLinkIcon = props => { + return /*#__PURE__*/_react.default.createElement(_ui.SvgIcon, (0, _extends2.default)({ + viewBox: "0 0 18 18", + sx: { + fontSize: 16, + color: 'info.light' + } + }, props), /*#__PURE__*/_react.default.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M11 1C11 0.585786 11.3358 0.25 11.75 0.25H16.75C17.1642 0.25 17.5 0.585786 17.5 1V6C17.5 6.41421 17.1642 6.75 16.75 6.75C16.3358 6.75 16 6.41421 16 6V2.81066L7.28033 11.5303C6.98744 11.8232 6.51256 11.8232 6.21967 11.5303C5.92678 11.2374 5.92678 10.7626 6.21967 10.4697L14.9393 1.75H11.75C11.3358 1.75 11 1.41421 11 1ZM0.805456 4.05546C1.32118 3.53973 2.02065 3.25 2.75 3.25H7.75C8.16421 3.25 8.5 3.58579 8.5 4C8.5 4.41421 8.16421 4.75 7.75 4.75H2.75C2.41848 4.75 2.10054 4.8817 1.86612 5.11612C1.6317 5.35054 1.5 5.66848 1.5 6V15C1.5 15.3315 1.6317 15.6495 1.86612 15.8839C2.10054 16.1183 2.41848 16.25 2.75 16.25H11.75C12.0815 16.25 12.3995 16.1183 12.6339 15.8839C12.8683 15.6495 13 15.3315 13 15V10C13 9.58579 13.3358 9.25 13.75 9.25C14.1642 9.25 14.5 9.58579 14.5 10V15C14.5 15.7293 14.2103 16.4288 13.6945 16.9445C13.1788 17.4603 12.4793 17.75 11.75 17.75H2.75C2.02065 17.75 1.32118 17.4603 0.805456 16.9445C0.289731 16.4288 0 15.7293 0 15V6C0 5.27065 0.289731 4.57118 0.805456 4.05546Z", + fill: "currentColor" + })); +}; +function ThemeBuilderCustomization({ + state, + settingKey, + onStateChange, + data, + disabled, + tooltip = false +}) { + const isImport = data.hasOwnProperty('uploadedData'); + const [conflicts, setConflicts] = (0, _react.useState)([]); + const [loading, setLoading] = (0, _react.useState)(false); + (0, _react.useEffect)(() => { + if (state?.enabled && isImport) { + loadConflicts(); + } else { + setConflicts([]); + setLoading(false); + } + }, [state?.enabled, isImport, data]); + const loadConflicts = async () => { + setLoading(true); + try { + const actualConflicts = data?.uploadedData?.conflicts ? Object.entries(data.uploadedData.conflicts) : []; + const formattedConflicts = actualConflicts.map(([importedTemplateId, conflictsList]) => { + const importedTemplate = data?.uploadedData?.manifest?.templates?.[importedTemplateId]; + const firstConflict = conflictsList[0]; + return { + template_id: firstConflict.template_id, + template_name: firstConflict.template_title, + edit_url: firstConflict.edit_url, + imported_template_id: parseInt(importedTemplateId), + imported_template_name: importedTemplate?.title || 'Unknown Template', + location: importedTemplate?.location || '', + location_label: getTemplateTypeLabel(importedTemplateId) + }; + }); + setConflicts(formattedConflicts); + if (!state?.overrideConditions || 0 === state.overrideConditions.length) { + const defaultOverrides = formattedConflicts.map(conflict => conflict.imported_template_id); + onStateChange(settingKey, { + ...state, + overrideConditions: defaultOverrides + }); + } + } catch (error) { + setConflicts([]); + } finally { + setLoading(false); + } + }; + const getTemplateTypeLabel = templateId => { + const template = data?.uploadedData?.manifest?.templates?.[templateId]; + if (!template) { + return 'Unknown Template'; + } + const templateType = template.doc_type; + const summaryTitle = elementorAppConfig?.['import-export-customization']?.summaryTitles?.templates?.[templateType]; + return summaryTitle?.single || templateType; + }; + const handleToggleEnabled = () => { + const newState = { + enabled: !state?.enabled + }; + if (isImport) { + newState.overrideConditions = state?.enabled ? [] : state?.overrideConditions || []; + } + onStateChange(settingKey, newState); + }; + const handleConflictChoice = (location, choice, importedTemplateId) => { + const currentOverrides = state?.overrideConditions || []; + let newOverrides; + if ('imported' === choice) { + if (!currentOverrides.includes(importedTemplateId)) { + newOverrides = [...currentOverrides, importedTemplateId]; + } else { + newOverrides = currentOverrides; + } + } else { + newOverrides = currentOverrides.filter(templateId => templateId !== importedTemplateId); + } + onStateChange(settingKey, { + ...state, + overrideConditions: newOverrides + }); + }; + const getConflictChoice = importedTemplateId => { + const overrides = state?.overrideConditions || []; + const hasOverride = overrides.includes(importedTemplateId); + return hasOverride ? 'imported' : 'current'; + }; + const renderConflictTable = () => { + if (loading) { + return /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + color: "text.secondary" + }, (0, _i18n.__)('Checking for conflicts...', 'elementor-pro')); + } + return /*#__PURE__*/_react.default.createElement(_ui.Stack, { + spacing: 2 + }, /*#__PURE__*/_react.default.createElement(_ui.Alert, { + severity: "warning" + }, /*#__PURE__*/_react.default.createElement(_ui.AlertTitle, { + key: "title" + }, (0, _i18n.__)('Conflicted part', 'elementor-pro')), (0, _i18n.__)('Some parts are in conflict. Choose which one you want to assign.', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_ui.TableContainer, { + component: _ui.Box, + sx: { + maxWidth: '100%', + border: 1, + borderRadius: 1, + borderColor: 'action.focus' + } + }, /*#__PURE__*/_react.default.createElement(_ui.Table, { + size: "small" + }, /*#__PURE__*/_react.default.createElement(_ui.TableHead, null, /*#__PURE__*/_react.default.createElement(_ui.TableRow, null, /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, (0, _i18n.__)('Conflicted part', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, (0, _i18n.__)('Current site part', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, (0, _i18n.__)('Imported template part', 'elementor-pro')))), /*#__PURE__*/_react.default.createElement(_ui.TableBody, null, conflicts.map((conflict, index) => /*#__PURE__*/_react.default.createElement(_ui.TableRow, { + key: index + }, /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + fontWeight: "medium" + }, getTemplateTypeLabel(conflict.imported_template_id))), /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, /*#__PURE__*/_react.default.createElement(_ui.FormControlLabel, { + control: /*#__PURE__*/_react.default.createElement(_ui.Radio, { + checked: 'current' === getConflictChoice(conflict.imported_template_id, conflict.location), + onChange: () => handleConflictChoice(conflict.location, 'current', conflict.imported_template_id), + size: "small" + }), + label: conflict.template_name + })), /*#__PURE__*/_react.default.createElement(_ui.TableCell, null, /*#__PURE__*/_react.default.createElement(_ui.FormControlLabel, { + control: /*#__PURE__*/_react.default.createElement(_ui.Radio, { + checked: 'imported' === getConflictChoice(conflict.imported_template_id, conflict.location), + onChange: () => handleConflictChoice(conflict.location, 'imported', conflict.imported_template_id), + size: "small" + }), + label: conflict.imported_template_name + })))))))); + }; + return /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + mb: 3, + border: 1, + borderRadius: 1, + borderColor: 'action.focus', + p: 2.5 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + spacing: 1 + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "h6" + }, (0, _i18n.__)('Theme builder', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_ui.Link, { + href: elementorAppConfig.base_url + '#/site-editor/templates', + target: "_blank", + rel: "noopener noreferrer", + color: "info.light", + underline: "hover", + sx: { + display: 'inline-flex', + alignItems: 'center', + gap: 0.5 + } + }, (0, _i18n.__)('Check your themes builder', 'elementor-pro'), /*#__PURE__*/_react.default.createElement(ExternalLinkIcon, null))), /*#__PURE__*/_react.default.createElement(_upgradeTooltip.UpgradeTooltip, { + disabled: disabled, + tooltip: tooltip + }, /*#__PURE__*/_react.default.createElement(_ui.Switch, { + "data-testid": `${settingKey}-switch`, + checked: state?.enabled || false, + disabled: disabled, + onChange: handleToggleEnabled, + color: "info", + size: "medium", + sx: { + alignSelf: 'center', + ...(disabled && tooltip && { + cursor: 'pointer' + }) + } + }))), state?.enabled && isImport && 0 < conflicts.length && /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + mt: 1 + } + }, renderConflictTable())); +} +ThemeBuilderCustomization.propTypes = { + state: PropTypes.object.isRequired, + settingKey: PropTypes.string.isRequired, + onStateChange: PropTypes.func.isRequired, + data: PropTypes.object.isRequired, + disabled: PropTypes.bool, + tooltip: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js": +/*!*****************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/upgrade-notice-banner.js ***! + \*****************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.UpgradeNoticeBanner = UpgradeNoticeBanner; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _useTier = __webpack_require__(/*! ../hooks/use-tier */ "../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js"); +function UpgradeNoticeBanner() { + if ((0, _useTier.isHighTier)()) { + return null; + } + return /*#__PURE__*/_react.default.createElement(_ui.Paper, { + sx: { + position: 'sticky', + bottom: 0, + marginLeft: -3, + marginRight: -3, + zIndex: 1000, + py: 2, + px: 3 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Paper, { + elevation: 0, + color: "promotion", + sx: { + borderRadius: 1, + p: 2 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + display: 'flex', + alignItems: 'flex-start', + justifyContent: 'space-between', + gap: 2 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + flex: 1, + minWidth: 0 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2", + color: "text.secondary" + }, (0, _i18n.__)('Take control of your workflow. The Expert plan lets you decide exactly what\'s included in your export/import kits, from themes to experiments so nothing gets left behind.', 'elementor'))), /*#__PURE__*/_react.default.createElement(_ui.Button, { + variant: "outlined", + color: "promotion", + onClick: () => window.open('https://go.elementor.com/go-pro-import-export', '_blank'), + startIcon: /*#__PURE__*/_react.default.createElement("span", { + className: "eicon-upgrade-crown" + }), + sx: { + flexShrink: 0, + whiteSpace: 'nowrap' + } + }, (0, _i18n.__)('Check Expert plan', 'elementor'))))); +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js": +/*!***********************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/upgrade-tooltip.js ***! + \***********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.UpgradeTooltip = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const UpgradeTooltip = ({ + children, + disabled = false, + tooltip = false, + ...props +}) => { + if (disabled && tooltip) { + return /*#__PURE__*/_react.default.createElement(_ui.Tooltip, (0, _extends2.default)({ + title: (0, _i18n.__)('Upgrade your plan to choose which elements to adjust.', 'elementor'), + placement: "top", + arrow: true, + componentsProps: { + tooltip: { + sx: { + maxWidth: 200, + fontSize: '12px', + fontWeight: 500, + lineHeight: 1.4, + textAlign: 'center', + backgroundColor: 'background.paper', + color: 'text.secondary', + padding: 1.5, + boxShadow: '0 4px 20px rgba(0, 0, 0, 0.15)' + } + }, + arrow: { + sx: { + fontSize: '1.2rem', + color: 'background.paper', + filter: 'drop-shadow(0 2px 8px rgba(0, 0, 0, 0.15))', + '&::before': { + backgroundColor: 'background.paper' + } + } + } + } + }, props), /*#__PURE__*/_react.default.createElement(_ui.Box, { + component: "span" + }, children)); + } + return children; +}; +exports.UpgradeTooltip = UpgradeTooltip; +UpgradeTooltip.propTypes = { + children: PropTypes.node.isRequired, + disabled: PropTypes.bool, + tooltip: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js": +/*!******************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/components/upgrade-version-banner.js ***! + \******************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.UpgradeVersionBanner = UpgradeVersionBanner; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +function UpgradeVersionBanner() { + return /*#__PURE__*/_react.default.createElement(_ui.Paper, { + color: "info", + elevation: 0, + variant: "elevation" + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + direction: "row", + sx: { + alignItems: 'center', + justifyContent: 'space-between', + gap: '5px', + py: 1.5, + px: 2.5 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Stack, { + direction: "row", + sx: { + alignItems: 'center', + gap: '5px' + } + }, /*#__PURE__*/_react.default.createElement(_ui.SvgIcon, { + viewBox: "0 0 22 22", + sx: { + fontSize: 16, + color: 'info.light' + } + }, /*#__PURE__*/_react.default.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M4.58268 4.35352C4.5219 4.35352 4.46361 4.37766 4.42064 4.42064C4.37766 4.46361 4.35352 4.5219 4.35352 4.58268V6.64518H6.64518V4.35352H4.58268ZM4.58268 2.97852C4.15723 2.97852 3.7492 3.14753 3.44837 3.44837C3.14753 3.7492 2.97852 4.15723 2.97852 4.58268V17.416C2.97852 17.8415 3.14753 18.2495 3.44837 18.5503C3.74921 18.8512 4.15723 19.0202 4.58268 19.0202H17.416C17.8415 19.0202 18.2495 18.8512 18.5503 18.5503C18.8512 18.2495 19.0202 17.8415 19.0202 17.416V4.58268C19.0202 4.15723 18.8512 3.74921 18.5503 3.44837C18.2495 3.14753 17.8415 2.97852 17.416 2.97852H4.58268ZM8.02018 4.35352V6.64518H17.6452V4.58268C17.6452 4.5219 17.621 4.46361 17.5781 4.42064C17.5351 4.37766 17.4768 4.35352 17.416 4.35352H8.02018ZM17.6452 8.02018H4.35352V17.416C4.35352 17.4768 4.37766 17.5351 4.42064 17.5781C4.46361 17.621 4.5219 17.6452 4.58268 17.6452H17.416C17.4768 17.6452 17.5351 17.621 17.5781 17.5781C17.621 17.5351 17.6452 17.4768 17.6452 17.416V8.02018Z", + fill: "currentColor" + })), /*#__PURE__*/_react.default.createElement(_ui.Typography, { + variant: "body2" + }, __('You’re using an older Elementor version. Update for full customization.', 'elementor'))), /*#__PURE__*/_react.default.createElement(_ui.Button, { + variant: "outlined", + onClick: () => window.open(elementorAppConfig['import-export-customization']?.upgradeVersionUrl, '_blank'), + color: "info" + }, __('Update version', 'elementor')))); +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-custom-post-types.js": +/*!************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-custom-post-types.js ***! + \************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.useCustomPostTypes = useCustomPostTypes; +var _react = __webpack_require__(/*! react */ "react"); +function useCustomPostTypes({ + include = [] +} = {}) { + const [customPostTypes, setCustomPostTypes] = (0, _react.useState)([]); + (0, _react.useEffect)(() => { + const cpt = Object.assign({}, elementorAppConfig['import-export-customization']?.summaryTitles?.content?.customPostTypes || {}); + if (include.length) { + Object.entries(elementorAppConfig['import-export-customization']?.summaryTitles?.content || {}).forEach(([postType, post]) => { + if (include.includes(postType)) { + cpt[postType] = post; + } + }); + } + if (Object.keys(cpt).length) { + setCustomPostTypes(Object.entries(cpt).map(([postType, post]) => ({ + value: postType, + label: post.single + }))); + } + }, []); + return { + customPostTypes + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-custom-post-types.js": +/*!******************************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-custom-post-types.js ***! + \******************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.useKitCustomizationCustomPostTypes = useKitCustomizationCustomPostTypes; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var _react = __webpack_require__(/*! react */ "react"); +var _useCustomPostTypes = __webpack_require__(/*! ./use-custom-post-types */ "../core/app/modules/import-export-customization/assets/js/hooks/use-custom-post-types.js"); +function useKitCustomizationCustomPostTypes({ + data +}) { + const isImport = data?.hasOwnProperty('uploadedData'); + const { + customPostTypes: builtInCustomPostTypes + } = (0, _useCustomPostTypes.useCustomPostTypes)({ + include: ['post'] + }); + const customPostTypes = (0, _react.useMemo)(() => { + if (!isImport) { + return builtInCustomPostTypes; + } + const customPostTypesTitles = Object.values(data?.uploadedData?.manifest?.['custom-post-type-title'] || {}).map(postType => { + return { + value: postType.name, + label: postType.label + }; + }); + if (!customPostTypesTitles.some(postType => 'post' === postType.value)) { + customPostTypesTitles.push({ + value: 'post', + label: 'Post' + }); + } + const wpContent = data?.uploadedData?.manifest?.['wp-content'] || {}; + const content = data?.uploadedData?.manifest?.content || {}; + return customPostTypesTitles.filter(postType => { + const postTypeValue = postType.value; + const wpContentObject = wpContent[postTypeValue]; + const isInWpContent = wpContentObject && 'object' === typeof wpContentObject && Object.keys(wpContentObject).length > 0; + const contentObject = content[postTypeValue]; + const isInElementorContent = contentObject && 'object' === typeof contentObject && Object.keys(contentObject).length > 0; + return isInWpContent || isInElementorContent; + }); + }, [isImport, data?.uploadedData, builtInCustomPostTypes]); + return { + customPostTypes + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-pages.js": +/*!******************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-pages.js ***! + \******************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.useKitCustomizationPages = useKitCustomizationPages; +var _react = __webpack_require__(/*! react */ "react"); +var _usePages = __webpack_require__(/*! ./use-pages */ "../core/app/modules/import-export-customization/assets/js/hooks/use-pages.js"); +function useKitCustomizationPages({ + data, + open +}) { + const isImport = data?.hasOwnProperty('uploadedData'); + const { + isLoading, + pageOptions: loadedPagesOptions, + isLoaded + } = (0, _usePages.usePages)({ + skipLoading: isImport || !open + }); + const pageOptions = (0, _react.useMemo)(() => { + if (!isImport) { + return loadedPagesOptions; + } + const elementorPages = Object.entries(data?.uploadedData?.manifest?.content?.page || {}).map(([id, page]) => { + return { + value: id, + label: page.title + }; + }); + const wpPages = Object.entries(data?.uploadedData?.manifest?.['wp-content']?.page || {}).map(([id, page]) => { + return { + value: id, + label: page.title + }; + }); + return [...elementorPages, ...wpPages]; + }, [loadedPagesOptions, isImport, data?.uploadedData]); + return { + isLoading, + pageOptions, + isLoaded + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-taxonomies.js": +/*!***********************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-kit-customization-taxonomies.js ***! + \***********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.useKitCustomizationTaxonomies = useKitCustomizationTaxonomies; +var _react = __webpack_require__(/*! react */ "react"); +var _useTaxonomies = __webpack_require__(/*! ./use-taxonomies */ "../core/app/modules/import-export-customization/assets/js/hooks/use-taxonomies.js"); +function useKitCustomizationTaxonomies({ + data, + open +}) { + const isImport = data?.hasOwnProperty('uploadedData'); + const { + isLoading, + taxonomyOptions: loadedTaxonomyOptions, + isLoaded + } = (0, _useTaxonomies.useTaxonomies)({ + skipLoading: isImport || !open, + exclude: ['nav_menu'] + }); + const taxonomyOptions = (0, _react.useMemo)(() => { + if (!isImport) { + return loadedTaxonomyOptions; + } + const taxonomiesMap = {}; + Object.values(data?.uploadedData?.manifest?.taxonomies || {}).forEach(taxonomiesListForPostType => { + taxonomiesListForPostType.forEach(taxonomy => { + const taxonomyObj = 'string' === typeof taxonomy + // BC For Old Export + ? { + name: taxonomy, + label: taxonomy.split('_').join(' ') + } : taxonomy; + if (!taxonomiesMap[taxonomyObj.name]) { + taxonomiesMap[taxonomyObj.name] = { + value: taxonomyObj.name, + label: taxonomyObj.label + }; + } + }); + }); + return Object.values(taxonomiesMap); + }, [data?.uploadedData, isImport, loadedTaxonomyOptions]); + return { + taxonomyOptions, + isLoading, + isLoaded + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-pages.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-pages.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.usePages = usePages; +var _react = __webpack_require__(/*! react */ "react"); +function usePages({ + skipLoading = false +} = {}) { + const [pages, setPages] = (0, _react.useState)([]); + const [isLoading, setIsLoading] = (0, _react.useState)(false); + const [error, setError] = (0, _react.useState)(null); + const [hasMorePages, setHasMorePages] = (0, _react.useState)(true); + const isLoaded = (0, _react.useRef)(null); + const fetchAllPages = (0, _react.useCallback)(async () => { + if (isLoaded.current) { + return; + } + try { + setIsLoading(true); + setError(null); + setPages([]); + setHasMorePages(true); + let currentPage = 1; + let allPages = []; + while (hasMorePages || 1 === currentPage) { + const baseUrl = new URL(elementorCommon.config.urls.rest, window.location.origin); + const isPlainPermalink = 'index.php' === baseUrl.pathname.replace(/\//g, ''); + baseUrl.pathname = isPlainPermalink ? baseUrl.pathname : `${baseUrl.pathname}wp/v2/pages`; + if (isPlainPermalink) { + baseUrl.searchParams.set('rest_route', '/wp/v2/pages'); + } + baseUrl.searchParams.append('page', 1); + baseUrl.searchParams.append('per_page', 100); + baseUrl.searchParams.append('_embed', ''); + const response = await fetch(baseUrl.toString(), { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': window.wpApiSettings?.nonce || '' + } + }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const totalPages = parseInt(response.headers.get('X-WP-TotalPages') || '1'); + allPages = [...allPages, ...data]; + if (totalPages <= currentPage) { + setHasMorePages(false); + break; + } + currentPage++; + } + setPages(allPages); + isLoaded.current = true; + } catch (err) { + setError(err.message); + } finally { + setIsLoading(false); + } + }, [hasMorePages]); + const refreshPages = (0, _react.useCallback)(() => { + fetchAllPages(); + }, [fetchAllPages]); + const pageOptions = (0, _react.useMemo)(() => { + return pages.map(page => ({ + value: page.id, + label: page.title.rendered + })); + }, [pages]); + (0, _react.useEffect)(() => { + if (!skipLoading) { + fetchAllPages(); + } + }, [skipLoading]); + return { + pages, + isLoading, + error, + refreshPages, + pageOptions, + isLoaded: isLoaded.current + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-taxonomies.js": +/*!*****************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-taxonomies.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.useTaxonomies = useTaxonomies; +var _react = __webpack_require__(/*! react */ "react"); +const fetchTaxonomies = async () => { + const requestUrl = `${elementorCommon.config.urls.rest}wp/v2/taxonomies`; + const response = await fetch(requestUrl, { + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': window.wpApiSettings?.nonce || '' + } + }); + const result = await response.json(); + if (!response.ok) { + const errorMessage = result?.data?.message || `HTTP error! with the following code: ${result?.data?.code}`; + throw new Error(errorMessage); + } + return Object.values(result); +}; +function useTaxonomies({ + skipLoading = false, + exclude = [] +} = {}) { + const [taxonomies, setTaxonomies] = (0, _react.useState)([]); + const [isLoading, setIsLoading] = (0, _react.useState)(false); + const [error, setError] = (0, _react.useState)(null); + const isLoaded = (0, _react.useRef)(null); + const fetchAllTaxonomies = (0, _react.useCallback)(async () => { + if (isLoaded.current) { + return; + } + try { + setIsLoading(true); + setError(null); + const data = await fetchTaxonomies(); + setTaxonomies(exclude.length ? data.filter(taxonomy => !exclude.includes(taxonomy.slug)) : data); + isLoaded.current = true; + } catch (err) { + setError(err.message); + } finally { + setIsLoading(false); + } + }, []); + const refreshTaxonomies = (0, _react.useCallback)(() => { + fetchAllTaxonomies(); + }, [fetchAllTaxonomies]); + const taxonomyOptions = (0, _react.useMemo)(() => { + return taxonomies.map(taxonomy => ({ + value: taxonomy.slug, + label: taxonomy.name + })); + }, [taxonomies]); + (0, _react.useEffect)(() => { + if (!skipLoading) { + fetchAllTaxonomies(); + } + }, [skipLoading]); + return { + taxonomies, + isLoading, + error, + refreshTaxonomies, + taxonomyOptions, + isLoaded: isLoaded.current + }; +} + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/hooks/use-tier.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isHighTier = void 0; +const isHighTier = () => { + try { + return 'expert' === elementorCommon?.config?.library_connect?.plan_type || 'agency' === elementorCommon?.config?.library_connect?.plan_type; + } catch (error) { + return false; + } +}; +exports.isHighTier = isHighTier; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/module.js": +/*!***************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/module.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _kitContentCustomizationDialog = __webpack_require__(/*! ./components/kit-content-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-content-customization-dialog.js"); +var _kitTemplatesCustomizationDialog = __webpack_require__(/*! ./components/kit-templates-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-templates-customization-dialog.js"); +var _kitSettingsCustomizationDialog = __webpack_require__(/*! ./components/kit-settings-customization-dialog */ "../core/app/modules/import-export-customization/assets/js/components/kit-settings-customization-dialog.js"); +class Module { + constructor() { + this.registerCustomizationDialogs(); + } + registerCustomizationDialogs() { + if (!elementorCommon?.config?.experimentalFeatures?.['import-export-customization']) { + return; + } + const registry = window.elementorModules?.importExport?.customizationDialogsRegistry; + if (!registry) { + return; + } + registry.register({ + key: 'content', + title: 'Content Dialog', + component: _kitContentCustomizationDialog.KitContentCustomizationDialog + }); + registry.register({ + key: 'templates', + title: 'Templates Dialog', + component: _kitTemplatesCustomizationDialog.KitTemplatesCustomizationDialog + }); + registry.register({ + key: 'settings', + title: 'Settings Dialog', + component: _kitSettingsCustomizationDialog.KitSettingsCustomizationDialog + }); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js": +/*!************************************************************************************************!*\ + !*** ../core/app/modules/import-export-customization/assets/js/utils/analytics-transformer.js ***! + \************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.transformValueForAnalytics = exports.getTotalAvailableCount = exports.ANALYTICS_TRANSFORM_RULES = void 0; +const ANALYTICS_TRANSFORM_RULES = exports.ANALYTICS_TRANSFORM_RULES = { + STRING: value => value, + BOOLEAN: value => value, + EMPTY_ARRAY: () => 'None', + FULL_ARRAY: () => 'All', + PARTIAL_ARRAY: () => 'Partial' +}; +const getTotalAvailableCount = (key, optionsArray) => { + const optionsMap = optionsArray.reduce((map, { + key: optionKey, + options + }) => { + map[optionKey] = options.length; + return map; + }, {}); + return optionsMap[key] || 0; +}; +exports.getTotalAvailableCount = getTotalAvailableCount; +const transformValueForAnalytics = (key, value, optionsArray) => { + if ('string' === typeof value || 'boolean' === typeof value) { + return ANALYTICS_TRANSFORM_RULES[(typeof value).toUpperCase()](value); + } + if ('object' === typeof value && value !== null && !Array.isArray(value) && 'enabled' in value) { + return value.enabled; + } + if (Array.isArray(value)) { + if (0 === value.length) { + return ANALYTICS_TRANSFORM_RULES.EMPTY_ARRAY(); + } + const totalAvailable = getTotalAvailableCount(key, optionsArray); + const isFullSelection = value.length === totalAvailable; + return isFullSelection ? ANALYTICS_TRANSFORM_RULES.FULL_ARRAY() : ANALYTICS_TRANSFORM_RULES.PARTIAL_ARRAY(); + } + return value; +}; +exports.transformValueForAnalytics = transformValueForAnalytics; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.js": +/*!***************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Indicator = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +__webpack_require__(/*! ./indicator-bullet.scss */ "../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.scss"); +const Indicator = props => { + let className = 'eps-indicator-bullet'; + if (props.active) { + className += ` ${className}--active`; + } + return /*#__PURE__*/_react.default.createElement("i", { + className: className + }); +}; +exports.Indicator = Indicator; +Indicator.propTypes = { + active: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/atoms/preview-iframe.js": +/*!*************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/atoms/preview-iframe.js ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = PreviewIFrame; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +__webpack_require__(/*! ./preview-iframe.scss */ "../core/app/modules/site-editor/assets/js/atoms/preview-iframe.scss"); +function PreviewIFrame(props) { + const ref = _react.default.useRef(null), + previewBreakpoint = 1200, + [scale, setScale] = _react.default.useState(1), + [height, setHeight] = _react.default.useState(0); + + // In order to make sure that the iframe itself show the content in specific viewport, + // and it should fit to the size of the card, there is a use of css props `scale` and `height`, + // and another element that wraps the iframe to be the guidelines of the iframe sizes. + _react.default.useEffect(() => { + const currentScale = ref.current.clientWidth / previewBreakpoint; + setScale(currentScale); + setHeight(ref.current.clientHeight / currentScale); + }, []); + return /*#__PURE__*/_react.default.createElement("div", { + ref: ref, + className: `site-editor__preview-iframe site-editor__preview-iframe--${props.templateType}` + }, /*#__PURE__*/_react.default.createElement("iframe", { + title: "preview", + src: props.src, + className: `site-editor__preview-iframe__iframe`, + style: { + transform: `scale(${scale})`, + height, + width: previewBreakpoint + } + })); +} +PreviewIFrame.propTypes = { + src: PropTypes.string.isRequired, + templateType: PropTypes.string.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/base-context.js": +/*!*************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/base-context.js ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var React = __webpack_require__(/*! react */ "react"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.BaseContext = void 0; +class BaseContext extends React.Component { + constructor(props) { + super(props); + this.state = { + action: { + current: null, + loading: false, + error: null, + errorMeta: {} + }, + updateActionState: this.updateActionState.bind(this), + resetActionState: this.resetActionState.bind(this) + }; + } + executeAction(name, handler) { + this.updateActionState({ + current: name, + loading: true, + error: null, + errorMeta: {} + }); + return handler().then(response => { + this.resetActionState(); + return Promise.resolve(response); + }).catch(error => { + this.updateActionState({ + current: name, + loading: false, + error: error.message, + errorMeta: error + }); + return Promise.reject(error); + }); + } + updateActionState(data) { + return this.setState(prev => ({ + action: { + ...prev.action, + ...data + } + })); + } + resetActionState() { + this.updateActionState({ + current: null, + loading: false, + error: null, + errorMeta: {} + }); + } +} +exports.BaseContext = BaseContext; +var _default = exports["default"] = BaseContext; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/conditions.js": +/*!***********************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/conditions.js ***! + \***********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Context = exports.ConditionsProvider = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _condition = _interopRequireDefault(__webpack_require__(/*! ./models/condition */ "../core/app/modules/site-editor/assets/js/context/models/condition.js")); +var _conditionsConfig = _interopRequireDefault(__webpack_require__(/*! ./services/conditions-config */ "../core/app/modules/site-editor/assets/js/context/services/conditions-config.js")); +var _baseContext = _interopRequireDefault(__webpack_require__(/*! ./base-context */ "../core/app/modules/site-editor/assets/js/context/base-context.js")); +var _commands = __webpack_require__(/*! ../data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +const Context = exports.Context = _react.default.createContext(); +class ConditionsProvider extends _baseContext.default { + static propTypes = { + children: PropTypes.any.isRequired, + currentTemplate: PropTypes.object.isRequired, + onConditionsSaved: PropTypes.func.isRequired, + validateConflicts: PropTypes.bool + }; + static defaultProps = { + validateConflicts: true + }; + static actions = { + FETCH_CONFIG: 'fetch-config', + SAVE: 'save', + CHECK_CONFLICTS: 'check-conflicts' + }; + + /** + * Holds the conditions config object. + * + * @type {ConditionsConfig} + */ + conditionsConfig = null; + + /** + * ConditionsProvider constructor. + * + * @param {any} props + */ + constructor(props) { + super(props); + this.state = { + ...this.state, + conditionsFetched: false, + conditions: {}, + updateConditionItemState: this.updateConditionItemState.bind(this), + removeConditionItemInState: this.removeConditionItemInState.bind(this), + createConditionItemInState: this.createConditionItemInState.bind(this), + findConditionItemInState: this.findConditionItemInState.bind(this), + saveConditions: this.saveConditions.bind(this) + }; + } + + /** + * Fetch the conditions config, then normalize the conditions and then setup titles for + * the subIds. + */ + componentDidMount() { + this.executeAction(ConditionsProvider.actions.FETCH_CONFIG, () => _conditionsConfig.default.create()).then(conditionsConfig => this.conditionsConfig = conditionsConfig).then(this.normalizeConditionsState.bind(this)).then(() => { + this.setSubIdTitles.bind(this); + this.setState({ + conditionsFetched: true + }); + }); + } + componentDidUpdate(prevProps, prevState) { + if (!prevState.conditionsFetched && this.state.conditionsFetched) { + this.setSubIdTitles(); + } + } + + /** + * Execute a request to save the template conditions. + * + * @return {any} Saved conditions + */ + saveConditions() { + const conditions = Object.values(this.state.conditions).map(condition => condition.forDb()); + return this.executeAction(ConditionsProvider.actions.SAVE, () => $e.data.update(_commands.TemplatesConditions.signature, { + conditions + }, { + id: this.props.currentTemplate.id + })).then(() => { + const contextConditions = Object.values(this.state.conditions).map(condition => condition.forContext()); + this.props.onConditionsSaved(this.props.currentTemplate.id, { + conditions: contextConditions, + instances: this.conditionsConfig.calculateInstances(Object.values(this.state.conditions)), + isActive: !!(Object.keys(this.state.conditions).length && 'publish' === this.props.currentTemplate.status) + }); + }); + } + + /** + * Check for conflicts in the server and mark the condition if there + * is a conflict. + * + * @param {any} condition + */ + checkConflicts(condition) { + return this.executeAction(ConditionsProvider.actions.CHECK_CONFLICTS, () => $e.data.get(_commands.TemplatesConditionsConflicts.signature, { + post_id: this.props.currentTemplate.id, + condition: condition.clone().toString() + })).then(response => this.updateConditionItemState(condition.id, { + conflictErrors: Object.values(response.data) + }, false)); + } + + /** + * Fetching subId titles. + * + * @param {any} condition + * @return {Promise} Titles + */ + fetchSubIdsTitles(condition) { + return new Promise(resolve => { + return elementorCommon.ajax.loadObjects({ + action: 'query_control_value_titles', + ids: _.isArray(condition.subId) ? condition.subId : [condition.subId], + data: { + get_titles: condition.subIdAutocomplete, + unique_id: elementorCommon.helpers.getUniqueId() + }, + success(response) { + resolve(response); + } + }); + }); + } + + /** + * Get the conditions from the template and normalize it to data structure + * that the components can work with. + */ + normalizeConditionsState() { + this.updateConditionsState(() => { + return this.props.currentTemplate.conditions.reduce((current, condition) => { + const conditionObj = new _condition.default({ + ...condition, + default: this.props.currentTemplate.defaultCondition, + options: this.conditionsConfig.getOptions(), + subOptions: this.conditionsConfig.getSubOptions(condition.name), + subIdAutocomplete: this.conditionsConfig.getSubIdAutocomplete(condition.sub), + subIdOptions: condition.subId ? [{ + value: condition.subId, + label: '' + }] : [] + }); + return { + ...current, + [conditionObj.id]: conditionObj + }; + }, {}); + }).then(() => { + Object.values(this.state.conditions).forEach(condition => this.checkConflicts(condition)); + }); + } + + /** + * Set titles to the subIds, + * for the first render of the component. + */ + setSubIdTitles() { + return Object.values(this.state.conditions).forEach(condition => { + if (!condition.subId) { + return; + } + return this.fetchSubIdsTitles(condition).then(response => this.updateConditionItemState(condition.id, { + subIdOptions: [{ + label: Object.values(response)[0], + value: condition.subId + }] + }, false)); + }); + } + + /** + * Update state of specific condition item. + * + * @param {any} id + * @param {any} args + * @param {boolean} shouldCheckConflicts + */ + updateConditionItemState(id, args, shouldCheckConflicts = true) { + if (args.name) { + args.subOptions = this.conditionsConfig.getSubOptions(args.name); + } + if (args.sub || args.name) { + args.subIdAutocomplete = this.conditionsConfig.getSubIdAutocomplete(args.sub); + + // In case that the condition has been changed, it will set the options of the subId + // to empty array to let select2 autocomplete handle the options. + args.subIdOptions = []; + } + this.updateConditionsState(prev => { + const condition = prev[id]; + return { + ...prev, + [id]: condition.clone().set(args) + }; + }).then(() => { + if (shouldCheckConflicts) { + this.checkConflicts(this.findConditionItemInState(id)); + } + }); + } + + /** + * Remove a condition item from the state. + * + * @param {any} id + */ + removeConditionItemInState(id) { + this.updateConditionsState(prev => { + const newConditions = { + ...prev + }; + delete newConditions[id]; + return newConditions; + }); + } + + /** + * Add a new condition item into the state. + * + * @param {boolean} shouldCheckConflicts + */ + createConditionItemInState(shouldCheckConflicts = true) { + const defaultCondition = this.props.currentTemplate.defaultCondition, + newCondition = new _condition.default({ + name: defaultCondition, + default: defaultCondition, + options: this.conditionsConfig.getOptions(), + subOptions: this.conditionsConfig.getSubOptions(defaultCondition), + subIdAutocomplete: this.conditionsConfig.getSubIdAutocomplete('') + }); + this.updateConditionsState(prev => ({ + ...prev, + [newCondition.id]: newCondition + })).then(() => { + if (shouldCheckConflicts) { + this.checkConflicts(newCondition); + } + }); + } + + /** + * Find a condition item from the conditions state. + * + * @param {any} id + * @return {Condition|null} Condition + */ + findConditionItemInState(id) { + return Object.values(this.state.conditions).find(c => c.id === id); + } + + /** + * Update the whole conditions state. + * + * @param {Function} callback + * @return {Promise} Conditions state + */ + updateConditionsState(callback) { + return new Promise(resolve => this.setState(prev => ({ + conditions: callback(prev.conditions) + }), resolve)); + } + + /** + * Renders the provider. + * + * @return {any} Element + */ + render() { + if (this.state.action.current === ConditionsProvider.actions.FETCH_CONFIG) { + if (this.state.error) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Error:', 'elementor-pro'), " ", this.state.error); + } + if (this.state.loading) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Loading', 'elementor-pro'), "..."); + } + } + return /*#__PURE__*/_react.default.createElement(Context.Provider, { + value: this.state + }, this.props.children); + } +} +exports.ConditionsProvider = ConditionsProvider; +var _default = exports["default"] = ConditionsProvider; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/models/condition.js": +/*!*****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/models/condition.js ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class Condition { + id = elementorCommon.helpers.getUniqueId(); + default = ''; + type = 'include'; + name = ''; + sub = ''; + subId = ''; + options = []; + subOptions = []; + subIdAutocomplete = []; + subIdOptions = []; + conflictErrors = []; + constructor(args) { + this.set(args); + } + set(args) { + Object.assign(this, args); + return this; + } + clone() { + return Object.assign(new Condition(), this); + } + remove(keys) { + if (!Array.isArray(keys)) { + keys = [keys]; + } + keys.forEach(key => { + delete this[key]; + }); + return this; + } + only(keys) { + if (!Array.isArray(keys)) { + keys = [keys]; + } + const keysToRemove = Object.keys(this).filter(conditionKey => !keys.includes(conditionKey)); + this.remove(keysToRemove); + return this; + } + toJson() { + return JSON.stringify(this); + } + toString() { + return this.forDb().filter(item => item).join('/'); + } + forDb() { + return [this.type, this.name, this.sub, this.subId]; + } + forContext() { + return { + type: this.type, + name: this.name, + sub: this.sub, + subId: this.subId + }; + } +} +exports["default"] = Condition; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/services/conditions-config.js": +/*!***************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/services/conditions-config.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ConditionsConfig = void 0; +var _commands = __webpack_require__(/*! ../../data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +class ConditionsConfig { + static instance; + config = null; + constructor(config) { + this.config = config; + } + + /** + * @return {Promise} Conditions config + */ + static create() { + if (ConditionsConfig.instance) { + return Promise.resolve(ConditionsConfig.instance); + } + return $e.data.get(_commands.ConditionsConfig.signature, {}, { + refresh: true + }).then(response => { + ConditionsConfig.instance = new ConditionsConfig(response.data); + return ConditionsConfig.instance; + }); + } + + /** + * Get main options for condition name. + * + * @return {Array} Condition options + */ + getOptions() { + return this.getSubOptions('general', true).map(({ + label, + value + }) => { + return { + label, + value + }; + }); + } + + /** + * Get the sub options for the select. + * + * @param {string} itemName + * @param {boolean} isSubItem + * @return {Array} Sub options + */ + getSubOptions(itemName, isSubItem = false) { + const config = this.config[itemName]; + if (!config) { + return []; + } + return [{ + label: config.all_label, + value: isSubItem ? itemName : '' + }, ...config.sub_conditions.map(subName => { + const subConfig = this.config[subName]; + return { + label: subConfig.label, + value: subName, + children: subConfig.sub_conditions.length ? this.getSubOptions(subName, true) : null + }; + })]; + } + + /** + * Get the autocomplete property from the conditions config + * + * @param {string} sub + * @return {{}|any} Conditions autocomplete + */ + getSubIdAutocomplete(sub) { + const config = this.config[sub]; + if (!config || !('object' === typeof config.controls)) { + return {}; + } + const controls = Object.values(config.controls); + if (!controls?.[0]?.autocomplete) { + return {}; + } + return controls[0].autocomplete; + } + + /** + * Calculate instances from the conditions. + * + * @param {Array} conditions + * @return {Object} Conditions Instances + */ + calculateInstances(conditions) { + let instances = conditions.reduce((current, condition) => { + if ('exclude' === condition.type) { + return current; + } + const key = condition.sub || condition.name, + config = this.config[key]; + if (!config) { + return current; + } + const instanceLabel = condition.subId ? `${config.label} #${condition.subId}` : config.all_label; + return { + ...current, + [key]: instanceLabel + }; + }, {}); + if (0 === Object.keys(instances).length) { + instances = [__('No instances', 'elementor-pro')]; + } + return instances; + } +} +exports.ConditionsConfig = ConditionsConfig; +var _default = exports["default"] = ConditionsConfig; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/templates.js": +/*!**********************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/templates.js ***! + \**********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesProvider = exports.Context = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _baseContext = _interopRequireDefault(__webpack_require__(/*! ./base-context */ "../core/app/modules/site-editor/assets/js/context/base-context.js")); +var _commands = __webpack_require__(/*! ../data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +var _component = _interopRequireDefault(__webpack_require__(/*! ../data/component */ "../core/app/modules/site-editor/assets/js/data/component.js")); +const Context = exports.Context = _react.default.createContext(); +class TemplatesProvider extends _baseContext.default { + static propTypes = { + children: PropTypes.object.isRequired + }; + static actions = { + FETCH: 'fetch', + DELETE: 'delete', + UPDATE: 'update', + IMPORT: 'import' + }; + constructor(props) { + super(props); + this.state = { + ...this.state, + action: { + ...this.state.action, + current: TemplatesProvider.actions.FETCH, + loading: true + }, + templates: {}, + updateTemplateItemState: this.updateTemplateItemState.bind(this), + findTemplateItemInState: this.findTemplateItemInState.bind(this), + fetchTemplates: this.fetchTemplates.bind(this), + deleteTemplate: this.deleteTemplate.bind(this), + updateTemplate: this.updateTemplate.bind(this), + importTemplates: this.importTemplates.bind(this) + }; + } + componentDidMount() { + this.fetchTemplates(); + } + importTemplates({ + fileName, + fileData + }) { + return this.executeAction(TemplatesProvider.actions.IMPORT, () => $e.data.create(_commands.Templates.signature, { + fileName, + fileData + })).then(response => { + this.updateTemplatesState(prev => ({ + ...prev, + ...Object.values(response.data).reduce((current, template) => { + if (!template.supportsSiteEditor) { + return current; + } + return { + ...current, + [template.id]: template + }; + }, {}) + })); + return response; + }); + } + deleteTemplate(id) { + return this.executeAction(TemplatesProvider.actions.DELETE, () => $e.data.delete(_commands.Templates.signature, { + id + })).then(() => { + this.updateTemplatesState(prev => { + const newTemplates = { + ...prev + }; + delete newTemplates[id]; + return newTemplates; + }); + }); + } + updateTemplate(id, args) { + return this.executeAction(TemplatesProvider.actions.UPDATE, () => $e.data.update(_commands.Templates.signature, args, { + id + })).then(response => { + this.updateTemplateItemState(id, response.data); + }); + } + fetchTemplates() { + return this.executeAction(TemplatesProvider.actions.FETCH, () => $e.data.get(_commands.Templates.signature, {}, { + refresh: true + })).then(response => { + this.updateTemplatesState(() => Object.values(response.data).reduce((current, template) => ({ + ...current, + [template.id]: template + }), {}), false); + }); + } + updateTemplateItemState(id, args) { + return this.updateTemplatesState(prev => { + const template = { + ...prev[id], + ...args + }; + return { + ...prev, + [id]: template + }; + }); + } + updateTemplatesState(callback, clearCache = true) { + if (clearCache) { + $e.data.deleteCache($e.components.get(_component.default.namespace), _commands.Templates.signature); + } + return this.setState(prev => { + return { + templates: callback(prev.templates) + }; + }); + } + findTemplateItemInState(id) { + return this.state.templates[id]; + } + render() { + if (this.state.action.current === TemplatesProvider.actions.FETCH) { + if (this.state.action.error) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Error:', 'elementor-pro'), " ", this.state.action.error); + } + if (this.state.action.loading) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Loading', 'elementor-pro'), "..."); + } + } + return /*#__PURE__*/_react.default.createElement(Context.Provider, { + value: this.state + }, this.props.children); + } +} +exports.TemplatesProvider = TemplatesProvider; +var _default = exports["default"] = TemplatesProvider; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ConditionsConfig = void 0; +class ConditionsConfig extends $e.modules.CommandData { + static signature = 'site-editor/conditions-config'; + static getEndpointFormat() { + return 'site-editor/conditions-config/{id}'; + } +} +exports.ConditionsConfig = ConditionsConfig; +var _default = exports["default"] = ConditionsConfig; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/index.js": +/*!************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/index.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ConditionsConfig", ({ + enumerable: true, + get: function () { + return _conditionsConfig.ConditionsConfig; + } +})); +Object.defineProperty(exports, "Templates", ({ + enumerable: true, + get: function () { + return _templates.Templates; + } +})); +Object.defineProperty(exports, "TemplatesConditions", ({ + enumerable: true, + get: function () { + return _templatesConditions.TemplatesConditions; + } +})); +Object.defineProperty(exports, "TemplatesConditionsConflicts", ({ + enumerable: true, + get: function () { + return _templatesConditionsConflicts.TemplatesConditionsConflicts; + } +})); +var _templates = __webpack_require__(/*! ./templates */ "../core/app/modules/site-editor/assets/js/data/commands/templates.js"); +var _conditionsConfig = __webpack_require__(/*! ./conditions-config */ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js"); +var _templatesConditions = __webpack_require__(/*! ./templates-conditions */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js"); +var _templatesConditionsConflicts = __webpack_require__(/*! ./templates-conditions-conflicts */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js"); + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js": +/*!*************************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditionsConflicts = void 0; +class TemplatesConditionsConflicts extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions-conflicts'; + static getEndpointFormat() { + return `${TemplatesConditionsConflicts.signature}/{id}`; + } +} +exports.TemplatesConditionsConflicts = TemplatesConditionsConflicts; +var _default = exports["default"] = TemplatesConditionsConflicts; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js": +/*!***************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditions = void 0; +class TemplatesConditions extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions'; + static getEndpointFormat() { + return 'site-editor/templates-conditions/{id}'; + } +} +exports.TemplatesConditions = TemplatesConditions; +var _default = exports["default"] = TemplatesConditions; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates.js": +/*!****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Templates = void 0; +class Templates extends $e.modules.CommandData { + static signature = 'site-editor/templates'; + static getEndpointFormat() { + return 'site-editor/templates/{id}'; + } +} +exports.Templates = Templates; +var _default = exports["default"] = Templates; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/component.js": +/*!*******************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/component.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var dataCommands = _interopRequireWildcard(__webpack_require__(/*! ./commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + static namespace = 'site-editor'; + getNamespace() { + return this.constructor.namespace; + } + defaultData() { + return this.importCommands(dataCommands); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/hooks/use-templates-screenshot.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/hooks/use-templates-screenshot.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var React = __webpack_require__(/*! react */ "react"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = useTemplatesScreenshot; +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +var _useScreenshot = _interopRequireWildcard(__webpack_require__(/*! modules/screenshots/app/assets/js/hooks/use-screenshot */ "../modules/screenshots/app/assets/js/hooks/use-screenshot.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +/** + * Wrapper function that was made to take screenshots specific for template. + * it will capture a screenshot and update the templates context with the new screenshot. + * + * @param {any} templateType + */ +function useTemplatesScreenshot(templateType = null) { + const { + updateTemplateItemState, + templates + } = React.useContext(_templates.Context); + const templatesForScreenshot = Object.values(templates).filter(template => shouldScreenshotTemplate(template, templateType)); + + // Start to capture screenshots. + const screenshot = (0, _useScreenshot.default)(templatesForScreenshot); + + // Update the thumbnail url when screenshot created. + React.useEffect(() => { + screenshot.posts.filter(post => post.status === _useScreenshot.SCREENSHOT_STATUS_SUCCEED).forEach(post => updateTemplateItemState(post.id, { + thumbnail: post.imageUrl + })); + }, [screenshot.succeed]); + + // Update the screenshot url that was failed. + // When the user will hit the route on the second time it will avoid trying to take another screenshot. + React.useEffect(() => { + screenshot.posts.filter(post => post.status === _useScreenshot.SCREENSHOT_STATUS_FAILED).forEach(post => updateTemplateItemState(post.id, { + screenshot_url: null + })); + }, [screenshot.failed]); + return screenshot; +} + +/** + * Filter handler. + * will remove all the drafts and private and also will filter by template type if exists. + * + * @param {any} template + * @param {any} templateType + * @return {boolean} should screenshot template + */ +function shouldScreenshotTemplate(template, templateType = null) { + if (templateType) { + return false; + } + return 'publish' === template.status && !template.thumbnail && template.screenshot_url; +} + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/back-button.js": +/*!**************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/back-button.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = BackButton; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +__webpack_require__(/*! ./back-button.scss */ "../core/app/modules/site-editor/assets/js/molecules/back-button.scss"); +function BackButton(props) { + return /*#__PURE__*/_react.default.createElement("div", { + className: "back-button-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "eps-back-button", + text: __('Back', 'elementor-pro'), + icon: "eicon-chevron-left", + onClick: props.onClick + })); +} +BackButton.propTypes = { + onClick: PropTypes.func +}; +BackButton.defaultProps = { + onClick: () => history.back() +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template-body.js": +/*!*********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template-body.js ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SiteTemplateBody = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _siteTemplateThumbnail = _interopRequireDefault(__webpack_require__(/*! ./site-template-thumbnail */ "../core/app/modules/site-editor/assets/js/molecules/site-template-thumbnail.js")); +var _previewIframe = _interopRequireDefault(__webpack_require__(/*! ../atoms/preview-iframe */ "../core/app/modules/site-editor/assets/js/atoms/preview-iframe.js")); +const SiteTemplateBody = props => { + return /*#__PURE__*/_react.default.createElement(_appUi.CardBody, null, props.extended ? /*#__PURE__*/_react.default.createElement(_previewIframe.default, { + src: props.previewUrl, + templateType: props.type + }) : /*#__PURE__*/_react.default.createElement(_siteTemplateThumbnail.default, { + id: props.id, + title: props.title, + type: props.type, + thumbnail: props.thumbnail, + placeholder: props.placeholderUrl + })); +}; +exports.SiteTemplateBody = SiteTemplateBody; +SiteTemplateBody.propTypes = { + extended: PropTypes.bool, + id: PropTypes.number, + title: PropTypes.string, + thumbnail: PropTypes.string, + placeholderUrl: PropTypes.string, + type: PropTypes.string, + previewUrl: PropTypes.string +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template-footer.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template-footer.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SiteTemplateFooter = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +const SiteTemplateFooter = props => { + const instances = Object.values(props.instances).join(', '); + return /*#__PURE__*/_react.default.createElement(_appUi.CardFooter, null, /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-template__instances" + }, /*#__PURE__*/_react.default.createElement(_appUi.Icon, { + className: "eicon-flow" + }), /*#__PURE__*/_react.default.createElement(_appUi.Text, { + tag: "span", + variant: "sm" + }, /*#__PURE__*/_react.default.createElement("b", null, __('Instances', 'elementor-pro'), ":")), /*#__PURE__*/_react.default.createElement(_appUi.Text, { + className: "e-site-template__instances-list", + tag: "span", + variant: "xxs" + }, " ", instances), /*#__PURE__*/_react.default.createElement(_appUi.Button, { + text: __('Edit Conditions', 'elementor-pro'), + className: "e-site-template__edit-conditions", + url: `/site-editor/conditions/${props.id}` + }))); +}; +exports.SiteTemplateFooter = SiteTemplateFooter; +SiteTemplateFooter.propTypes = { + id: PropTypes.number.isRequired, + instances: PropTypes.any +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template-header.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template-header.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SiteTemplateHeader = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _dialogsAndButtons = _interopRequireDefault(__webpack_require__(/*! ../part-actions/dialogs-and-buttons */ "../core/app/modules/site-editor/assets/js/part-actions/dialogs-and-buttons.js")); +var _indicatorBullet = __webpack_require__(/*! ../atoms/indicator-bullet */ "../core/app/modules/site-editor/assets/js/atoms/indicator-bullet.js"); +const SiteTemplateHeader = props => { + const status = props.status && 'publish' !== props.status ? ` (${props.status})` : '', + title = props.title + status, + ActionButtons = () => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + text: __('Edit', 'elementor-pro'), + icon: "eicon-edit", + className: "e-site-template__edit-btn", + size: "sm", + url: props.editURL + }), /*#__PURE__*/_react.default.createElement(_dialogsAndButtons.default, props)), + MetaDataIcon = innerProps => /*#__PURE__*/_react.default.createElement(_appUi.Text, { + tag: "span", + className: "e-site-template__meta-data" + }, /*#__PURE__*/_react.default.createElement(_appUi.Icon, { + className: innerProps.icon + }), innerProps.content), + MetaData = () => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(MetaDataIcon, { + icon: "eicon-user-circle-o", + content: props.author + }), /*#__PURE__*/_react.default.createElement(MetaDataIcon, { + icon: "eicon-clock-o", + content: props.modifiedDate + })), + IndicatorDot = props.showInstances ? /*#__PURE__*/_react.default.createElement(_indicatorBullet.Indicator, { + active: props.isActive + }) : ''; + return /*#__PURE__*/_react.default.createElement(_appUi.CardHeader, null, IndicatorDot, /*#__PURE__*/_react.default.createElement(_appUi.Heading, { + tag: "h1", + title: title, + variant: "text-sm", + className: "eps-card__headline" + }, title), props.extended && /*#__PURE__*/_react.default.createElement(MetaData, null), props.extended && /*#__PURE__*/_react.default.createElement(ActionButtons, null)); +}; +exports.SiteTemplateHeader = SiteTemplateHeader; +SiteTemplateHeader.propTypes = { + isActive: PropTypes.bool, + author: PropTypes.string, + editURL: PropTypes.string, + extended: PropTypes.bool, + modifiedDate: PropTypes.string, + status: PropTypes.string, + title: PropTypes.string, + showInstances: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template-thumbnail.js": +/*!**************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template-thumbnail.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = SiteTemplateThumbnail; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function SiteTemplateThumbnail(props) { + return /*#__PURE__*/_react.default.createElement(_appUi.CardImage, { + alt: props.title, + src: props.thumbnail || props.placeholder, + className: !props.thumbnail ? 'e-site-template__placeholder' : '' + }, /*#__PURE__*/_react.default.createElement(_appUi.CardOverlay, { + className: "e-site-template__overlay-preview" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "e-site-template__overlay-preview-button", + text: __('Preview', 'elementor-pro'), + icon: "eicon-preview-medium", + url: `/site-editor/templates/${props.type}/${props.id}` + }))); +} +SiteTemplateThumbnail.propTypes = { + id: PropTypes.number, + title: PropTypes.string, + type: PropTypes.string, + thumbnail: PropTypes.string, + placeholder: PropTypes.string +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/molecules/site-template.js": +/*!****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/molecules/site-template.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = SiteTemplate; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _siteTemplateHeader = __webpack_require__(/*! ./site-template-header */ "../core/app/modules/site-editor/assets/js/molecules/site-template-header.js"); +var _siteTemplateBody = __webpack_require__(/*! ./site-template-body */ "../core/app/modules/site-editor/assets/js/molecules/site-template-body.js"); +var _siteTemplateFooter = __webpack_require__(/*! ./site-template-footer */ "../core/app/modules/site-editor/assets/js/molecules/site-template-footer.js"); +__webpack_require__(/*! ./site-template.scss */ "../core/app/modules/site-editor/assets/js/molecules/site-template.scss"); +function SiteTemplate(props) { + const baseClassName = 'e-site-template', + classes = [baseClassName], + ref = _react.default.useRef(null); + _react.default.useEffect(() => { + if (!props.isSelected) { + return; + } + ref.current.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + }, [props.isSelected]); + if (props.extended) { + classes.push(`${baseClassName}--extended`); + } + if (props.aspectRatio) { + classes.push(`${baseClassName}--${props.aspectRatio}`); + } + const CardFooter = props.extended && props.showInstances ? /*#__PURE__*/_react.default.createElement(_siteTemplateFooter.SiteTemplateFooter, props) : ''; + return /*#__PURE__*/_react.default.createElement(_appUi.Card, { + className: classes.join(' '), + ref: ref + }, /*#__PURE__*/_react.default.createElement(_siteTemplateHeader.SiteTemplateHeader, props), /*#__PURE__*/_react.default.createElement(_siteTemplateBody.SiteTemplateBody, props), CardFooter); +} +SiteTemplate.propTypes = { + aspectRatio: PropTypes.string, + className: PropTypes.string, + extended: PropTypes.bool, + id: PropTypes.number.isRequired, + isActive: PropTypes.bool.isRequired, + status: PropTypes.string, + thumbnail: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + isSelected: PropTypes.bool, + type: PropTypes.string.isRequired, + showInstances: PropTypes.bool +}; +SiteTemplate.defaultProps = { + isSelected: false +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/organisms/site-templates.js": +/*!*****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/organisms/site-templates.js ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = SiteTemplates; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _siteTemplate = _interopRequireDefault(__webpack_require__(/*! ../molecules/site-template */ "../core/app/modules/site-editor/assets/js/molecules/site-template.js")); +var _dialogsAndButtons = __webpack_require__(/*! ../part-actions/dialogs-and-buttons */ "../core/app/modules/site-editor/assets/js/part-actions/dialogs-and-buttons.js"); +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +var _useTemplatesScreenshot = _interopRequireDefault(__webpack_require__(/*! ../hooks/use-templates-screenshot */ "../core/app/modules/site-editor/assets/js/hooks/use-templates-screenshot.js")); +function SiteTemplates(props) { + const { + templates: contextTemplates, + action, + resetActionState + } = _react.default.useContext(_templates.Context); + let gridColumns, templates; + + // Make the templates object a memorize value, will re run again only if + // templates has been changed, also sort the templates by `isActive`. + templates = _react.default.useMemo(() => { + return Object.values(contextTemplates).sort((a, b) => { + // This sort make sure to show first the active templates, second the + // inactive templates that are not draft, and then the drafts, + // in each category it sorts it inside by date. + + if (!b.isActive && !a.isActive) { + if ('draft' === b.status && 'draft' === a.status || 'draft' !== b.status && 'draft' !== a.status) { + return b.date < a.date ? 1 : -1; + } + return 'draft' === a.status ? 1 : -1; + } + if (b.isActive && a.isActive) { + return b.date < a.date ? 1 : -1; + } + return b.isActive ? 1 : -1; + }); + }, [contextTemplates]); + + // Start to capture screenshots. + (0, _useTemplatesScreenshot.default)(props.type); + const siteTemplateConfig = {}; + if (props.type) { + templates = templates.filter(item => item.type === props.type); + siteTemplateConfig.extended = true; + siteTemplateConfig.type = props.type; + switch (props.type) { + case 'header': + case 'footer': + gridColumns = 1; + siteTemplateConfig.aspectRatio = 'wide'; + break; + default: + gridColumns = 2; + } + } + if (!templates || !templates.length) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('No Templates found. Want to create one?', 'elementor-pro'), "..."); + } + return /*#__PURE__*/_react.default.createElement("section", { + className: "e-site-editor__site-templates" + }, /*#__PURE__*/_react.default.createElement(_dialogsAndButtons.PartActionsDialogs, null), action.error && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + text: action.error, + dismissButtonText: __('Go Back', 'elementor-pro'), + dismissButtonOnClick: resetActionState, + approveButtonText: __('Learn More', 'elementor-pro'), + approveButtonColor: "link", + approveButtonUrl: "https://go.elementor.com/app-theme-builder-template-load-issue", + approveButtonTarget: "_target" + }), /*#__PURE__*/_react.default.createElement(_appUi.CssGrid, { + columns: gridColumns, + spacing: 24, + colMinWidth: 200 + }, templates.map(item => /*#__PURE__*/_react.default.createElement(_siteTemplate.default, (0, _extends2.default)({ + key: item.id + }, item, siteTemplateConfig, { + isSelected: parseInt(props.id) === item.id + }))))); +} +SiteTemplates.propTypes = { + type: PropTypes.string, + id: PropTypes.string +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/add-new.js": +/*!******************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/add-new.js ***! + \******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = AddNew; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _siteEditor = __webpack_require__(/*! @elementor/site-editor */ "@elementor/site-editor"); +__webpack_require__(/*! ./add-new.scss */ "../core/app/modules/site-editor/assets/js/pages/add-new.scss"); +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +var _backButton = _interopRequireDefault(__webpack_require__(/*! ../molecules/back-button */ "../core/app/modules/site-editor/assets/js/molecules/back-button.js")); +var _useFeatureLock = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app/hooks/use-feature-lock */ "../core/app/assets/js/hooks/use-feature-lock.js")); +function AddNew() { + const { + templates + } = _react.default.useContext(_templates.Context), + hasTemplates = 1 <= Object.keys(templates).length; + const { + isLocked, + ConnectButton + } = (0, _useFeatureLock.default)('site-editor'); + + /** + * An hover element for each site part. + * + * @param {any} props + */ + const HoverElement = props => { + if (isLocked) { + return /*#__PURE__*/_react.default.createElement(_appUi.CardOverlay, { + className: "e-site-editor__promotion-overlay" + }, /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor__promotion-overlay__link" + }, /*#__PURE__*/_react.default.createElement("i", { + className: "e-site-editor__promotion-overlay__icon eicon-lock" + }))); + } + return /*#__PURE__*/_react.default.createElement("a", { + href: props.urls.create, + className: "eps-card__image-overlay eps-add-new__overlay" + }, /*#__PURE__*/_react.default.createElement(_appUi.AddNewButton, { + hideText: true + })); + }; + HoverElement.propTypes = { + urls: PropTypes.object.isRequired + }; + return /*#__PURE__*/_react.default.createElement("section", { + className: "e-site-editor__add-new" + }, /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + container: true, + direction: "column", + className: "e-site-editor__header" + }, hasTemplates && /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + item: true + }, /*#__PURE__*/_react.default.createElement(_backButton.default, null)), /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + item: true, + container: true, + justify: "space-between", + alignItems: "start" + }, /*#__PURE__*/_react.default.createElement(_appUi.Heading, { + variant: "h1" + }, __('Start customizing every part of your site', 'elementor-pro')), isLocked && /*#__PURE__*/_react.default.createElement(ConnectButton, null))), /*#__PURE__*/_react.default.createElement(_siteEditor.SiteParts, { + hoverElement: HoverElement + })); +} + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js": +/*!*********************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js ***! + \*********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _reactDom = __webpack_require__(/*! react-dom */ "react-dom"); +var _react = __webpack_require__(/*! react */ "react"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConditionButtonPortal = props => { + const [shouldCreatePortal, setShouldCreatePortal] = (0, _react.useState)(false), + portalRoot = document.getElementById('portal-root'); + (0, _react.useEffect)(() => { + setShouldCreatePortal(!!portalRoot); + }, [portalRoot]); + return shouldCreatePortal ? (0, _reactDom.createPortal)(props.children, portalRoot) : null; +}; +ConditionButtonPortal.propTypes = { + children: PropTypes.oneOfType([PropTypes.node, PropTypes.string]) +}; +var _default = exports["default"] = ConditionButtonPortal; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js": +/*!*****************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var sprintf = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["sprintf"]; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionConflicts; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionConflicts(props) { + if (!props.conflicts.length) { + return ''; + } + const conflictLinks = props.conflicts.map(conflict => { + return /*#__PURE__*/_react.default.createElement(_appUi.Button, { + key: conflict.template_id, + target: "_blank", + url: conflict.edit_url, + text: conflict.template_title + }); + }); + return /*#__PURE__*/_react.default.createElement(_appUi.Text, { + className: "e-site-editor-conditions__conflict", + variant: "sm" + }, sprintf(/* Translators: %s: a list of conflicted templates */ + __('We noticed that you already applied %s with the same condition.', 'elementor-pro'), conflictLinks), /*#__PURE__*/_react.default.createElement("br", null), __("To continue, set different conditions for each so they don't conflict.", 'elementor-pro')); +} +ConditionConflicts.propTypes = { + conflicts: PropTypes.array.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionName; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionName(props) { + // Hide for template types that has another default, like single & archive. + if ('general' !== props.default) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + name: e.target.value, + sub: '', + subId: '' + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: props.options, + value: props.name, + onChange: onChange + })); +} +ConditionName.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + options: PropTypes.array.isRequired, + default: PropTypes.string.isRequired +}; +ConditionName.defaultProps = { + name: '' +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js": +/*!**************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionSubId; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +/** + * Main component. + * + * @param {any} props + * @return {any} Element + * @class + */ +function ConditionSubId(props) { + const settings = _react.default.useMemo(() => Object.keys(props.subIdAutocomplete).length ? getSettings(props.subIdAutocomplete) : null, [props.subIdAutocomplete]); + if (!props.sub || !settings) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + subId: e.target.value + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select2, { + onChange: onChange, + value: props.subId, + settings: settings, + options: props.subIdOptions + })); +} + +/** + * Get settings for the select2 base on the autocomplete settings, + * that passes as a prop + * + * @param {any} autocomplete + * @return {Object} Settings + */ +function getSettings(autocomplete) { + return { + allowClear: false, + placeholder: __('All', 'elementor-pro'), + dir: elementorCommon.config.isRTL ? 'rtl' : 'ltr', + ajax: { + transport(params, success, failure) { + return elementorCommon.ajax.addRequest('pro_panel_posts_control_filter_autocomplete', { + data: { + q: params.data.q, + autocomplete + }, + success, + error: failure + }); + }, + data(params) { + return { + q: params.term, + page: params.page + }; + }, + cache: true + }, + escapeMarkup(markup) { + return markup; + }, + minimumInputLength: 1 + }; +} +ConditionSubId.propTypes = { + subIdAutocomplete: PropTypes.object, + id: PropTypes.string.isRequired, + sub: PropTypes.string, + subId: PropTypes.string, + updateConditions: PropTypes.func, + subIdOptions: PropTypes.array +}; +ConditionSubId.defaultProps = { + subId: '', + subIdOptions: [] +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionSub; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionSub(props) { + if ('general' === props.name || !props.subOptions.length) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + sub: e.target.value, + subId: '' + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: props.subOptions, + value: props.sub, + onChange: onChange + })); +} +ConditionSub.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + sub: PropTypes.string.isRequired, + subOptions: PropTypes.array.isRequired +}; +ConditionSub.defaultProps = { + sub: '', + subOptions: {} +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionType; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionType(props) { + const wrapperRef = _react.default.createRef(); + const options = [{ + label: __('Include', 'elementor-pro'), + value: 'include' + }, { + label: __('Exclude', 'elementor-pro'), + value: 'exclude' + }]; + const onChange = e => { + props.updateConditions(props.id, { + type: e.target.value + }); + }; + _react.default.useEffect(() => { + wrapperRef.current.setAttribute('data-elementor-condition-type', props.type); + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper e-site-editor-conditions__input-wrapper--condition-type", + ref: wrapperRef + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: options, + value: props.type, + onChange: onChange + })); +} +ConditionType.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + type: PropTypes.string.isRequired +}; +ConditionType.defaultProps = { + type: '' +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js": +/*!*************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionsRows; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _conditions = __webpack_require__(/*! ../../context/conditions */ "../core/app/modules/site-editor/assets/js/context/conditions.js"); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _conditionType = _interopRequireDefault(__webpack_require__(/*! ./condition-type */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js")); +var _conditionName = _interopRequireDefault(__webpack_require__(/*! ./condition-name */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js")); +var _conditionSub = _interopRequireDefault(__webpack_require__(/*! ./condition-sub */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js")); +var _conditionSubId = _interopRequireDefault(__webpack_require__(/*! ./condition-sub-id */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js")); +var _conditionConflicts = _interopRequireDefault(__webpack_require__(/*! ./condition-conflicts */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js")); +var _conditionButtonPortal = _interopRequireDefault(__webpack_require__(/*! ./condition-button-portal */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js")); +function ConditionsRows(props) { + const { + conditions, + createConditionItemInState: create, + updateConditionItemState: update, + removeConditionItemInState: remove, + saveConditions: save, + action, + resetActionState + } = _react.default.useContext(_conditions.Context); + const rows = Object.values(conditions).map(condition => /*#__PURE__*/_react.default.createElement("div", { + key: condition.id + }, /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__row" + }, /*#__PURE__*/_react.default.createElement("div", { + className: `e-site-editor-conditions__row-controls ${condition.conflictErrors.length && 'e-site-editor-conditions__row-controls--error'}` + }, /*#__PURE__*/_react.default.createElement(_conditionType.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__row-controls-inner" + }, /*#__PURE__*/_react.default.createElement(_conditionName.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement(_conditionSub.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement(_conditionSubId.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })))), /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "e-site-editor-conditions__remove-condition", + text: __('Delete', 'elementor-pro'), + icon: "eicon-close", + hideText: true, + onClick: () => remove(condition.id) + })), /*#__PURE__*/_react.default.createElement(_conditionConflicts.default, { + conflicts: condition.conflictErrors + }))); + const SaveButton = () => { + return /*#__PURE__*/_react.default.createElement(_appUi.Button, { + variant: "contained", + color: "primary", + size: "lg", + hideText: isSaving, + icon: isSaving ? 'eicon-loading eicon-animation-spin' : '', + text: __('Save & Close', 'elementor-pro'), + onClick: () => save().then(props.onAfterSave) + }); + }; + const isSaving = action.current === _conditions.ConditionsProvider.actions.SAVE && action.loading; + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, action.error && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + text: action.error, + dismissButtonText: __('Go Back', 'elementor-pro'), + dismissButtonOnClick: resetActionState, + approveButtonText: __('Learn More', 'elementor-pro'), + approveButtonColor: "link", + approveButtonUrl: "https://go.elementor.com/app-theme-builder-conditions-load-issue", + approveButtonTarget: "_target" + }), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__rows" + }, rows), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__add-button-container" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "e-site-editor-conditions__add-button", + variant: "contained", + size: "lg", + text: __('Add Condition', 'elementor-pro'), + onClick: create + })), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__footer" + }, props?.loadPortal ? /*#__PURE__*/_react.default.createElement(_conditionButtonPortal.default, null, /*#__PURE__*/_react.default.createElement(SaveButton, null)) : /*#__PURE__*/_react.default.createElement(SaveButton, null))); +} +ConditionsRows.propTypes = { + onAfterSave: PropTypes.func, + loadPortal: PropTypes.bool +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions.js": +/*!********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/conditions.js ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = Conditions; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _conditions = _interopRequireDefault(__webpack_require__(/*! ../../context/conditions */ "../core/app/modules/site-editor/assets/js/context/conditions.js")); +var _templates = __webpack_require__(/*! ../../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +var _conditionsRows = _interopRequireDefault(__webpack_require__(/*! ./conditions-rows */ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js")); +__webpack_require__(/*! ./conditions.scss */ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions.scss"); +var _backButton = _interopRequireDefault(__webpack_require__(/*! ../../molecules/back-button */ "../core/app/modules/site-editor/assets/js/molecules/back-button.js")); +function Conditions(props) { + const { + findTemplateItemInState, + updateTemplateItemState + } = _react.default.useContext(_templates.Context), + template = findTemplateItemInState(parseInt(props.id)); + if (!template) { + return /*#__PURE__*/_react.default.createElement("div", null, __('Not Found', 'elementor-pro')); + } + return /*#__PURE__*/_react.default.createElement("section", { + className: "e-site-editor-conditions" + }, /*#__PURE__*/_react.default.createElement(_backButton.default, null), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__header" + }, /*#__PURE__*/_react.default.createElement("img", { + className: "e-site-editor-conditions__header-image", + src: `${elementorAppProConfig.baseUrl}/modules/theme-builder/assets/images/conditions-tab.svg`, + alt: __('Import template', 'elementor-pro') + }), /*#__PURE__*/_react.default.createElement(_appUi.Heading, { + variant: "h1", + tag: "h1" + }, __('Where do you want to display your template?', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_appUi.Text, { + variant: "p" + }, __('Set the conditions that determine where your template is used throughout your site.', 'elementor-pro'), /*#__PURE__*/_react.default.createElement("br", null), __('For example, choose \'Entire Site\' to display the template across your site.', 'elementor-pro'))), /*#__PURE__*/_react.default.createElement(_conditions.default, { + currentTemplate: template, + onConditionsSaved: updateTemplateItemState + }, /*#__PURE__*/_react.default.createElement(_conditionsRows.default, { + onAfterSave: () => history.back(), + loadPortal: true + }))); +} +Conditions.propTypes = { + id: PropTypes.string +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/import.js": +/*!*****************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/import.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = Import; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +var _backButton = _interopRequireDefault(__webpack_require__(/*! ../molecules/back-button */ "../core/app/modules/site-editor/assets/js/molecules/back-button.js")); +var _hooks = __webpack_require__(/*! @elementor/hooks */ "@elementor/hooks"); +// The hook `useConfirmAction` comes from the core plugin, so it is possible that it is not available. +const useConfirmActionFallback = ({ + action +}) => ({ + runAction: action, + dialog: { + isOpen: false + } +}); +const useConfirmAction = _hooks.useConfirmAction ?? useConfirmActionFallback; +function Import() { + const { + importTemplates, + action, + resetActionState + } = _react.default.useContext(_templates.Context), + [importedTemplate, setImportedTemplate] = _react.default.useState(null), + isImport = action.current === _templates.TemplatesProvider.actions.IMPORT, + isUploading = isImport && action.loading, + hasError = isImport && action.error; + const upload = _react.default.useCallback(file => { + if (isUploading) { + return; + } + readFile(file).then(fileData => importTemplates({ + fileName: file.name, + fileData + })).then(response => { + // For now it show a dialog for the first template ONLY! + setImportedTemplate(response.data[0]); + }); + }, []); + const { + runAction: uploadFile, + dialog, + checkbox + } = useConfirmAction({ + doNotShowAgainKey: 'upload_json_warning_generic_message', + action: upload + }); + return /*#__PURE__*/_react.default.createElement("section", { + className: "site-editor__import" + }, importedTemplate && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + title: __('Your template was imported', 'elementor-pro'), + approveButtonText: __('Preview', 'elementor-pro'), + approveButtonUrl: importedTemplate.url, + approveButtonTarget: "_blank", + dismissButtonText: __('Edit', 'elementor-pro'), + dismissButtonUrl: importedTemplate.editURL, + dismissButtonTarget: "_top", + onClose: () => setImportedTemplate(null) + }), hasError && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + title: action.error, + approveButtonText: __('Learn More', 'elementor-pro'), + approveButtonUrl: "https://go.elementor.com/app-theme-builder-import-issue", + approveButtonTarget: "_blank", + approveButtonColor: "link", + dismissButtonText: __('Go Back', 'elementor-pro'), + dismissButtonOnClick: resetActionState, + onClose: resetActionState + }), dialog.isOpen && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + title: __('Warning: JSON or ZIP files may be unsafe', 'elementor-pro'), + text: __('Uploading JSON or ZIP files from unknown sources can be harmful and put your site at risk. For maximum safety, upload only JSON or ZIP files from trusted sources.', 'elementor-pro'), + approveButtonColor: "link", + approveButtonText: __('Continue', 'elementor-pro'), + approveButtonOnClick: dialog.approve, + dismissButtonText: __('Cancel', 'elementor-pro'), + dismissButtonOnClick: dialog.dismiss, + onClose: dialog.dismiss + }, /*#__PURE__*/_react.default.createElement("label", { + htmlFor: "do-not-show-upload-json-warning-again", + style: { + display: 'flex', + alignItems: 'center', + gap: '5px' + } + }, /*#__PURE__*/_react.default.createElement(_appUi.Checkbox, { + id: "do-not-show-upload-json-warning-again", + type: "checkbox", + value: checkbox.isChecked, + onChange: event => checkbox.setIsChecked(!!event.target.checked) + }), __('Do not show this message again', 'elementor-pro'))), /*#__PURE__*/_react.default.createElement(_backButton.default, null), /*#__PURE__*/_react.default.createElement(_appUi.DropZone, { + heading: __('Import Template To Your Library', 'elementor-pro'), + text: __('Drag & Drop your .JSON or .zip template file', 'elementor-pro'), + secondaryText: __('or', 'elementor-pro'), + onFileSelect: uploadFile, + isLoading: isUploading, + filetypes: ['zip', 'json'] + })); +} +function readFile(file) { + return new Promise(resolve => { + const fileReader = new FileReader(); + fileReader.readAsDataURL(file); + fileReader.onload = event => { + // Replace the mime type that prepended to the base64 with empty string and return a + // resolved promise only with the base64 string. + resolve(event.target.result.replace(/^[^,]+,/, '')); + }; + }); +} + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/template-type.js": +/*!************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/template-type.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = TemplateType; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _siteEditor = __webpack_require__(/*! @elementor/site-editor */ "@elementor/site-editor"); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _siteTemplates = _interopRequireDefault(__webpack_require__(/*! ../organisms/site-templates */ "../core/app/modules/site-editor/assets/js/organisms/site-templates.js")); +var _useFeatureLock = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app/hooks/use-feature-lock */ "../core/app/assets/js/hooks/use-feature-lock.js")); +__webpack_require__(/*! ./template-type.scss */ "../core/app/modules/site-editor/assets/js/pages/template-type.scss"); +function TemplateType(props) { + const { + templateTypes + } = _react.default.useContext(_siteEditor.TemplateTypesContext), + currentType = templateTypes.find(item => item.type === props.type), + { + isLocked, + ConnectButton + } = (0, _useFeatureLock.default)('site-editor'); + if (!currentType) { + return /*#__PURE__*/_react.default.createElement(_appUi.NotFound, null); + } + return /*#__PURE__*/_react.default.createElement("section", { + className: `e-site-editor__templates e-site-editor__templates--type-${props.type}` + }, /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + className: "page-header", + container: true, + justify: "space-between" + }, /*#__PURE__*/_react.default.createElement(_appUi.Heading, { + variant: "h1" + }, currentType.page_title), isLocked ? /*#__PURE__*/_react.default.createElement(ConnectButton, null) : /*#__PURE__*/_react.default.createElement(_appUi.AddNewButton, { + url: currentType.urls.create, + text: __('Add New', 'elementor-pro') + })), /*#__PURE__*/_react.default.createElement("hr", { + className: "eps-separator" + }), /*#__PURE__*/_react.default.createElement(_siteTemplates.default, { + type: currentType.type, + id: props.id + })); +} +TemplateType.propTypes = { + type: PropTypes.string, + page_title: PropTypes.string, + id: PropTypes.string +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/templates.js": +/*!********************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/templates.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = Templates; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _siteTemplates = _interopRequireDefault(__webpack_require__(/*! ../organisms/site-templates */ "../core/app/modules/site-editor/assets/js/organisms/site-templates.js")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _useFeatureLock = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app/hooks/use-feature-lock */ "../core/app/assets/js/hooks/use-feature-lock.js")); +function Templates() { + const { + isLocked, + ConnectButton + } = (0, _useFeatureLock.default)('site-editor'); + return /*#__PURE__*/_react.default.createElement("section", { + className: "e-site-editor__site-templates" + }, /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + container: true, + justify: "space-between", + alignItems: "start", + className: "page-header" + }, /*#__PURE__*/_react.default.createElement("h1", null, __('Your Site\'s Global Parts', 'elementor-pro')), isLocked ? /*#__PURE__*/_react.default.createElement(ConnectButton, null) : /*#__PURE__*/_react.default.createElement(_appUi.AddNewButton, { + url: "/site-editor/add-new" + })), /*#__PURE__*/_react.default.createElement("hr", { + className: "eps-separator" + }), /*#__PURE__*/_react.default.createElement(_siteTemplates.default, null)); +} + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/part-actions/dialog-delete.js": +/*!*******************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/part-actions/dialog-delete.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = DialogDelete; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +function DialogDelete(props) { + const { + deleteTemplate, + findTemplateItemInState + } = _react.default.useContext(_templates.Context); + const closeDialog = shouldUpdate => { + props.setId(null); + if (shouldUpdate) { + deleteTemplate(props.id); + } + }; + if (!props.id) { + return ''; + } + const template = findTemplateItemInState(props.id); + return /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + title: __('Move Item To Trash', 'elementor-pro'), + text: __('Are you sure you want to move this item to trash:', 'elementor-pro') + ` "${template.title}"`, + onSubmit: () => closeDialog(true), + approveButtonText: __('Move to Trash', 'elementor-pro'), + approveButtonOnClick: () => closeDialog(true), + approveButtonColor: "danger", + dismissButtonText: __('Cancel', 'elementor-pro'), + dismissButtonOnClick: () => closeDialog(), + onClose: () => closeDialog() + }); +} +DialogDelete.propTypes = { + id: PropTypes.number, + setId: PropTypes.func.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/part-actions/dialog-rename.js": +/*!*******************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/part-actions/dialog-rename.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = DialogRename; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _templates = __webpack_require__(/*! ../context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +function DialogRename(props) { + const { + findTemplateItemInState, + updateTemplate + } = _react.default.useContext(_templates.Context), + template = findTemplateItemInState(props.id); + const [title, setTitle] = _react.default.useState(''); + (0, _react.useEffect)(() => { + // The "title" state should be updated if the template title changed. + if (template) { + setTitle(template.title); + } + }, [template]); + const closeDialog = shouldUpdate => { + props.setId(null); + if (shouldUpdate) { + updateTemplate(props.id, { + post_title: title + }); + } + }; + if (!props.id) { + return ''; + } + return /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + title: __('Rename Site Part', 'elementor-pro'), + approveButtonText: __('Change', 'elementor-pro'), + onSubmit: () => closeDialog(true), + approveButtonOnClick: () => closeDialog(true), + approveButtonColor: "primary", + dismissButtonText: __('Cancel', 'elementor-pro'), + dismissButtonOnClick: () => closeDialog(), + onClose: () => closeDialog() + }, /*#__PURE__*/_react.default.createElement("input", { + type: "text", + className: "eps-input eps-input-text eps-input--block" + // eslint-disable-next-line jsx-a11y/no-autofocus + , + autoFocus: true, + value: title, + onChange: e => setTitle(e.target.value) + })); +} +DialogRename.propTypes = { + id: PropTypes.number, + setId: PropTypes.func.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/part-actions/dialogs-and-buttons.js": +/*!*************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/part-actions/dialogs-and-buttons.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PartActionsDialogs = PartActionsDialogs; +exports["default"] = PartActionsButtons; +exports.handlers = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _dialogRename = _interopRequireDefault(__webpack_require__(/*! ./dialog-rename */ "../core/app/modules/site-editor/assets/js/part-actions/dialog-rename.js")); +var _dialogDelete = _interopRequireDefault(__webpack_require__(/*! ./dialog-delete */ "../core/app/modules/site-editor/assets/js/part-actions/dialog-delete.js")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +const handlers = exports.handlers = { + rename: null, + delete: null +}; + +// TODO: Think about refactor to portals: https://reactjs.org/docs/portals.html +function PartActionsDialogs() { + const [DialogRenameId, setDialogRenameId] = _react.default.useState(null); + const [DialogDeleteId, setDialogDeleteId] = _react.default.useState(null); + handlers.rename = setDialogRenameId; + handlers.delete = setDialogDeleteId; + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_dialogRename.default, { + id: DialogRenameId, + setId: setDialogRenameId + }), /*#__PURE__*/_react.default.createElement(_dialogDelete.default, { + id: DialogDeleteId, + setId: setDialogDeleteId + })); +} +function PartActionsButtons(props) { + const [showMenu, setShowMenu] = _react.default.useState(false); + let SiteTemplatePopover = ''; + if (showMenu) { + SiteTemplatePopover = /*#__PURE__*/_react.default.createElement(_appUi.Popover, { + closeFunction: () => setShowMenu(!showMenu) + }, /*#__PURE__*/_react.default.createElement("li", null, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "eps-popover__item", + icon: "eicon-sign-out", + text: __('Export', 'elementor-pro'), + url: props.exportLink + })), /*#__PURE__*/_react.default.createElement("li", null, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "eps-popover__item eps-popover__item--danger", + icon: "eicon-trash-o", + text: __('Trash', 'elementor-pro'), + onClick: () => handlers.delete(props.id) + })), /*#__PURE__*/_react.default.createElement("li", null, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "eps-popover__item", + icon: "eicon-edit", + text: __('Rename', 'elementor-pro'), + onClick: () => handlers.rename(props.id) + }))); + } + return /*#__PURE__*/_react.default.createElement("div", { + className: "eps-popover__container" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + text: __('Toggle', 'elementor-pro'), + hideText: true, + icon: "eicon-ellipsis-h", + size: "lg", + onClick: () => setShowMenu(!showMenu) + }), SiteTemplatePopover); +} +PartActionsButtons.propTypes = { + id: PropTypes.number.isRequired, + exportLink: PropTypes.string.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/site-editor.js": +/*!****************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/site-editor.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _router = __webpack_require__(/*! @reach/router */ "../node_modules/@reach/router/es/index.js"); +var _templates = _interopRequireDefault(__webpack_require__(/*! ./pages/templates */ "../core/app/modules/site-editor/assets/js/pages/templates.js")); +var _templateType = _interopRequireDefault(__webpack_require__(/*! ./pages/template-type */ "../core/app/modules/site-editor/assets/js/pages/template-type.js")); +var _addNew = _interopRequireDefault(__webpack_require__(/*! ./pages/add-new */ "../core/app/modules/site-editor/assets/js/pages/add-new.js")); +var _conditions = _interopRequireDefault(__webpack_require__(/*! ./pages/conditions/conditions */ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions.js")); +var _import = _interopRequireDefault(__webpack_require__(/*! ./pages/import */ "../core/app/modules/site-editor/assets/js/pages/import.js")); +var _templates2 = _interopRequireWildcard(__webpack_require__(/*! ./context/templates */ "../core/app/modules/site-editor/assets/js/context/templates.js")); +var _siteEditor = __webpack_require__(/*! @elementor/site-editor */ "@elementor/site-editor"); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _router2 = _interopRequireDefault(__webpack_require__(/*! @elementor/router */ "@elementor/router")); +var _component = _interopRequireDefault(__webpack_require__(/*! ./data/component */ "../core/app/modules/site-editor/assets/js/data/component.js")); +var _useFeatureLock = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app/hooks/use-feature-lock */ "../core/app/assets/js/hooks/use-feature-lock.js")); +__webpack_require__(/*! ./site-editor.scss */ "../core/app/modules/site-editor/assets/js/site-editor.scss"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +function SiteEditor() { + const { + isLocked + } = (0, _useFeatureLock.default)('site-editor'); + const basePath = 'site-editor'; + const headerButtons = [{ + id: 'import', + text: __('import', 'elementor-pro'), + hideText: true, + icon: 'eicon-upload-circle-o', + onClick: () => _router2.default.appHistory.navigate(basePath + '/import') + }]; + + // Remove Core cache. + elementorCommon.ajax.invalidateCache({ + unique_id: 'app_site_editor_template_types' + }); + const SiteEditorDefault = () => { + const { + templates + } = _react.default.useContext(_templates2.Context); + if (Object.keys(templates).length) { + return /*#__PURE__*/_react.default.createElement(_router.Redirect, { + from: '/', + to: '/' + basePath + '/templates', + noThrow: true + }); + } + return /*#__PURE__*/_react.default.createElement(_router.Redirect, { + from: '/', + to: '/' + basePath + '/add-new', + noThrow: true + }); + }; + return /*#__PURE__*/_react.default.createElement(_appUi.ErrorBoundary, { + title: __('Theme Builder could not be loaded', 'elementor-pro'), + learnMoreUrl: "https://go.elementor.com/app-theme-builder-load-issue" + }, /*#__PURE__*/_react.default.createElement(_siteEditor.Layout, { + allPartsButton: /*#__PURE__*/_react.default.createElement(_siteEditor.AllPartsButton, { + url: '/' + basePath + }), + headerButtons: headerButtons, + titleRedirectRoute: '/' + basePath, + promotion: isLocked + }, /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + container: true, + className: "e-site-editor__content_container" + }, /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + item: true, + className: "e-site-editor__content_container_main" + }, /*#__PURE__*/_react.default.createElement(_templates2.default, null, /*#__PURE__*/_react.default.createElement(_router.LocationProvider, { + history: _router2.default.appHistory + }, /*#__PURE__*/_react.default.createElement(_router.Router, null, /*#__PURE__*/_react.default.createElement(SiteEditorDefault, { + path: basePath + }), /*#__PURE__*/_react.default.createElement(_templates.default, { + path: basePath + '/templates' + }), /*#__PURE__*/_react.default.createElement(_templateType.default, { + path: basePath + '/templates/:type/*id' + }), /*#__PURE__*/_react.default.createElement(_addNew.default, { + path: basePath + '/add-new' + }), /*#__PURE__*/_react.default.createElement(_conditions.default, { + path: basePath + '/conditions/:id' + }), /*#__PURE__*/_react.default.createElement(_import.default, { + path: basePath + '/import' + }), /*#__PURE__*/_react.default.createElement(_siteEditor.NotFound, { + default: true + }))))), /*#__PURE__*/_react.default.createElement(_appUi.Grid, { + container: true, + justify: "space-between", + className: "e-site-editor__content_container_secondary" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + text: __('Switch to table view', 'elementor-pro'), + url: elementorAppProConfig['site-editor']?.urls?.legacy_view + }), window.location.href.indexOf('conditions') !== -1 && /*#__PURE__*/_react.default.createElement("div", { + id: "portal-root" + }))))); +} +class Module { + constructor() { + elementorCommon.debug.addURLToWatch('elementor-pro/assets'); + $e.components.register(new _component.default()); + _router2.default.addRoute({ + path: '/site-editor/*', + component: SiteEditor + }); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/screenshots/app/assets/js/hooks/use-screenshot.js": +/*!********************************************************************!*\ + !*** ../modules/screenshots/app/assets/js/hooks/use-screenshot.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var React = __webpack_require__(/*! react */ "react"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SCREENSHOT_STATUS_SUCCEED = exports.SCREENSHOT_STATUS_QUEUE = exports.SCREENSHOT_STATUS_IN_PROGRESS = exports.SCREENSHOT_STATUS_FAILED = void 0; +exports["default"] = useScreenshot; +const { + useState, + useEffect, + useMemo, + useCallback +} = React; +const SCREENSHOT_STATUS_QUEUE = exports.SCREENSHOT_STATUS_QUEUE = 'queue'; +const SCREENSHOT_STATUS_IN_PROGRESS = exports.SCREENSHOT_STATUS_IN_PROGRESS = 'in-progress'; +const SCREENSHOT_STATUS_SUCCEED = exports.SCREENSHOT_STATUS_SUCCEED = 'succeed'; +const SCREENSHOT_STATUS_FAILED = exports.SCREENSHOT_STATUS_FAILED = 'failed'; + +/** + * Default options for the hook function + * + * @type {{numberOfScreenshotInParallel: number}} + */ +const defaultOptions = { + numberOfScreenshotInParallel: 1 +}; + +/** + * Filter the posts by status. + * + * @param {Array} posts + * @param {string} status + * @return {Array} Filtered posts + */ +function filterPostByStatus(posts, status) { + return posts.filter(item => status === item.status); +} + +/** + * Receive the initial posts and normalize it + * to an array that the hook can work with. + * + * @param {Array} posts + */ +function normalizeInitialPosts(posts) { + return posts.map(post => ({ + id: post.id, + screenshot_url: post.screenshot_url, + status: 'queue', + iframe: null, + imageUrl: null + })); +} + +/** + * Find the post id inside the posts array, update it with the attrs, + * and make sure to return the whole posts array. + * + * @param {Array} posts + * @param {number} id + * @param {Object} attrs + * @return {Array} Posts array + */ +function updatePostsAttrs(posts, id, attrs = {}) { + return posts.map(post => { + if (post.id !== id) { + return post; + } + return { + ...post, + ...attrs + }; + }); +} + +/** + * Creates an IFrame that will create the screenshot. + * + * @param {Object} post + * @return {HTMLIFrameElement} iframe + */ +function createScreenshotIframe(post) { + const iframe = document.createElement('iframe'); + iframe.src = post.screenshot_url; + iframe.width = '1200'; + iframe.style = 'visibility: hidden;'; + document.body.appendChild(iframe); + return iframe; +} + +/** + * Returns a callback, that will be bind to the iframe message event. + * + * @param {Array} inProgressPosts + * @param {Function} setPosts + */ +function useIFrameMessageListener(inProgressPosts, setPosts) { + return useCallback(message => { + const { + data + } = message; + if (!data.name || data.name !== 'capture-screenshot-done') { + return; + } + const post = inProgressPosts.find(item => item.id === parseInt(data.id)); + if (!post) { + return; + } + post.iframe.remove(); + setPosts(prevState => updatePostsAttrs(prevState, post.id, { + status: data.success ? SCREENSHOT_STATUS_SUCCEED : SCREENSHOT_STATUS_FAILED, + imageUrl: data.imageUrl + })); + }, [inProgressPosts]); +} + +/** + * Will create a screenshot based on the posts that was passed to it. + * + * @param {Array} initialPosts + * @param {number} numberOfScreenshotInParallel + * @return {{inProgress: Array, succeed: Array, failed: Array, posts: Array, queue: Array}} An array of posts, queue, inProgress, succeed, failed + */ +function useScreenshot(initialPosts, { + numberOfScreenshotInParallel +} = defaultOptions) { + const [posts, setPosts] = useState([]); + + // Holds some kind of computed value of the `posts` state, + // it is been created mostly for convenient workflow and little bit performance optimization. + const queue = useMemo(() => filterPostByStatus(posts, SCREENSHOT_STATUS_QUEUE), [posts]); + const inProgress = useMemo(() => filterPostByStatus(posts, SCREENSHOT_STATUS_IN_PROGRESS), [posts]); + const succeed = useMemo(() => filterPostByStatus(posts, SCREENSHOT_STATUS_SUCCEED), [posts]); + const failed = useMemo(() => filterPostByStatus(posts, SCREENSHOT_STATUS_FAILED), [posts]); + + // Will run every initialPosts change, make the diff between the local state + // and initialPosts and creates a new local state. + useEffect(() => { + const postsDiff = initialPosts.filter(initialPost => !posts.find(statePost => statePost.id === initialPost.id)); + if (!postsDiff.length) { + return; + } + setPosts(prev => [...prev, ...normalizeInitialPosts(postsDiff)]); + }, [initialPosts]); + + // Holds the useCallback that will be used to listen to the screenshot iframe events. + const iframeMessageListener = useIFrameMessageListener(inProgress, setPosts); + + // Listens to the screenshot iframe events + // eventually will remove the iframe and set the post status to succeed or failed. + useEffect(() => { + window.addEventListener('message', iframeMessageListener, false); + return () => { + window.removeEventListener('message', iframeMessageListener); + }; + }, [iframeMessageListener]); + + // Runs every time `posts` state change (all most every event in this hook will trigger change to `posts`), + // this logic response for setting status of the process to DONE if needed + taking the next post and start + // to capture a screenshot. + useEffect(() => { + if (0 === queue.length || inProgress.length >= numberOfScreenshotInParallel) { + return; + } + const [nextPost] = queue; + const iframe = createScreenshotIframe(nextPost); + setPosts(prevState => updatePostsAttrs(prevState, nextPost.id, { + status: SCREENSHOT_STATUS_IN_PROGRESS, + iframe + })); + }, [posts]); + return { + posts, + queue, + inProgress, + succeed, + failed + }; +} + +/***/ }), + +/***/ "../node_modules/gud/index.js": +/*!************************************!*\ + !*** ../node_modules/gud/index.js ***! + \************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +// @flow + + +var key = '__global_unique_id__'; + +module.exports = function() { + return __webpack_require__.g[key] = (__webpack_require__.g[key] || 0) + 1; +}; + + +/***/ }), + +/***/ "../node_modules/invariant/browser.js": +/*!********************************************!*\ + !*** ../node_modules/invariant/browser.js ***! + \********************************************/ +/***/ ((module) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var invariant = function(condition, format, a, b, c, d, e, f) { + if (true) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +}; + +module.exports = invariant; + + +/***/ }), + +/***/ "../node_modules/object-assign/index.js": +/*!**********************************************!*\ + !*** ../node_modules/object-assign/index.js ***! + \**********************************************/ +/***/ ((module) => { + +"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + + +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/checkPropTypes.js": +/*!****************************************************!*\ + !*** ../node_modules/prop-types/checkPropTypes.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var printWarning = function() {}; + +if (true) { + var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); + var loggedTypeFailures = {}; + var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); + + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) { /**/ } + }; +} + +/** + * Assert that the values match with the type specs. + * Error messages are memorized and will only be shown once. + * + * @param {object} typeSpecs Map of name to a ReactPropType + * @param {object} values Runtime values that need to be type-checked + * @param {string} location e.g. "prop", "context", "child context" + * @param {string} componentName Name of the component for error messages. + * @param {?Function} getStack Returns the component stack. + * @private + */ +function checkPropTypes(typeSpecs, values, location, componentName, getStack) { + if (true) { + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== 'function') { + var err = Error( + (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.' + ); + err.name = 'Invariant Violation'; + throw err; + } + error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); + } catch (ex) { + error = ex; + } + if (error && !(error instanceof Error)) { + printWarning( + (componentName || 'React class') + ': type specification of ' + + location + ' `' + typeSpecName + '` is invalid; the type checker ' + + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + + 'You may have forgotten to pass an argument to the type checker ' + + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + + 'shape all require an argument).' + ); + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var stack = getStack ? getStack() : ''; + + printWarning( + 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') + ); + } + } + } + } +} + +/** + * Resets warning cache when testing. + * + * @private + */ +checkPropTypes.resetWarningCache = function() { + if (true) { + loggedTypeFailures = {}; + } +} + +module.exports = checkPropTypes; + + +/***/ }), + +/***/ "../node_modules/prop-types/factoryWithTypeCheckers.js": +/*!*************************************************************!*\ + !*** ../node_modules/prop-types/factoryWithTypeCheckers.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); +var assign = __webpack_require__(/*! object-assign */ "../node_modules/object-assign/index.js"); + +var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); +var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); +var checkPropTypes = __webpack_require__(/*! ./checkPropTypes */ "../node_modules/prop-types/checkPropTypes.js"); + +var printWarning = function() {}; + +if (true) { + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; +} + +function emptyFunctionThatReturnsNull() { + return null; +} + +module.exports = function(isValidElement, throwOnDirectAccess) { + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + /** + * Collection of methods that allow declaration and validation of props that are + * supplied to React components. Example usage: + * + * var Props = require('ReactPropTypes'); + * var MyArticle = React.createClass({ + * propTypes: { + * // An optional string prop named "description". + * description: Props.string, + * + * // A required enum prop named "category". + * category: Props.oneOf(['News','Photos']).isRequired, + * + * // A prop named "dialog" that requires an instance of Dialog. + * dialog: Props.instanceOf(Dialog).isRequired + * }, + * render: function() { ... } + * }); + * + * A more formal specification of how these methods are used: + * + * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) + * decl := ReactPropTypes.{type}(.isRequired)? + * + * Each and every declaration produces a function with the same signature. This + * allows the creation of custom validation functions. For example: + * + * var MyLink = React.createClass({ + * propTypes: { + * // An optional string or URI prop named "href". + * href: function(props, propName, componentName) { + * var propValue = props[propName]; + * if (propValue != null && typeof propValue !== 'string' && + * !(propValue instanceof URI)) { + * return new Error( + * 'Expected a string or an URI for ' + propName + ' in ' + + * componentName + * ); + * } + * } + * }, + * render: function() {...} + * }); + * + * @internal + */ + + var ANONYMOUS = '<>'; + + // Important! + // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. + var ReactPropTypes = { + array: createPrimitiveTypeChecker('array'), + bigint: createPrimitiveTypeChecker('bigint'), + bool: createPrimitiveTypeChecker('boolean'), + func: createPrimitiveTypeChecker('function'), + number: createPrimitiveTypeChecker('number'), + object: createPrimitiveTypeChecker('object'), + string: createPrimitiveTypeChecker('string'), + symbol: createPrimitiveTypeChecker('symbol'), + + any: createAnyTypeChecker(), + arrayOf: createArrayOfTypeChecker, + element: createElementTypeChecker(), + elementType: createElementTypeTypeChecker(), + instanceOf: createInstanceTypeChecker, + node: createNodeChecker(), + objectOf: createObjectOfTypeChecker, + oneOf: createEnumTypeChecker, + oneOfType: createUnionTypeChecker, + shape: createShapeTypeChecker, + exact: createStrictShapeTypeChecker, + }; + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + /*eslint-disable no-self-compare*/ + function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return x !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } + } + /*eslint-enable no-self-compare*/ + + /** + * We use an Error-like object for backward compatibility as people may call + * PropTypes directly and inspect their output. However, we don't use real + * Errors anymore. We don't inspect their stack anyway, and creating them + * is prohibitively expensive if they are created too often, such as what + * happens in oneOfType() for any type before the one that matched. + */ + function PropTypeError(message, data) { + this.message = message; + this.data = data && typeof data === 'object' ? data: {}; + this.stack = ''; + } + // Make `instanceof Error` still work for returned errors. + PropTypeError.prototype = Error.prototype; + + function createChainableTypeChecker(validate) { + if (true) { + var manualPropTypeCallCache = {}; + var manualPropTypeWarningCount = 0; + } + function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { + componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; + + if (secret !== ReactPropTypesSecret) { + if (throwOnDirectAccess) { + // New behavior only for users of `prop-types` package + var err = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + + 'Use `PropTypes.checkPropTypes()` to call them. ' + + 'Read more at http://fb.me/use-check-prop-types' + ); + err.name = 'Invariant Violation'; + throw err; + } else if ( true && typeof console !== 'undefined') { + // Old behavior for people using React.PropTypes + var cacheKey = componentName + ':' + propName; + if ( + !manualPropTypeCallCache[cacheKey] && + // Avoid spamming the console because they are often not actionable except for lib authors + manualPropTypeWarningCount < 3 + ) { + printWarning( + 'You are manually calling a React.PropTypes validation ' + + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + + 'and will throw in the standalone `prop-types` package. ' + + 'You may be seeing this warning due to a third-party PropTypes ' + + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.' + ); + manualPropTypeCallCache[cacheKey] = true; + manualPropTypeWarningCount++; + } + } + } + if (props[propName] == null) { + if (isRequired) { + if (props[propName] === null) { + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); + } + return null; + } else { + return validate(props, propName, componentName, location, propFullName); + } + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; + } + + function createPrimitiveTypeChecker(expectedType) { + function validate(props, propName, componentName, location, propFullName, secret) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== expectedType) { + // `propValue` being instance of, say, date/regexp, pass the 'object' + // check, but we can offer a more precise error message here rather than + // 'of type `object`'. + var preciseType = getPreciseType(propValue); + + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'), + {expectedType: expectedType} + ); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createAnyTypeChecker() { + return createChainableTypeChecker(emptyFunctionThatReturnsNull); + } + + function createArrayOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); + } + var propValue = props[propName]; + if (!Array.isArray(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); + } + for (var i = 0; i < propValue.length; i++) { + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!isValidElement(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!ReactIs.isValidElementType(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createInstanceTypeChecker(expectedClass) { + function validate(props, propName, componentName, location, propFullName) { + if (!(props[propName] instanceof expectedClass)) { + var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createEnumTypeChecker(expectedValues) { + if (!Array.isArray(expectedValues)) { + if (true) { + if (arguments.length > 1) { + printWarning( + 'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' + + 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).' + ); + } else { + printWarning('Invalid argument supplied to oneOf, expected an array.'); + } + } + return emptyFunctionThatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + for (var i = 0; i < expectedValues.length; i++) { + if (is(propValue, expectedValues[i])) { + return null; + } + } + + var valuesString = JSON.stringify(expectedValues, function replacer(key, value) { + var type = getPreciseType(value); + if (type === 'symbol') { + return String(value); + } + return value; + }); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); + } + return createChainableTypeChecker(validate); + } + + function createObjectOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); + } + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); + } + for (var key in propValue) { + if (has(propValue, key)) { + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createUnionTypeChecker(arrayOfTypeCheckers) { + if (!Array.isArray(arrayOfTypeCheckers)) { + true ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : 0; + return emptyFunctionThatReturnsNull; + } + + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (typeof checker !== 'function') { + printWarning( + 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.' + ); + return emptyFunctionThatReturnsNull; + } + } + + function validate(props, propName, componentName, location, propFullName) { + var expectedTypes = []; + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret); + if (checkerResult == null) { + return null; + } + if (checkerResult.data && has(checkerResult.data, 'expectedType')) { + expectedTypes.push(checkerResult.data.expectedType); + } + } + var expectedTypesMessage = (expectedTypes.length > 0) ? ', expected one of type [' + expectedTypes.join(', ') + ']': ''; + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.')); + } + return createChainableTypeChecker(validate); + } + + function createNodeChecker() { + function validate(props, propName, componentName, location, propFullName) { + if (!isNode(props[propName])) { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function invalidValidatorError(componentName, location, propFullName, key, type) { + return new PropTypeError( + (componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + type + '`.' + ); + } + + function createShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + for (var key in shapeTypes) { + var checker = shapeTypes[key]; + if (typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createStrictShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + // We need to check all keys in case some are required but missing from props. + var allKeys = assign({}, props[propName], shapeTypes); + for (var key in allKeys) { + var checker = shapeTypes[key]; + if (has(shapeTypes, key) && typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + if (!checker) { + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') + ); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + + return createChainableTypeChecker(validate); + } + + function isNode(propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + case 'undefined': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (propValue === null || isValidElement(propValue)) { + return true; + } + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } + } + } else { + return false; + } + + return true; + default: + return false; + } + } + + function isSymbol(propType, propValue) { + // Native Symbol. + if (propType === 'symbol') { + return true; + } + + // falsy value can't be a Symbol + if (!propValue) { + return false; + } + + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' + if (propValue['@@toStringTag'] === 'Symbol') { + return true; + } + + // Fallback for non-spec compliant Symbols which are polyfilled. + if (typeof Symbol === 'function' && propValue instanceof Symbol) { + return true; + } + + return false; + } + + // Equivalent of `typeof` but with special handling for array and regexp. + function getPropType(propValue) { + var propType = typeof propValue; + if (Array.isArray(propValue)) { + return 'array'; + } + if (propValue instanceof RegExp) { + // Old webkits (at least until Android 4.0) return 'function' rather than + // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ + // passes PropTypes.object. + return 'object'; + } + if (isSymbol(propType, propValue)) { + return 'symbol'; + } + return propType; + } + + // This handles more types than `getPropType`. Only used for error messages. + // See `createPrimitiveTypeChecker`. + function getPreciseType(propValue) { + if (typeof propValue === 'undefined' || propValue === null) { + return '' + propValue; + } + var propType = getPropType(propValue); + if (propType === 'object') { + if (propValue instanceof Date) { + return 'date'; + } else if (propValue instanceof RegExp) { + return 'regexp'; + } + } + return propType; + } + + // Returns a string that is postfixed to a warning about an invalid type. + // For example, "undefined" or "of type array" + function getPostfixForTypeWarning(value) { + var type = getPreciseType(value); + switch (type) { + case 'array': + case 'object': + return 'an ' + type; + case 'boolean': + case 'date': + case 'regexp': + return 'a ' + type; + default: + return type; + } + } + + // Returns class name of the object, if any. + function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return ANONYMOUS; + } + return propValue.constructor.name; + } + + ReactPropTypes.checkPropTypes = checkPropTypes; + ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/index.js": +/*!*******************************************!*\ + !*** ../node_modules/prop-types/index.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +if (true) { + var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); + + // By explicitly using `prop-types` you are opting into new development behavior. + // http://fb.me/prop-types-in-prod + var throwOnDirectAccess = true; + module.exports = __webpack_require__(/*! ./factoryWithTypeCheckers */ "../node_modules/prop-types/factoryWithTypeCheckers.js")(ReactIs.isElement, throwOnDirectAccess); +} else {} + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/ReactPropTypesSecret.js": +/*!**************************************************************!*\ + !*** ../node_modules/prop-types/lib/ReactPropTypesSecret.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + +module.exports = ReactPropTypesSecret; + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/has.js": +/*!*********************************************!*\ + !*** ../node_modules/prop-types/lib/has.js ***! + \*********************************************/ +/***/ ((module) => { + +module.exports = Function.call.bind(Object.prototype.hasOwnProperty); + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js": +/*!************************************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** @license React v16.13.1 + * react-is.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + + + +if (true) { + (function() { +'use strict'; + +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + +var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; +var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; +var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8; +var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; +var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4; +var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7; + +function isValidElementType(type) { + return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill. + type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE); +} + +function typeOf(object) { + if (typeof object === 'object' && object !== null) { + var $$typeof = object.$$typeof; + + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + var type = object.type; + + switch (type) { + case REACT_ASYNC_MODE_TYPE: + case REACT_CONCURRENT_MODE_TYPE: + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + return type; + + default: + var $$typeofType = type && type.$$typeof; + + switch ($$typeofType) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + case REACT_PROVIDER_TYPE: + return $$typeofType; + + default: + return $$typeof; + } + + } + + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + + return undefined; +} // AsyncMode is deprecated along with isAsyncMode + +var AsyncMode = REACT_ASYNC_MODE_TYPE; +var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE; +var ContextConsumer = REACT_CONTEXT_TYPE; +var ContextProvider = REACT_PROVIDER_TYPE; +var Element = REACT_ELEMENT_TYPE; +var ForwardRef = REACT_FORWARD_REF_TYPE; +var Fragment = REACT_FRAGMENT_TYPE; +var Lazy = REACT_LAZY_TYPE; +var Memo = REACT_MEMO_TYPE; +var Portal = REACT_PORTAL_TYPE; +var Profiler = REACT_PROFILER_TYPE; +var StrictMode = REACT_STRICT_MODE_TYPE; +var Suspense = REACT_SUSPENSE_TYPE; +var hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated + +function isAsyncMode(object) { + { + if (!hasWarnedAboutDeprecatedIsAsyncMode) { + hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint + + console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.'); + } + } + + return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE; +} +function isConcurrentMode(object) { + return typeOf(object) === REACT_CONCURRENT_MODE_TYPE; +} +function isContextConsumer(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; +} +function isContextProvider(object) { + return typeOf(object) === REACT_PROVIDER_TYPE; +} +function isElement(object) { + return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; +} +function isForwardRef(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; +} +function isFragment(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; +} +function isLazy(object) { + return typeOf(object) === REACT_LAZY_TYPE; +} +function isMemo(object) { + return typeOf(object) === REACT_MEMO_TYPE; +} +function isPortal(object) { + return typeOf(object) === REACT_PORTAL_TYPE; +} +function isProfiler(object) { + return typeOf(object) === REACT_PROFILER_TYPE; +} +function isStrictMode(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; +} +function isSuspense(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; +} + +exports.AsyncMode = AsyncMode; +exports.ConcurrentMode = ConcurrentMode; +exports.ContextConsumer = ContextConsumer; +exports.ContextProvider = ContextProvider; +exports.Element = Element; +exports.ForwardRef = ForwardRef; +exports.Fragment = Fragment; +exports.Lazy = Lazy; +exports.Memo = Memo; +exports.Portal = Portal; +exports.Profiler = Profiler; +exports.StrictMode = StrictMode; +exports.Suspense = Suspense; +exports.isAsyncMode = isAsyncMode; +exports.isConcurrentMode = isConcurrentMode; +exports.isContextConsumer = isContextConsumer; +exports.isContextProvider = isContextProvider; +exports.isElement = isElement; +exports.isForwardRef = isForwardRef; +exports.isFragment = isFragment; +exports.isLazy = isLazy; +exports.isMemo = isMemo; +exports.isPortal = isPortal; +exports.isProfiler = isProfiler; +exports.isStrictMode = isStrictMode; +exports.isSuspense = isSuspense; +exports.isValidElementType = isValidElementType; +exports.typeOf = typeOf; + })(); +} + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/index.js": +/*!*****************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/index.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +if (false) {} else { + module.exports = __webpack_require__(/*! ./cjs/react-is.development.js */ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js"); +} + + +/***/ }), + +/***/ "../node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js": +/*!*****************************************************************************!*\ + !*** ../node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ polyfill: () => (/* binding */ polyfill) +/* harmony export */ }); +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +function componentWillMount() { + // Call this.constructor.gDSFP to support sub-classes. + var state = this.constructor.getDerivedStateFromProps(this.props, this.state); + if (state !== null && state !== undefined) { + this.setState(state); + } +} + +function componentWillReceiveProps(nextProps) { + // Call this.constructor.gDSFP to support sub-classes. + // Use the setState() updater to ensure state isn't stale in certain edge cases. + function updater(prevState) { + var state = this.constructor.getDerivedStateFromProps(nextProps, prevState); + return state !== null && state !== undefined ? state : null; + } + // Binding "this" is important for shallow renderer support. + this.setState(updater.bind(this)); +} + +function componentWillUpdate(nextProps, nextState) { + try { + var prevProps = this.props; + var prevState = this.state; + this.props = nextProps; + this.state = nextState; + this.__reactInternalSnapshotFlag = true; + this.__reactInternalSnapshot = this.getSnapshotBeforeUpdate( + prevProps, + prevState + ); + } finally { + this.props = prevProps; + this.state = prevState; + } +} + +// React may warn about cWM/cWRP/cWU methods being deprecated. +// Add a flag to suppress these warnings for this special case. +componentWillMount.__suppressDeprecationWarning = true; +componentWillReceiveProps.__suppressDeprecationWarning = true; +componentWillUpdate.__suppressDeprecationWarning = true; + +function polyfill(Component) { + var prototype = Component.prototype; + + if (!prototype || !prototype.isReactComponent) { + throw new Error('Can only polyfill class components'); + } + + if ( + typeof Component.getDerivedStateFromProps !== 'function' && + typeof prototype.getSnapshotBeforeUpdate !== 'function' + ) { + return Component; + } + + // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Error if any of these lifecycles are present, + // Because they would work differently between older and newer (16.3+) versions of React. + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + if (typeof prototype.componentWillMount === 'function') { + foundWillMountName = 'componentWillMount'; + } else if (typeof prototype.UNSAFE_componentWillMount === 'function') { + foundWillMountName = 'UNSAFE_componentWillMount'; + } + if (typeof prototype.componentWillReceiveProps === 'function') { + foundWillReceivePropsName = 'componentWillReceiveProps'; + } else if (typeof prototype.UNSAFE_componentWillReceiveProps === 'function') { + foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; + } + if (typeof prototype.componentWillUpdate === 'function') { + foundWillUpdateName = 'componentWillUpdate'; + } else if (typeof prototype.UNSAFE_componentWillUpdate === 'function') { + foundWillUpdateName = 'UNSAFE_componentWillUpdate'; + } + if ( + foundWillMountName !== null || + foundWillReceivePropsName !== null || + foundWillUpdateName !== null + ) { + var componentName = Component.displayName || Component.name; + var newApiName = + typeof Component.getDerivedStateFromProps === 'function' + ? 'getDerivedStateFromProps()' + : 'getSnapshotBeforeUpdate()'; + + throw Error( + 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + + componentName + + ' uses ' + + newApiName + + ' but also contains the following legacy lifecycles:' + + (foundWillMountName !== null ? '\n ' + foundWillMountName : '') + + (foundWillReceivePropsName !== null + ? '\n ' + foundWillReceivePropsName + : '') + + (foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '') + + '\n\nThe above lifecycles should be removed. Learn more about this warning here:\n' + + 'https://fb.me/react-async-component-lifecycle-hooks' + ); + } + + // React <= 16.2 does not support static getDerivedStateFromProps. + // As a workaround, use cWM and cWRP to invoke the new static lifecycle. + // Newer versions of React will ignore these lifecycles if gDSFP exists. + if (typeof Component.getDerivedStateFromProps === 'function') { + prototype.componentWillMount = componentWillMount; + prototype.componentWillReceiveProps = componentWillReceiveProps; + } + + // React <= 16.2 does not support getSnapshotBeforeUpdate. + // As a workaround, use cWU to invoke the new lifecycle. + // Newer versions of React will ignore that lifecycle if gSBU exists. + if (typeof prototype.getSnapshotBeforeUpdate === 'function') { + if (typeof prototype.componentDidUpdate !== 'function') { + throw new Error( + 'Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype' + ); + } + + prototype.componentWillUpdate = componentWillUpdate; + + var componentDidUpdate = prototype.componentDidUpdate; + + prototype.componentDidUpdate = function componentDidUpdatePolyfill( + prevProps, + prevState, + maybeSnapshot + ) { + // 16.3+ will not execute our will-update method; + // It will pass a snapshot value to did-update though. + // Older versions will require our polyfilled will-update value. + // We need to handle both cases, but can't just check for the presence of "maybeSnapshot", + // Because for <= 15.x versions this might be a "prevContext" object. + // We also can't just check "__reactInternalSnapshot", + // Because get-snapshot might return a falsy value. + // So check for the explicit __reactInternalSnapshotFlag flag to determine behavior. + var snapshot = this.__reactInternalSnapshotFlag + ? this.__reactInternalSnapshot + : maybeSnapshot; + + componentDidUpdate.call(this, prevProps, prevState, snapshot); + }; + } + + return Component; +} + + + + +/***/ }), + +/***/ "../node_modules/warning/warning.js": +/*!******************************************!*\ + !*** ../node_modules/warning/warning.js ***! + \******************************************/ +/***/ ((module) => { + +"use strict"; +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var __DEV__ = "development" !== 'production'; + +var warning = function() {}; + +if (__DEV__) { + var printWarning = function printWarning(format, args) { + var len = arguments.length; + args = new Array(len > 1 ? len - 1 : 0); + for (var key = 1; key < len; key++) { + args[key - 1] = arguments[key]; + } + var argIndex = 0; + var message = 'Warning: ' + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + } + + warning = function(condition, format, args) { + var len = arguments.length; + args = new Array(len > 2 ? len - 2 : 0); + for (var key = 2; key < len; key++) { + args[key - 2] = arguments[key]; + } + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + if (!condition) { + printWarning.apply(null, [format].concat(args)); + } + }; +} + +module.exports = warning; + + +/***/ }), + +/***/ "react": +/*!************************!*\ + !*** external "React" ***! + \************************/ +/***/ ((module) => { + +"use strict"; +module.exports = React; + +/***/ }), + +/***/ "react-dom": +/*!***************************!*\ + !*** external "ReactDOM" ***! + \***************************/ +/***/ ((module) => { + +"use strict"; +module.exports = ReactDOM; + +/***/ }), + +/***/ "@elementor/app-ui": +/*!*********************************************!*\ + !*** external "elementorAppPackages.appUi" ***! + \*********************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorAppPackages.appUi; + +/***/ }), + +/***/ "@elementor/hooks": +/*!*********************************************!*\ + !*** external "elementorAppPackages.hooks" ***! + \*********************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorAppPackages.hooks; + +/***/ }), + +/***/ "@elementor/router": +/*!**********************************************!*\ + !*** external "elementorAppPackages.router" ***! + \**********************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorAppPackages.router; + +/***/ }), + +/***/ "@elementor/site-editor": +/*!**************************************************!*\ + !*** external "elementorAppPackages.siteEditor" ***! + \**************************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorAppPackages.siteEditor; + +/***/ }), + +/***/ "@elementor/ui": +/*!*********************************!*\ + !*** external "elementorV2.ui" ***! + \*********************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorV2.ui; + +/***/ }), + +/***/ "@wordpress/i18n": +/*!**************************!*\ + !*** external "wp.i18n" ***! + \**************************/ +/***/ ((module) => { + +"use strict"; +module.exports = wp.i18n; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/extends.js": +/*!*********************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/extends.js ***! + \*********************************************************/ +/***/ ((module) => { + +function _extends() { + return module.exports = _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends.apply(null, arguments); +} +module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js": +/*!***********************************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! + \***********************************************************************/ +/***/ ((module) => { + +function _interopRequireDefault(e) { + return e && e.__esModule ? e : { + "default": e + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/core-js/internals/a-callable.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/a-callable.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var tryToString = __webpack_require__(/*! ../internals/try-to-string */ "../node_modules/core-js/internals/try-to-string.js"); + +var $TypeError = TypeError; + +// `Assert: IsCallable(argument) is true` +module.exports = function (argument) { + if (isCallable(argument)) return argument; + throw new $TypeError(tryToString(argument) + ' is not a function'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/an-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/an-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $String = String; +var $TypeError = TypeError; + +// `Assert: Type(argument) is Object` +module.exports = function (argument) { + if (isObject(argument)) return argument; + throw new $TypeError($String(argument) + ' is not an object'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-includes.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/array-includes.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ "../node_modules/core-js/internals/to-absolute-index.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); + +// `Array.prototype.{ indexOf, includes }` methods implementation +var createMethod = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = lengthOfArrayLike(O); + if (length === 0) return !IS_INCLUDES && -1; + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare -- NaN check + if (IS_INCLUDES && el !== el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare -- NaN check + if (value !== value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) { + if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +module.exports = { + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod(false) +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-set-length.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/array-set-length.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var isArray = __webpack_require__(/*! ../internals/is-array */ "../node_modules/core-js/internals/is-array.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Safari < 13 does not throw an error in this case +var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () { + // makes no sense without proper strict mode support + if (this !== undefined) return true; + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).length = 1; + } catch (error) { + return error instanceof TypeError; + } +}(); + +module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { + if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) { + throw new $TypeError('Cannot set read only .length'); + } return O.length = length; +} : function (O, length) { + return O.length = length; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/classof-raw.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/classof-raw.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var toString = uncurryThis({}.toString); +var stringSlice = uncurryThis(''.slice); + +module.exports = function (it) { + return stringSlice(toString(it), 8, -1); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/copy-constructor-properties.js": +/*!************************************************************************!*\ + !*** ../node_modules/core-js/internals/copy-constructor-properties.js ***! + \************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var ownKeys = __webpack_require__(/*! ../internals/own-keys */ "../node_modules/core-js/internals/own-keys.js"); +var getOwnPropertyDescriptorModule = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); + +module.exports = function (target, source, exceptions) { + var keys = ownKeys(source); + var defineProperty = definePropertyModule.f; + var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) { + defineProperty(target, key, getOwnPropertyDescriptor(source, key)); + } + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-non-enumerable-property.js": +/*!***************************************************************************!*\ + !*** ../node_modules/core-js/internals/create-non-enumerable-property.js ***! + \***************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); + +module.exports = DESCRIPTORS ? function (object, key, value) { + return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-property-descriptor.js": +/*!***********************************************************************!*\ + !*** ../node_modules/core-js/internals/create-property-descriptor.js ***! + \***********************************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-built-in.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/define-built-in.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var makeBuiltIn = __webpack_require__(/*! ../internals/make-built-in */ "../node_modules/core-js/internals/make-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +module.exports = function (O, key, value, options) { + if (!options) options = {}; + var simple = options.enumerable; + var name = options.name !== undefined ? options.name : key; + if (isCallable(value)) makeBuiltIn(value, name, options); + if (options.global) { + if (simple) O[key] = value; + else defineGlobalProperty(key, value); + } else { + try { + if (!options.unsafe) delete O[key]; + else if (O[key]) simple = true; + } catch (error) { /* empty */ } + if (simple) O[key] = value; + else definePropertyModule.f(O, key, { + value: value, + enumerable: false, + configurable: !options.nonConfigurable, + writable: !options.nonWritable + }); + } return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-global-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/define-global-property.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; + +module.exports = function (key, value) { + try { + defineProperty(globalThis, key, { value: value, configurable: true, writable: true }); + } catch (error) { + globalThis[key] = value; + } return value; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/descriptors.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/descriptors.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// Detect IE8's incomplete defineProperty implementation +module.exports = !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/document-create-element.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/document-create-element.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var document = globalThis.document; +// typeof document.createElement is 'object' in old IE +var EXISTS = isObject(document) && isObject(document.createElement); + +module.exports = function (it) { + return EXISTS ? document.createElement(it) : {}; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/does-not-exceed-safe-integer.js ***! + \*************************************************************************/ +/***/ ((module) => { + +"use strict"; + +var $TypeError = TypeError; +var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 + +module.exports = function (it) { + if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded'); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/enum-bug-keys.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/enum-bug-keys.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +// IE8- don't enum bug keys +module.exports = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' +]; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-user-agent.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-user-agent.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var navigator = globalThis.navigator; +var userAgent = navigator && navigator.userAgent; + +module.exports = userAgent ? String(userAgent) : ''; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-v8-version.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-v8-version.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var userAgent = __webpack_require__(/*! ../internals/environment-user-agent */ "../node_modules/core-js/internals/environment-user-agent.js"); + +var process = globalThis.process; +var Deno = globalThis.Deno; +var versions = process && process.versions || Deno && Deno.version; +var v8 = versions && versions.v8; +var match, version; + +if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} + +// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` +// so check `userAgent` even if `.v8` exists, but 0 +if (!version && userAgent) { + match = userAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent.match(/Chrome\/(\d+)/); + if (match) version = +match[1]; + } +} + +module.exports = version; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/export.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/export.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var getOwnPropertyDescriptor = (__webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js").f); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var defineBuiltIn = __webpack_require__(/*! ../internals/define-built-in */ "../node_modules/core-js/internals/define-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); +var copyConstructorProperties = __webpack_require__(/*! ../internals/copy-constructor-properties */ "../node_modules/core-js/internals/copy-constructor-properties.js"); +var isForced = __webpack_require__(/*! ../internals/is-forced */ "../node_modules/core-js/internals/is-forced.js"); + +/* + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.dontCallGetSet - prevent calling a getter on target + options.name - the .name of the function if it does not match the key +*/ +module.exports = function (options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED, target, key, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = globalThis; + } else if (STATIC) { + target = globalThis[TARGET] || defineGlobalProperty(TARGET, {}); + } else { + target = globalThis[TARGET] && globalThis[TARGET].prototype; + } + if (target) for (key in source) { + sourceProperty = source[key]; + if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; + FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); + // contained in target + if (!FORCED && targetProperty !== undefined) { + if (typeof sourceProperty == typeof targetProperty) continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + // add a flag to not completely full polyfills + if (options.sham || (targetProperty && targetProperty.sham)) { + createNonEnumerableProperty(sourceProperty, 'sham', true); + } + defineBuiltIn(target, key, sourceProperty, options); + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/fails.js": +/*!**************************************************!*\ + !*** ../node_modules/core-js/internals/fails.js ***! + \**************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (exec) { + try { + return !!exec(); + } catch (error) { + return true; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-bind-native.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/function-bind-native.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +module.exports = !fails(function () { + // eslint-disable-next-line es/no-function-prototype-bind -- safe + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test != 'function' || test.hasOwnProperty('prototype'); +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-call.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-call.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var call = Function.prototype.call; + +module.exports = NATIVE_BIND ? call.bind(call) : function () { + return call.apply(call, arguments); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-name.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-name.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); + +var FunctionPrototype = Function.prototype; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor; + +var EXISTS = hasOwn(FunctionPrototype, 'name'); +// additional protection from minified / mangled / dropped function names +var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; +var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable)); + +module.exports = { + EXISTS: EXISTS, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-uncurry-this.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/function-uncurry-this.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var FunctionPrototype = Function.prototype; +var call = FunctionPrototype.call; +var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call); + +module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) { + return function () { + return call.apply(fn, arguments); + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-built-in.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/get-built-in.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var aFunction = function (argument) { + return isCallable(argument) ? argument : undefined; +}; + +module.exports = function (namespace, method) { + return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-method.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/get-method.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var aCallable = __webpack_require__(/*! ../internals/a-callable */ "../node_modules/core-js/internals/a-callable.js"); +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +// `GetMethod` abstract operation +// https://tc39.es/ecma262/#sec-getmethod +module.exports = function (V, P) { + var func = V[P]; + return isNullOrUndefined(func) ? undefined : aCallable(func); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/global-this.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/global-this.js ***! + \********************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + +var check = function (it) { + return it && it.Math === Math && it; +}; + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +module.exports = + // eslint-disable-next-line es/no-global-this -- safe + check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == 'object' && self) || + check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) || + check(typeof this == 'object' && this) || + // eslint-disable-next-line no-new-func -- fallback + (function () { return this; })() || Function('return this')(); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/has-own-property.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/has-own-property.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); + +var hasOwnProperty = uncurryThis({}.hasOwnProperty); + +// `HasOwnProperty` abstract operation +// https://tc39.es/ecma262/#sec-hasownproperty +// eslint-disable-next-line es/no-object-hasown -- safe +module.exports = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty(toObject(it), key); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/hidden-keys.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/hidden-keys.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = {}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ie8-dom-define.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/ie8-dom-define.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var createElement = __webpack_require__(/*! ../internals/document-create-element */ "../node_modules/core-js/internals/document-create-element.js"); + +// Thanks to IE8 for its funny defineProperty +module.exports = !DESCRIPTORS && !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(createElement('div'), 'a', { + get: function () { return 7; } + }).a !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/indexed-object.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/indexed-object.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +var $Object = Object; +var split = uncurryThis(''.split); + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +module.exports = fails(function () { + // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 + // eslint-disable-next-line no-prototype-builtins -- safe + return !$Object('z').propertyIsEnumerable(0); +}) ? function (it) { + return classof(it) === 'String' ? split(it, '') : $Object(it); +} : $Object; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/inspect-source.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/inspect-source.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +var functionToString = uncurryThis(Function.toString); + +// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper +if (!isCallable(store.inspectSource)) { + store.inspectSource = function (it) { + return functionToString(it); + }; +} + +module.exports = store.inspectSource; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/internal-state.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/internal-state.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/weak-map-basic-detection */ "../node_modules/core-js/internals/weak-map-basic-detection.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var shared = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); +var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "../node_modules/core-js/internals/shared-key.js"); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; +var TypeError = globalThis.TypeError; +var WeakMap = globalThis.WeakMap; +var set, get, has; + +var enforce = function (it) { + return has(it) ? get(it) : set(it, {}); +}; + +var getterFor = function (TYPE) { + return function (it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw new TypeError('Incompatible receiver, ' + TYPE + ' required'); + } return state; + }; +}; + +if (NATIVE_WEAK_MAP || shared.state) { + var store = shared.state || (shared.state = new WeakMap()); + /* eslint-disable no-self-assign -- prototype methods protection */ + store.get = store.get; + store.has = store.has; + store.set = store.set; + /* eslint-enable no-self-assign -- prototype methods protection */ + set = function (it, metadata) { + if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + store.set(it, metadata); + return metadata; + }; + get = function (it) { + return store.get(it) || {}; + }; + has = function (it) { + return store.has(it); + }; +} else { + var STATE = sharedKey('state'); + hiddenKeys[STATE] = true; + set = function (it, metadata) { + if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty(it, STATE, metadata); + return metadata; + }; + get = function (it) { + return hasOwn(it, STATE) ? it[STATE] : {}; + }; + has = function (it) { + return hasOwn(it, STATE); + }; +} + +module.exports = { + set: set, + get: get, + has: has, + enforce: enforce, + getterFor: getterFor +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-array.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/is-array.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +// `IsArray` abstract operation +// https://tc39.es/ecma262/#sec-isarray +// eslint-disable-next-line es/no-array-isarray -- safe +module.exports = Array.isArray || function isArray(argument) { + return classof(argument) === 'Array'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-callable.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/is-callable.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot +var documentAll = typeof document == 'object' && document.all; + +// `IsCallable` abstract operation +// https://tc39.es/ecma262/#sec-iscallable +// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing +module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) { + return typeof argument == 'function' || argument === documentAll; +} : function (argument) { + return typeof argument == 'function'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-forced.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-forced.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var replacement = /#|\.prototype\./; + +var isForced = function (feature, detection) { + var value = data[normalize(feature)]; + return value === POLYFILL ? true + : value === NATIVE ? false + : isCallable(detection) ? fails(detection) + : !!detection; +}; + +var normalize = isForced.normalize = function (string) { + return String(string).replace(replacement, '.').toLowerCase(); +}; + +var data = isForced.data = {}; +var NATIVE = isForced.NATIVE = 'N'; +var POLYFILL = isForced.POLYFILL = 'P'; + +module.exports = isForced; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-null-or-undefined.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/is-null-or-undefined.js ***! + \*****************************************************************/ +/***/ ((module) => { + +"use strict"; + +// we can't use just `it == null` since of `document.all` special case +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec +module.exports = function (it) { + return it === null || it === undefined; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +module.exports = function (it) { + return typeof it == 'object' ? it !== null : isCallable(it); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-pure.js": +/*!****************************************************!*\ + !*** ../node_modules/core-js/internals/is-pure.js ***! + \****************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = false; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-symbol.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-symbol.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isPrototypeOf = __webpack_require__(/*! ../internals/object-is-prototype-of */ "../node_modules/core-js/internals/object-is-prototype-of.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var $Object = Object; + +module.exports = USE_SYMBOL_AS_UID ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + var $Symbol = getBuiltIn('Symbol'); + return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/length-of-array-like.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/length-of-array-like.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toLength = __webpack_require__(/*! ../internals/to-length */ "../node_modules/core-js/internals/to-length.js"); + +// `LengthOfArrayLike` abstract operation +// https://tc39.es/ecma262/#sec-lengthofarraylike +module.exports = function (obj) { + return toLength(obj.length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/make-built-in.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/make-built-in.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(/*! ../internals/function-name */ "../node_modules/core-js/internals/function-name.js").CONFIGURABLE); +var inspectSource = __webpack_require__(/*! ../internals/inspect-source */ "../node_modules/core-js/internals/inspect-source.js"); +var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "../node_modules/core-js/internals/internal-state.js"); + +var enforceInternalState = InternalStateModule.enforce; +var getInternalState = InternalStateModule.get; +var $String = String; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; +var stringSlice = uncurryThis(''.slice); +var replace = uncurryThis(''.replace); +var join = uncurryThis([].join); + +var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () { + return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; +}); + +var TEMPLATE = String(String).split('String'); + +var makeBuiltIn = module.exports = function (value, name, options) { + if (stringSlice($String(name), 0, 7) === 'Symbol(') { + name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']'; + } + if (options && options.getter) name = 'get ' + name; + if (options && options.setter) name = 'set ' + name; + if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) { + if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true }); + else value.name = name; + } + if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { + defineProperty(value, 'length', { value: options.arity }); + } + try { + if (options && hasOwn(options, 'constructor') && options.constructor) { + if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false }); + // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable + } else if (value.prototype) value.prototype = undefined; + } catch (error) { /* empty */ } + var state = enforceInternalState(value); + if (!hasOwn(state, 'source')) { + state.source = join(TEMPLATE, typeof name == 'string' ? name : ''); + } return value; +}; + +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +// eslint-disable-next-line no-extend-native -- required +Function.prototype.toString = makeBuiltIn(function toString() { + return isCallable(this) && getInternalState(this).source || inspectSource(this); +}, 'toString'); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/math-trunc.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/math-trunc.js ***! + \*******************************************************/ +/***/ ((module) => { + +"use strict"; + +var ceil = Math.ceil; +var floor = Math.floor; + +// `Math.trunc` method +// https://tc39.es/ecma262/#sec-math.trunc +// eslint-disable-next-line es/no-math-trunc -- safe +module.exports = Math.trunc || function trunc(x) { + var n = +x; + return (n > 0 ? floor : ceil)(n); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-define-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-define-property.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); +var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(/*! ../internals/v8-prototype-define-bug */ "../node_modules/core-js/internals/v8-prototype-define-bug.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var $defineProperty = Object.defineProperty; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var ENUMERABLE = 'enumerable'; +var CONFIGURABLE = 'configurable'; +var WRITABLE = 'writable'; + +// `Object.defineProperty` method +// https://tc39.es/ecma262/#sec-object.defineproperty +exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor(O, P); + if (current && current[WRITABLE]) { + O[P] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } return $defineProperty(O, P, Attributes); +} : $defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return $defineProperty(O, P, Attributes); + } catch (error) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-descriptor.js": +/*!*******************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-descriptor.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ "../node_modules/core-js/internals/object-property-is-enumerable.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// `Object.getOwnPropertyDescriptor` method +// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor +exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject(O); + P = toPropertyKey(P); + if (IE8_DOM_DEFINE) try { + return $getOwnPropertyDescriptor(O, P); + } catch (error) { /* empty */ } + if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-names.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-names.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ "../node_modules/core-js/internals/object-keys-internal.js"); +var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "../node_modules/core-js/internals/enum-bug-keys.js"); + +var hiddenKeys = enumBugKeys.concat('length', 'prototype'); + +// `Object.getOwnPropertyNames` method +// https://tc39.es/ecma262/#sec-object.getownpropertynames +// eslint-disable-next-line es/no-object-getownpropertynames -- safe +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return internalObjectKeys(O, hiddenKeys); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-symbols.js": +/*!****************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-symbols.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe +exports.f = Object.getOwnPropertySymbols; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-is-prototype-of.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-is-prototype-of.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +module.exports = uncurryThis({}.isPrototypeOf); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-keys-internal.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/object-keys-internal.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var indexOf = (__webpack_require__(/*! ../internals/array-includes */ "../node_modules/core-js/internals/array-includes.js").indexOf); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var push = uncurryThis([].push); + +module.exports = function (object, names) { + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key; + for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key); + // Don't enum bug & hidden keys + while (names.length > i) if (hasOwn(O, key = names[i++])) { + ~indexOf(result, key) || push(result, key); + } + return result; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-property-is-enumerable.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-property-is-enumerable.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +var $propertyIsEnumerable = {}.propertyIsEnumerable; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Nashorn ~ JDK8 bug +var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1); + +// `Object.prototype.propertyIsEnumerable` method implementation +// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable +exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) { + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; +} : $propertyIsEnumerable; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ordinary-to-primitive.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/ordinary-to-primitive.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $TypeError = TypeError; + +// `OrdinaryToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-ordinarytoprimitive +module.exports = function (input, pref) { + var fn, val; + if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val; + if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + throw new $TypeError("Can't convert object to primitive value"); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/own-keys.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/own-keys.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var getOwnPropertyNamesModule = __webpack_require__(/*! ../internals/object-get-own-property-names */ "../node_modules/core-js/internals/object-get-own-property-names.js"); +var getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ "../node_modules/core-js/internals/object-get-own-property-symbols.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); + +var concat = uncurryThis([].concat); + +// all object keys, includes non-enumerable and symbols +module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { + var keys = getOwnPropertyNamesModule.f(anObject(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/require-object-coercible.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/require-object-coercible.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +var $TypeError = TypeError; + +// `RequireObjectCoercible` abstract operation +// https://tc39.es/ecma262/#sec-requireobjectcoercible +module.exports = function (it) { + if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-key.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/shared-key.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); + +var keys = shared('keys'); + +module.exports = function (key) { + return keys[key] || (keys[key] = uid(key)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-store.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/shared-store.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "../node_modules/core-js/internals/is-pure.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +var SHARED = '__core-js_shared__'; +var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {}); + +(store.versions || (store.versions = [])).push({ + version: '3.38.1', + mode: IS_PURE ? 'pure' : 'global', + copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)', + license: 'https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE', + source: 'https://github.com/zloirock/core-js' +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/shared.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +module.exports = function (key, value) { + return store[key] || (store[key] = value || {}); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/symbol-constructor-detection.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/symbol-constructor-detection.js ***! + \*************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var V8_VERSION = __webpack_require__(/*! ../internals/environment-v8-version */ "../node_modules/core-js/internals/environment-v8-version.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var $String = globalThis.String; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing +module.exports = !!Object.getOwnPropertySymbols && !fails(function () { + var symbol = Symbol('symbol detection'); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will, + // of course, fail. + return !$String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION && V8_VERSION < 41; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-absolute-index.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-absolute-index.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var max = Math.max; +var min = Math.min; + +// Helper for a popular repeating case of the spec: +// Let integer be ? ToInteger(index). +// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). +module.exports = function (index, length) { + var integer = toIntegerOrInfinity(index); + return integer < 0 ? max(integer + length, 0) : min(integer, length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-indexed-object.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-indexed-object.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +// toObject with fallback for non-array-like ES3 strings +var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "../node_modules/core-js/internals/indexed-object.js"); +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +module.exports = function (it) { + return IndexedObject(requireObjectCoercible(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-integer-or-infinity.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/to-integer-or-infinity.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var trunc = __webpack_require__(/*! ../internals/math-trunc */ "../node_modules/core-js/internals/math-trunc.js"); + +// `ToIntegerOrInfinity` abstract operation +// https://tc39.es/ecma262/#sec-tointegerorinfinity +module.exports = function (argument) { + var number = +argument; + // eslint-disable-next-line no-self-compare -- NaN check + return number !== number || number === 0 ? 0 : trunc(number); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-length.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-length.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var min = Math.min; + +// `ToLength` abstract operation +// https://tc39.es/ecma262/#sec-tolength +module.exports = function (argument) { + var len = toIntegerOrInfinity(argument); + return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +var $Object = Object; + +// `ToObject` abstract operation +// https://tc39.es/ecma262/#sec-toobject +module.exports = function (argument) { + return $Object(requireObjectCoercible(argument)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-primitive.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/to-primitive.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); +var getMethod = __webpack_require__(/*! ../internals/get-method */ "../node_modules/core-js/internals/get-method.js"); +var ordinaryToPrimitive = __webpack_require__(/*! ../internals/ordinary-to-primitive */ "../node_modules/core-js/internals/ordinary-to-primitive.js"); +var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "../node_modules/core-js/internals/well-known-symbol.js"); + +var $TypeError = TypeError; +var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); + +// `ToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-toprimitive +module.exports = function (input, pref) { + if (!isObject(input) || isSymbol(input)) return input; + var exoticToPrim = getMethod(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = call(exoticToPrim, input, pref); + if (!isObject(result) || isSymbol(result)) return result; + throw new $TypeError("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-property-key.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/to-property-key.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ "../node_modules/core-js/internals/to-primitive.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); + +// `ToPropertyKey` abstract operation +// https://tc39.es/ecma262/#sec-topropertykey +module.exports = function (argument) { + var key = toPrimitive(argument, 'string'); + return isSymbol(key) ? key : key + ''; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/try-to-string.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/try-to-string.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +var $String = String; + +module.exports = function (argument) { + try { + return $String(argument); + } catch (error) { + return 'Object'; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/uid.js": +/*!************************************************!*\ + !*** ../node_modules/core-js/internals/uid.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var id = 0; +var postfix = Math.random(); +var toString = uncurryThis(1.0.toString); + +module.exports = function (key) { + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/use-symbol-as-uid.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/use-symbol-as-uid.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); + +module.exports = NATIVE_SYMBOL + && !Symbol.sham + && typeof Symbol.iterator == 'symbol'; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/v8-prototype-define-bug.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/v8-prototype-define-bug.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// V8 ~ Chrome 36- +// https://bugs.chromium.org/p/v8/issues/detail?id=3334 +module.exports = DESCRIPTORS && fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype !== 42; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/weak-map-basic-detection.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/weak-map-basic-detection.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var WeakMap = globalThis.WeakMap; + +module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap)); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/well-known-symbol.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/well-known-symbol.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var Symbol = globalThis.Symbol; +var WellKnownSymbolsStore = shared('wks'); +var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid; + +module.exports = function (name) { + if (!hasOwn(WellKnownSymbolsStore, name)) { + WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name) + ? Symbol[name] + : createWellKnownSymbol('Symbol.' + name); + } return WellKnownSymbolsStore[name]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/modules/es.array.push.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/modules/es.array.push.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var $ = __webpack_require__(/*! ../internals/export */ "../node_modules/core-js/internals/export.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); +var setArrayLength = __webpack_require__(/*! ../internals/array-set-length */ "../node_modules/core-js/internals/array-set-length.js"); +var doesNotExceedSafeInteger = __webpack_require__(/*! ../internals/does-not-exceed-safe-integer */ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +var INCORRECT_TO_LENGTH = fails(function () { + return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; +}); + +// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError +// https://bugs.chromium.org/p/v8/issues/detail?id=12681 +var properErrorOnNonWritableLength = function () { + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).push(); + } catch (error) { + return error instanceof TypeError; + } +}; + +var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); + +// `Array.prototype.push` method +// https://tc39.es/ecma262/#sec-array.prototype.push +$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + push: function push(item) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var argCount = arguments.length; + doesNotExceedSafeInteger(len + argCount); + for (var i = 0; i < argCount; i++) { + O[len] = arguments[i]; + len++; + } + setArrayLength(O, len); + return len; + } +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!**************************************!*\ + !*** ../core/app/assets/js/index.js ***! + \**************************************/ + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _siteEditor = _interopRequireDefault(__webpack_require__(/*! ../../modules/site-editor/assets/js/site-editor */ "../core/app/modules/site-editor/assets/js/site-editor.js")); +var _module = _interopRequireDefault(__webpack_require__(/*! ../../modules/import-export-customization/assets/js/module */ "../core/app/modules/import-export-customization/assets/js/module.js")); +new _siteEditor.default(); +new _module.default(); +})(); + +/******/ })() +; +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/assets/js/app.min.js b/assets/js/app.min.js new file mode 100644 index 00000000..983ba9bb --- /dev/null +++ b/assets/js/app.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +(()=>{var e={4047:()=>{},1260:()=>{},9652:()=>{},3762:()=>{},8515:()=>{},734:()=>{},1402:()=>{},5043:()=>{},3040:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Link:()=>V,Location:()=>M,LocationProvider:()=>D,Match:()=>J,Redirect:()=>Y,Router:()=>q,ServerLocation:()=>W,createHistory:()=>x,createMemorySource:()=>T,globalHistory:()=>w,isRedirect:()=>$,matchPath:()=>d,navigate:()=>O,redirectTo:()=>G,useLocation:()=>Q,useMatch:()=>te,useNavigate:()=>X,useParams:()=>ee});var o=n(1594),r=n.n(o),i=n(2091),a=n.n(i),s=n(3070),l=n.n(s);function componentWillMount(){var e=this.constructor.getDerivedStateFromProps(this.props,this.state);null!=e&&this.setState(e)}function componentWillReceiveProps(e){this.setState(function updater(t){var n=this.constructor.getDerivedStateFromProps(e,t);return null!=n?n:null}.bind(this))}function componentWillUpdate(e,t){try{var n=this.props,o=this.state;this.props=e,this.state=t,this.__reactInternalSnapshotFlag=!0,this.__reactInternalSnapshot=this.getSnapshotBeforeUpdate(n,o)}finally{this.props=n,this.state=o}}componentWillMount.__suppressDeprecationWarning=!0,componentWillReceiveProps.__suppressDeprecationWarning=!0,componentWillUpdate.__suppressDeprecationWarning=!0;var u=function startsWith(e,t){return e.substr(0,t.length)===t},c=function pick(e,t){for(var n=void 0,o=void 0,r=t.split("?")[0],i=y(r),s=""===i[0],l=b(e),u=0,c=l.length;ut.score?-1:e.index-t.index}))},y=function segmentize(e){return e.replace(/(^\/+|\/+$)/g,"").split("/")},_=function addQuery(e){for(var t=arguments.length,n=Array(t>1?t-1:0),o=1;o0})))&&n.length>0?"?"+n.join("&"):"")},C=["uri","path"],E=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},s=a.state,l=a.replace,u=void 0!==l&&l;if("number"==typeof t)e.history.go(t);else{s=E({},s,{key:Date.now()+""});try{r||u?e.history.replaceState(s,null,t):e.history.pushState(s,null,t)}catch(n){e.location[u?"replace":"assign"](t)}}o=S(e),r=!0;var c=new Promise((function(e){return i=e}));return n.forEach((function(e){return e({location:o,action:"PUSH"})})),c}}},T=function createMemorySource(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"/",t=e.indexOf("?"),n={pathname:t>-1?e.substr(0,t):e,search:t>-1?e.substr(t):""},o=0,r=[n],i=[null];return{get location(){return r[o]},addEventListener:function addEventListener(e,t){},removeEventListener:function removeEventListener(e,t){},history:{get entries(){return r},get index(){return o},get state(){return i[o]},pushState:function pushState(e,t,n){var a=n.split("?"),s=a[0],l=a[1],u=void 0===l?"":l;o++,r.push({pathname:s,search:u.length?"?"+u:u}),i.push(e)},replaceState:function replaceState(e,t,n){var a=n.split("?"),s=a[0],l=a[1],u=void 0===l?"":l;r[o]={pathname:s,search:u},i[o]=e},go:function go(e){var t=o+e;t<0||t>i.length-1||(o=t)}}}},P=!("undefined"==typeof window||!window.document||!window.document.createElement),w=x(function getSource(){return P?window:T()}()),O=w.navigate,R=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var j=function createNamedContext(e,t){var n=l()(t);return n.displayName=e,n},I=j("Location"),M=function Location(e){var t=e.children;return r().createElement(I.Consumer,null,(function(e){return e?t(e):r().createElement(D,null,t)}))},D=function(e){function LocationProvider(){var t,n;_classCallCheck(this,LocationProvider);for(var o=arguments.length,r=Array(o),i=0;i-1?(i=t.substring(0,o),a=t.substring(o)):i=t,r().createElement(I.Provider,{value:{location:{pathname:i,search:a,hash:""},navigate:function navigate(){throw new Error("You can't call navigate on the server.")}}},n)},A=j("Base",{baseuri:"/",basepath:"/"}),q=function Router(e){return r().createElement(A.Consumer,null,(function(t){return r().createElement(M,null,(function(n){return r().createElement(B,R({},t,n,e))}))}))},B=function(e){function RouterImpl(){return _classCallCheck(this,RouterImpl),_possibleConstructorReturn(this,e.apply(this,arguments))}return _inherits(RouterImpl,e),RouterImpl.prototype.render=function render(){var e=this.props,t=e.location,n=e.navigate,o=e.basepath,i=e.primary,a=e.children,s=(e.baseuri,e.component),l=void 0===s?"div":s,u=_objectWithoutProperties(e,["location","navigate","basepath","primary","children","baseuri","component"]),d=r().Children.toArray(a).reduce((function(e,t){var n=oe(o)(t);return e.concat(n)}),[]),f=t.pathname,m=c(d,f);if(m){var h=m.params,g=m.uri,v=m.route,b=m.route.value;o=v.default?o:v.path.replace(/\*$/,"");var y=R({},h,{uri:g,location:t,navigate:function navigate(e,t){return n(p(e,g),t)}}),_=r().cloneElement(b,y,b.props.children?r().createElement(q,{location:t,primary:i},b.props.children):void 0),C=i?N:l,E=i?R({uri:g,location:t,component:l},u):u;return r().createElement(A.Provider,{value:{baseuri:g,basepath:o}},r().createElement(C,E,_))}return null},RouterImpl}(r().PureComponent);B.defaultProps={primary:!0};var F=j("Focus"),N=function FocusHandler(e){var t=e.uri,n=e.location,o=e.component,i=_objectWithoutProperties(e,["uri","location","component"]);return r().createElement(F.Consumer,null,(function(e){return r().createElement(z,R({},i,{component:o,requestFocus:e,uri:t,location:n}))}))},L=!0,U=0,z=function(e){function FocusHandlerImpl(){var t,n;_classCallCheck(this,FocusHandlerImpl);for(var o=arguments.length,r=Array(o),i=0;i{"use strict";t.__esModule=!0;var o=n(1594),r=(_interopRequireDefault(o),_interopRequireDefault(n(2688))),i=_interopRequireDefault(n(8127));_interopRequireDefault(n(567));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var a=1073741823;t.default=function createReactContext(e,t){var n,s,l="__create-react-context-"+(0,i.default)()+"__",u=function(e){function Provider(){var t,n;_classCallCheck(this,Provider);for(var o=arguments.length,r=Array(o),i=0;i{"use strict";t.__esModule=!0;var o=_interopRequireDefault(n(1594)),r=_interopRequireDefault(n(6134));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}t.default=o.default.createContext||r.default,e.exports=t.default},4292:(e,t,n)=>{"use strict";var o=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function useFeatureLock(e){const t=elementorAppProConfig[e]??{},n=t.lock?.is_locked??!1,o=(0,a.htmlDecodeTextContent)(t.lock?.button.text),s=(0,a.replaceUtmPlaceholders)(t.lock?.button.url??"",t.utms??{});return{isLocked:n,ConnectButton:()=>r.default.createElement(i.default,{text:o,url:s})}};var r=o(n(1594)),i=o(n(8799)),a=n(40)},8799:(e,t,n)=>{"use strict";var o=n(2688),r=n(2470).__,i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=i(n(8304)),s=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(1594)),l=s,u=n(7401),c=n(40);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const ConnectButton=e=>{const t=(0,c.arrayToClassName)(["e-app-connect-button",e.className]),n=(0,s.useRef)(null);return(0,s.useEffect)((()=>{n.current&&jQuery(n.current).elementorConnect()}),[]),l.createElement(u.Button,(0,a.default)({},e,{elRef:n,className:t}))};ConnectButton.propTypes={...u.Button.propTypes,text:o.string.isRequired,url:o.string.isRequired,className:o.string},ConnectButton.defaultProps={className:"",variant:"contained",size:"sm",color:"cta",target:"_blank",rel:"noopener noreferrer",text:r("Connect & Activate","elementor-pro")};t.default=l.memo(ConnectButton)},40:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.replaceUtmPlaceholders=t.htmlDecodeTextContent=t.arrayToClassName=void 0;t.arrayToClassName=(e,t)=>e.filter((e=>"object"==typeof e?Object.entries(e)[0][1]:e)).map((e=>{const n="object"==typeof e?Object.entries(e)[0][0]:e;return t?t(n):n})).join(" ");t.htmlDecodeTextContent=e=>(new DOMParser).parseFromString(e,"text/html").documentElement.textContent;t.replaceUtmPlaceholders=(e="",t={})=>e&&t?(Object.keys(t).forEach((n=>{const o=new RegExp(`%%${n}%%`,"g");e=e.replace(o,t[n])})),e):e},9128:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ListSettingSection=ListSettingSection;var o=_interopRequireWildcard(n(1594)),r=n(2470),i=n(6956),a=_interopRequireWildcard(n(2688)),s=n(40),l=n(3101);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}const u=16;function ListSettingSection({items:e,title:t,loading:n,settings:a,onSettingChange:c,settingKey:d,disabled:p=!1,tooltip:f=!1}){const[m,h]=(0,o.useState)(!1);return o.default.createElement(i.Box,{key:d,sx:{mb:3,border:1,borderRadius:1,borderColor:"action.focus",p:2.5}},o.default.createElement(i.Stack,{spacing:2},o.default.createElement(i.Typography,{variant:"h6"},t),o.default.createElement(i.Grid,{container:!0,spacing:1,alignItems:"start"},n?o.default.createElement(i.Grid,{item:!0,xs:12,sx:{p:1,alignItems:"center",textAlign:"center"}},o.default.createElement(i.CircularProgress,{size:30})):o.default.createElement(o.default.Fragment,null,o.default.createElement(i.Grid,{key:"all",item:!0,xs:12,sx:{py:1,px:0}},o.default.createElement(l.UpgradeTooltip,{disabled:p&&a.length===e.length,tooltip:f},o.default.createElement(i.Box,{sx:{pointerEvents:"auto",...a.length===e.length&&p&&{cursor:"pointer"}}},o.default.createElement(i.FormControlLabel,{control:o.default.createElement(i.Checkbox,{color:"info",checked:a.length===e.length,indeterminate:a.length>0&&a.length!==e.length,onChange:(t,n)=>{c(n?e.map((({value:e})=>e)):[],!0)},sx:{p:0},disabled:p}),sx:{gap:1,...a.length===e.length&&p&&{cursor:"pointer"}},slotProps:{typography:{sx:{fontWeight:500,...a.length===e.length&&p&&{cursor:"pointer"}}}},label:`${(0,r.__)("All","elementor-pro")} ${t.toLowerCase()}`})))),(m?e:e.slice(0,u)).map((e=>o.default.createElement(i.Grid,{key:e.value,item:!0,xs:3,sx:{py:1,px:0}},o.default.createElement(l.UpgradeTooltip,{disabled:p&&a.includes(e.value),tooltip:f},o.default.createElement(i.Box,{sx:{pointerEvents:"auto",...a.includes(e.value)&&p&&{cursor:"pointer"}}},o.default.createElement(i.FormControlLabel,{control:o.default.createElement(i.Checkbox,{color:"info",checked:a.includes(e.value),onChange:(t,n)=>{c(n?[...a,e.value]:a.filter((t=>t!==e.value)))},sx:{p:0,...a.includes(e.value)&&p&&{cursor:"pointer"}},disabled:p}),sx:{maxWidth:"100%",gap:1,...a.includes(e.value)&&p&&{cursor:"pointer"}},slotProps:{typography:{sx:{fontWeight:400,maxWidth:"100%",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",...a.includes(e.value)&&p&&{cursor:"pointer"}}}},label:(0,s.htmlDecodeTextContent)(e.label)}))))))))),e.length>u&&o.default.createElement(i.Button,{variant:"text",color:"info",onClick:()=>h(!m)},m?(0,r.__)("Show less","elementor"):(0,r.__)("Show more","elementor")))}ListSettingSection.propTypes={title:a.string.isRequired,children:a.node,loading:a.bool,disabled:a.bool,checked:a.bool,settingKey:a.string,onSettingChange:a.func.isRequired,tooltip:a.bool,items:a.arrayOf(a.shape({label:a.string.isRequired,value:a.oneOfType([a.string,a.number])})),settings:a.arrayOf(a.oneOfType([a.string,a.number]))}},493:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.SettingSection=void 0;var i=r(n(1594)),a=n(6956),s=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(2688)),l=n(3101);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const SettingSection=({checked:e=!1,title:t,description:n,children:r,settingKey:s,onSettingChange:u,hasToggle:c=!0,disabled:d=!1,notExported:p=!1,tooltip:f=!1})=>i.default.createElement(a.Box,{key:s,sx:{mb:3,border:1,borderRadius:1,borderColor:"action.focus",p:2.5}},i.default.createElement(a.Box,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center"}},i.default.createElement(a.Stack,{spacing:1},i.default.createElement(a.Typography,{variant:"h6"},t),n&&i.default.createElement(a.Typography,{"data-testid":`${s}-description`,variant:"body1",color:"text.secondary"},n)),(()=>{if(p)return i.default.createElement(a.Typography,{"data-testid":`${s}-description`,variant:"body1",color:"text.secondary"},o("Not exported","elementor"));if(!c)return null;const t=i.default.createElement(a.Switch,{"data-testid":`${s}-switch`,checked:e,onChange:(e,t)=>u&&u(s,t),color:"info",size:"medium",sx:{alignSelf:"center",...d&&f&&{cursor:"pointer"}},disabled:d});return i.default.createElement(l.UpgradeTooltip,{disabled:d,tooltip:f},t)})()),r&&i.default.createElement(a.Box,{sx:{mt:1}},r));t.SettingSection=SettingSection,SettingSection.propTypes={title:s.string.isRequired,description:s.string,children:s.node,hasToggle:s.bool,checked:s.bool,disabled:s.bool,settingKey:s.string,onSettingChange:s.func,notExported:s.bool,tooltip:s.bool}},9460:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.SubSetting=void 0;var i=r(n(1594)),a=n(6956),s=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(2688)),l=n(3101);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const SubSetting=({label:e,settingKey:t,onSettingChange:n,checked:r=!1,disabled:s=!1,notExported:u=!1,tooltip:c=!1})=>i.default.createElement(a.Box,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center"}},i.default.createElement(a.Typography,{"data-testid":`${t}-label`,variant:"body1"},e),(()=>{if(u)return i.default.createElement(a.Typography,{"data-testid":`${t}-description`,variant:"body1",color:"text.secondary",sx:{fontWeight:400,alignSelf:"center"}},o("Not exported","elementor"));const e=i.default.createElement(a.Switch,{"data-testid":`${t}-switch`,checked:r,disabled:s,onChange:(e,o)=>n&&n(t,o),color:"info",size:"medium",sx:{alignSelf:"center",...s&&c&&{cursor:"pointer"}}});return i.default.createElement(l.UpgradeTooltip,{disabled:s,tooltip:c},e)})());t.SubSetting=SubSetting,SubSetting.propTypes={checked:s.bool,disabled:s.bool,notExported:s.bool,label:s.string.isRequired,settingKey:s.string.isRequired,onSettingChange:s.func,tooltip:s.bool}},8856:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KitContentCustomizationDialog=KitContentCustomizationDialog;var o=_interopRequireWildcard(n(1594)),r=_interopRequireWildcard(n(2688)),i=n(6956),a=n(2470),s=n(344),l=n(9128),u=n(493),c=n(9460),d=n(6919),p=n(7050),f=n(2771),m=n(6662),h=n(8551),g=n(225),v=n(5533);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}const b={LINK:"link",CLOUD:"cloud"},y=[{value:b.LINK,title:(0,a.__)("Link to media","elementor-pro"),description:(0,a.__)("Stores only the URLs. The export stays light, but files load only while the original site is online.","elementor-pro")},{value:b.CLOUD,title:(0,a.__)("Save media to the cloud","elementor-pro"),description:(0,a.__)("All images and files are stored with the template. Keeps everything intact, but the file is larger.","elementor-pro")}],transformAnalyticsData=(e,t,n,o)=>{const r=[{key:"pages",options:t},{key:"taxonomies",options:n},{key:"customPostTypes",options:o}],i={};for(const[t,n]of Object.entries(e))i[t]=(0,v.transformValueForAnalytics)(t,n,r);return i};function KitContentCustomizationDialog({open:e,handleClose:t,handleSaveChanges:n,data:r,isImport:v,isOldExport:_,isOldElementorVersion:C,isCloudKitsEligible:E=!1,showMediaFormatValidation:S=!1}){const x=r.includes.includes("content"),{isLoading:T,pageOptions:P,isLoaded:w}=(0,p.useKitCustomizationPages)({open:e,data:r}),{isLoading:O,taxonomyOptions:R,isLoaded:j}=(0,f.useKitCustomizationTaxonomies)({open:e,data:r}),{customPostTypes:I}=(0,m.useKitCustomizationCustomPostTypes)({data:r}),M=(0,o.useRef)(null),D=(0,o.useRef)(null),[W,A]=(0,o.useState)((()=>r.customization.content?r.customization.content:{pages:[],menus:x,taxonomies:[],customPostTypes:[],mediaFormat:b.LINK}));(0,o.useEffect)((()=>{e&&!r.includes.includes("content")&&A({pages:[],menus:!1,taxonomies:[],customPostTypes:[],mediaFormat:b.LINK})}),[e,r.includes]),(0,o.useEffect)((()=>{e&&r.includes.includes("content")&&A((e=>({...e,pages:w||v?r.customization.content?.pages||P.map((({value:e})=>e)):e.pages})))}),[e,r.includes,r.customization.content?.pages,w,v,P]),(0,o.useEffect)((()=>{e&&r.includes.includes("content")&&A((e=>({...e,taxonomies:j||v?r.customization.content?.taxonomies||R.map((({value:e})=>e)):e.taxonomies})))}),[e,r.includes,r.customization.content?.taxonomies,j,v,R]),(0,o.useEffect)((()=>{e&&r.includes.includes("content")&&A((e=>({...e,customPostTypes:I?r.customization.content?.customPostTypes||I.map((({value:e})=>e)):e.customPostTypes})))}),[e,r.includes,r.customization.content?.customPostTypes,I]),(0,o.useEffect)((()=>{e&&r.includes.includes("content")&&A((e=>({...e,menus:v?r.customization.content?.menus||Object.keys(r?.uploadedData?.manifest["wp-content"]?.nav_menu_item||{}).length>0:r.customization.content?.menus??x})))}),[e,r.includes,r.customization.content?.menus,r.uploadedData?.manifest,v]),(0,o.useEffect)((()=>{e&&r.includes.includes("content")&&A((e=>({...e,mediaFormat:r.customization.content?.mediaFormat||b.LINK})))}),[e,r.includes,r.customization.content?.mediaFormat]),(0,o.useEffect)((()=>{e&&window.elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit)}),[e]),(0,o.useEffect)((()=>{S&&setTimeout((()=>{const e=M.current||D.current;e&&e.scrollIntoView({behavior:"smooth",block:"center"})}))}),[S]);const handleSettingsChange=(e,t)=>{A((n=>({...n,[e]:t})))};return o.default.createElement(s.KitCustomizationDialog,{open:e,title:(0,a.__)("Edit content","elementor-pro"),handleClose:t,handleSaveChanges:()=>{const e=W.pages.length>0||W.menus||W.customPostTypes.length>0||W.taxonomies.length>0||W.mediaFormat!==b.LINK,t=transformAnalyticsData(W,P,R,I);n("content",W,e,t)}},o.default.createElement(i.Stack,{sx:{position:"relative"},gap:2},C&&o.default.createElement(g.UpgradeVersionBanner,null),o.default.createElement(i.Stack,null,v&&_?null:v&&!(()=>{const e=r?.uploadedData?.manifest?.content,t=r?.uploadedData?.manifest?.["wp-content"],n=Object.keys(e?.page||{})?.length,o=Object.keys(t?.page||{})?.length;return Boolean(n||o)})()?o.default.createElement(u.SettingSection,{title:(0,a.__)("Site pages","elementor-pro"),settingKey:"pages",notExported:!0}):o.default.createElement(l.ListSettingSection,{settingKey:"pages",title:(0,a.__)("Site pages","elementor-pro"),onSettingChange:e=>{handleSettingsChange("pages",e)},settings:W.pages,items:P,loading:T,disabled:!(0,h.isHighTier)(),tooltip:!(0,h.isHighTier)()}),!v||v&&I?.length>0?o.default.createElement(l.ListSettingSection,{settingKey:"customPostTypes",title:(0,a.__)("Custom post types","elementor-pro"),onSettingChange:e=>{handleSettingsChange("customPostTypes",e)},settings:W.customPostTypes,items:I,disabled:v&&void 0===r?.uploadedData?.manifest["custom-post-type-title"]||!(0,h.isHighTier)(),tooltip:!(0,h.isHighTier)()}):o.default.createElement(u.SettingSection,{title:(0,a.__)("Custom post types","elementor-pro"),settingKey:"customPostTypes",notExported:!0}),v?o.default.createElement(u.SettingSection,{title:(0,a.__)("Media format","elementor-pro"),settingKey:"mediaFormat",hasToggle:!1},o.default.createElement(i.Alert,{icon:o.default.createElement(i.SvgIcon,{color:"info",viewBox:"0 0 24 24"},o.default.createElement("path",{d:"M11.8623 14.7549C12.3665 14.8061 12.7598 15.2322 12.7598 15.75C12.7598 16.2678 12.3665 16.6939 11.8623 16.7451L11.7598 16.75H11.75C11.1977 16.75 10.75 16.3023 10.75 15.75C10.75 15.1977 11.1977 14.75 11.75 14.75H11.7598L11.8623 14.7549Z",fill:"currentColor"}),o.default.createElement("path",{d:"M11.75 7C12.1642 7 12.5 7.33579 12.5 7.75V12.75C12.5 13.1642 12.1642 13.5 11.75 13.5C11.3358 13.5 11 13.1642 11 12.75V7.75C11 7.33579 11.3358 7 11.75 7Z",fill:"currentColor"}),o.default.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11.75 2C17.1348 2 21.5 6.36522 21.5 11.75C21.5 17.1348 17.1348 21.5 11.75 21.5C6.36522 21.5 2 17.1348 2 11.75C2 6.36522 6.36522 2 11.75 2ZM11.75 3.5C7.19365 3.5 3.5 7.19365 3.5 11.75C3.5 16.3063 7.19365 20 11.75 20C16.3063 20 20 16.3063 20 11.75C20 7.19365 16.3063 3.5 11.75 3.5Z",fill:"currentColor"})),sx:{backgroundColor:"transparent",p:0}},o.default.createElement(i.Typography,{variant:"body2",color:"text.primary"},o.default.createElement("strong",null,(0,a.__)("Note:","elementor-pro"))," ",(0,a.__)("The media will be uploaded automatically, just as it was saved during export","elementor-pro")))):v||E?o.default.createElement(u.SettingSection,{ref:D,description:(0,a.__)("Select how do you want to save & export the media files.","elementor-pro"),title:(0,a.__)("Media format","elementor-pro"),settingKey:"mediaFormat",hasToggle:!1,disabled:!(0,h.isHighTier)(),tooltip:!(0,h.isHighTier)()},o.default.createElement(i.Box,{sx:{pt:2.5}},o.default.createElement(i.FormControl,{component:"fieldset",disabled:!(0,h.isHighTier)(),sx:{width:"100%"}},o.default.createElement(i.RadioGroup,{value:W.mediaFormat,onChange:e=>{handleSettingsChange("mediaFormat",e.target.value)},sx:{width:"100%"}},y.map(((e,t)=>o.default.createElement(i.Box,{key:e.value,sx:{border:1,borderColor:W.mediaFormat===e.value?"info.light":"divider",borderRadius:2,p:1,mb:t0||I?.find((e=>e.value.includes("nav_menu"))))||!(0,h.isHighTier)(),title:(0,a.__)("Menus","elementor-pro"),settingKey:"menus",tooltip:!(0,h.isHighTier)(),onSettingChange:(e,t)=>{handleSettingsChange(e,t)}}),v&&_?null:o.default.createElement(u.SettingSection,{description:(0,a.__)("Group your content by type, topic, or any structure you choose.","elementor-pro"),title:(0,a.__)("Taxonomies","elementor-pro"),settingKey:"taxonomies",notExported:v&&!(v&&R?.length>0),hasToggle:!1},O?o.default.createElement(i.Box,{sx:{p:1,alignItems:"center",textAlign:"center"}},o.default.createElement(i.CircularProgress,{size:30})):R.map((e=>o.default.createElement(c.SubSetting,{key:e.value,label:e.label,settingKey:"taxonomies",checked:W.taxonomies.includes(e.value),disabled:!(0,h.isHighTier)(),tooltip:!(0,h.isHighTier)(),onSettingChange:(t,n)=>{A((t=>{const o=n?[...t.taxonomies,e.value]:t.taxonomies.filter((t=>t!==e.value));return{...t,taxonomies:o}}))}}))))),o.default.createElement(d.UpgradeNoticeBanner,null)))}KitContentCustomizationDialog.propTypes={open:r.bool.isRequired,isImport:r.bool,isOldExport:r.bool,isOldElementorVersion:r.bool,handleClose:r.func.isRequired,handleSaveChanges:r.func.isRequired,data:r.object.isRequired,isCloudKitsEligible:r.bool,showMediaFormatValidation:r.bool}},344:(e,t,n)=>{"use strict";var o=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.KitCustomizationDialog=KitCustomizationDialog;var r=o(n(1594)),i=n(6956),a=n(2470),s=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function KitCustomizationDialog({open:e,title:t,handleClose:n,handleSaveChanges:o,children:s,saveDisabled:l=!1}){return r.default.createElement(i.Dialog,{open:e,onClose:n,maxWidth:"md",fullWidth:!0},r.default.createElement(i.DialogHeader,{onClose:n},r.default.createElement(i.DialogTitle,null,t)),r.default.createElement(i.DialogContent,{dividers:!0,sx:{pt:3,px:3,pb:0}},s),r.default.createElement(i.DialogActions,null,r.default.createElement(i.Button,{onClick:n,color:"secondary"},(0,a.__)("Cancel","elementor")),r.default.createElement(i.Button,{disabled:l,onClick:()=>{o(),n()},variant:"contained",color:"primary"},(0,a.__)("Save changes","elementor"))))}KitCustomizationDialog.propTypes={open:s.bool.isRequired,handleClose:s.func.isRequired,handleSaveChanges:s.func.isRequired,children:s.node.isRequired,title:s.string.isRequired,saveDisabled:s.bool}},8706:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KitSettingsCustomizationDialog=KitSettingsCustomizationDialog;var o=_interopRequireWildcard(n(1594)),r=n(6956),i=n(2470),a=_interopRequireWildcard(n(2688)),s=n(493),l=n(9460),u=n(344),c=n(6919),d=n(8551),p=n(225),f=n(5533);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}const transformAnalyticsData=e=>{const t={};for(const[n,o]of Object.entries(e))t[n]=(0,f.transformValueForAnalytics)(n,o,[]);return t};function KitSettingsCustomizationDialog({open:e,handleClose:t,handleSaveChanges:n,data:a,isImport:f,isOldExport:m,isOldElementorVersion:h}){const g=(0,o.useCallback)((e=>{if(!a.includes.includes("settings"))return{theme:e,globalColors:e,globalFonts:e,themeStyleSettings:e,generalSettings:e,experiments:e,customFonts:e,customIcons:e,customCode:e};if(f){const t=a?.uploadedData?.manifest?.["site-settings"];let n=!1;return n=m?!!e&&a?.uploadedData?.manifest?.theme:t?.theme??e,{theme:n,globalColors:!!m||(t?.globalColors??e),globalFonts:!!m||(t?.globalFonts??e),themeStyleSettings:!!m||(t?.themeStyleSettings??e),generalSettings:!!m||(t?.generalSettings??e),experiments:!!m||(t?.experiments??e),customFonts:!!m||(t?.customFonts??e),customIcons:!!m||(t?.customIcons??e),customCode:!!m||(t?.customCode??e)}}const t=a?.customization?.settings;return{theme:t?.theme??e,globalColors:t?.globalColors??e,globalFonts:t?.globalFonts??e,themeStyleSettings:t?.themeStyleSettings??e,generalSettings:t?.generalSettings??e,experiments:t?.experiments??e,customFonts:t?.customFonts??e,customIcons:t?.customIcons??e,customCode:t?.customCode??e}}),[a.includes,a?.uploadedData?.manifest,a?.customization?.settings,f,m]),v=a.includes.includes("settings"),[b,y]=(0,o.useState)((()=>a.customization.settings?a.customization.settings:g(v)));(0,o.useEffect)((()=>{if(e)if(a.customization.settings)y(a.customization.settings);else{const e=g(v);y(e)}}),[e,a.customization.settings,a?.uploadedData,v,g]),(0,o.useEffect)((()=>{e&&window.elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit)}),[e]);const handleToggleChange=e=>{y((t=>({...t,[e]:!t[e]})))};return o.default.createElement(u.KitCustomizationDialog,{open:e,title:(0,i.__)("Edit settings & configurations","elementor"),handleClose:t,handleSaveChanges:()=>{const e=b.theme||b.globalColors||b.globalFonts||b.themeStyleSettings||b.generalSettings||b.experiments||b.customFonts||b.customIcons||b.customCode,t=transformAnalyticsData(b);n("settings",b,e,t)}},o.default.createElement(r.Stack,{sx:{position:"relative"},gap:2},h&&o.default.createElement(p.UpgradeVersionBanner,null),o.default.createElement(r.Stack,null,o.default.createElement(s.SettingSection,{checked:b.theme,title:(0,i.__)("Theme","elementor"),description:(0,i.__)("Only public WordPress themes are supported","elementor"),settingKey:"theme",onSettingChange:handleToggleChange,notExported:f&&!a?.uploadedData?.manifest.theme}),!m&&o.default.createElement(o.default.Fragment,null,o.default.createElement(s.SettingSection,{title:(0,i.__)("Site settings","elementor"),hasToggle:!1},o.default.createElement(r.Stack,null,o.default.createElement(l.SubSetting,{label:(0,i.__)("Global colors","elementor"),settingKey:"globalColors",onSettingChange:handleToggleChange,checked:b.globalColors,disabled:f&&!a?.uploadedData?.manifest?.["site-settings"]?.globalColors||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(l.SubSetting,{label:(0,i.__)("Global fonts","elementor"),settingKey:"globalFonts",onSettingChange:handleToggleChange,checked:b.globalFonts,disabled:f&&!a?.uploadedData?.manifest?.["site-settings"]?.globalFonts||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(l.SubSetting,{label:(0,i.__)("Theme style settings","elementor"),settingKey:"themeStyleSettings",onSettingChange:handleToggleChange,checked:b.themeStyleSettings,disabled:f&&!a?.uploadedData?.manifest?.["site-settings"]?.themeStyleSettings||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}))),o.default.createElement(s.SettingSection,{checked:b.generalSettings,title:(0,i.__)("Settings","elementor"),description:(0,i.__)("Include site identity, background, layout, Lightbox, page transitions, and custom CSS","elementor"),settingKey:"generalSettings",onSettingChange:handleToggleChange,disabled:f&&!a?.uploadedData?.manifest?.["site-settings"]?.generalSettings||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(s.SettingSection,{checked:b.experiments,title:(0,i.__)("Experiments","elementor"),description:(0,i.__)("This will apply all experiments that are still active during import","elementor"),settingKey:"experiments",onSettingChange:handleToggleChange,disabled:f&&!a?.uploadedData?.manifest?.experiments||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(s.SettingSection,{title:(0,i.__)("Custom files","elementor"),hasToggle:!1},o.default.createElement(r.Stack,null,o.default.createElement(l.SubSetting,{label:(0,i.__)("Custom fonts","elementor"),settingKey:"customFonts",onSettingChange:handleToggleChange,checked:b.customFonts,disabled:f&&!a?.uploadedData?.manifest?.["custom-fonts"]||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(l.SubSetting,{label:(0,i.__)("Custom icons","elementor"),settingKey:"customIcons",onSettingChange:handleToggleChange,checked:b.customIcons,disabled:f&&!a?.uploadedData?.manifest?.["custom-icons"]||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}),o.default.createElement(l.SubSetting,{label:(0,i.__)("Custom code","elementor"),settingKey:"customCode",onSettingChange:handleToggleChange,checked:b.customCode,disabled:f&&!a?.uploadedData?.manifest?.["custom-code"]||!(0,d.isHighTier)(),tooltip:!(0,d.isHighTier)()}))))),o.default.createElement(c.UpgradeNoticeBanner,null)))}KitSettingsCustomizationDialog.propTypes={open:a.bool.isRequired,isImport:a.bool,isOldExport:a.bool,isOldElementorVersion:a.bool,handleClose:a.func.isRequired,handleSaveChanges:a.func.isRequired,data:a.object.isRequired}},7450:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KitTemplatesCustomizationDialog=KitTemplatesCustomizationDialog,t.hasTemplatesForExportGroup=void 0;var o=_interopRequireWildcard(n(1594)),r=n(6956),i=n(2470),a=_interopRequireWildcard(n(2688)),s=n(493),l=n(344),u=n(6919),c=n(8551),d=n(4920),p=n(225),f=n(5533);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}const transformAnalyticsData=e=>{const t={};for(const[n,o]of Object.entries(e))t[n]=(0,f.transformValueForAnalytics)(n,o,[]);return t},hasTemplatesForExportGroup=(e,t)=>{if(!t?.templates)return!1;const n=elementorAppConfig?.["import-export-customization"]?.exportGroups||{};return Object.values(t.templates).some((t=>{if(!t||"object"!=typeof t||!t.doc_type)return!1;return n[t.doc_type]===e}))};function KitTemplatesCustomizationDialog({open:e,handleClose:t,handleSaveChanges:n,data:a,isImport:f,isOldExport:m,isOldElementorVersion:h}){const g=a.includes.includes("templates"),v=(0,o.useCallback)((e=>a.includes.includes("templates")?f?{siteTemplates:{enabled:!(!f||!m)||(hasTemplatesForExportGroup("site-templates",a?.uploadedData?.manifest)??e)},themeBuilder:{enabled:!(!f||!m)||(hasTemplatesForExportGroup("theme-builder",a?.uploadedData?.manifest)??e)},globalWidgets:{enabled:!(!f||!m)||(hasTemplatesForExportGroup("global-widget",a?.uploadedData?.manifest)??e)}}:{siteTemplates:{enabled:a?.customization?.templates?.siteTemplates?.enabled??e},themeBuilder:{enabled:a?.customization?.templates?.themeBuilder?.enabled??e},globalWidgets:{enabled:a?.customization?.templates?.globalWidgets?.enabled??e}}:{siteTemplates:{enabled:e},themeBuilder:{enabled:e},globalWidgets:{enabled:e}}),[a.includes,a?.uploadedData?.manifest,a?.customization?.templates,f,m]),[b,y]=(0,o.useState)({});(0,o.useEffect)((()=>{if(e)if(a.customization.templates)y(a.customization.templates);else{const e=v(g);y(e)}}),[e,a.customization.templates,a?.uploadedData,g,v]),(0,o.useEffect)((()=>{e&&elementorModules?.appsEventTracking?.AppsEventTracking?.sendPageViewsWebsiteTemplates(elementorCommon.eventsManager.config.secondaryLocations.kitLibrary.kitExportCustomizationEdit)}),[e]);const handleToggleChange=(e,t)=>{y((n=>({...n,[e]:{...n[e],enabled:t}})))};return o.default.createElement(l.KitCustomizationDialog,{open:e,title:(0,i.__)("Edit templates","elementor"),handleClose:t,handleSaveChanges:()=>{const e=b.siteTemplates?.enabled||b.themeBuilder?.enabled||b.globalWidgets?.enabled,t=transformAnalyticsData(b);n("templates",b,e,t)},minHeight:"auto"},o.default.createElement(r.Stack,{sx:{position:"relative"},gap:2},h&&o.default.createElement(p.UpgradeVersionBanner,null),o.default.createElement(r.Stack,null,!m&&o.default.createElement(s.SettingSection,{checked:b.siteTemplates?.enabled||!1,title:(0,i.__)("Site Templates","elementor"),settingKey:"siteTemplates",onSettingChange:handleToggleChange,disabled:!(0,c.isHighTier)()||f&&!hasTemplatesForExportGroup("site-templates",a?.uploadedData?.manifest),tooltip:!(0,c.isHighTier)()}),o.default.createElement(d.ThemeBuilderCustomization,{state:b.themeBuilder,settingKey:"themeBuilder",onStateChange:(e,t,n=!1)=>{y((o=>n?{...o,[e]:{...o[e],...t}}:{...o,[e]:t}))},data:a,disabled:!(0,c.isHighTier)()||f&&!hasTemplatesForExportGroup("theme-builder",a?.uploadedData?.manifest),tooltip:!(0,c.isHighTier)()}),!m&&o.default.createElement(s.SettingSection,{checked:b.globalWidgets?.enabled||!1,title:"Global Widgets",settingKey:"globalWidgets",onSettingChange:handleToggleChange,disabled:!(0,c.isHighTier)()||f&&!hasTemplatesForExportGroup("global-widget",a?.uploadedData?.manifest),tooltip:!(0,c.isHighTier)()})),o.default.createElement(u.UpgradeNoticeBanner,null)))}t.hasTemplatesForExportGroup=hasTemplatesForExportGroup,KitTemplatesCustomizationDialog.propTypes={open:a.bool.isRequired,isImport:a.bool,isOldExport:a.bool,isOldElementorVersion:a.bool,handleClose:a.func.isRequired,handleSaveChanges:a.func.isRequired,data:a.object.isRequired}},4920:(e,t,n)=>{"use strict";var o=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.ThemeBuilderCustomization=ThemeBuilderCustomization;var r=_interopRequireWildcard(n(1594)),i=o(n(8304)),a=n(6956),s=n(2470),l=_interopRequireWildcard(n(2688)),u=n(3101);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}const ExternalLinkIcon=e=>r.default.createElement(a.SvgIcon,(0,i.default)({viewBox:"0 0 18 18",sx:{fontSize:16,color:"info.light"}},e),r.default.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11 1C11 0.585786 11.3358 0.25 11.75 0.25H16.75C17.1642 0.25 17.5 0.585786 17.5 1V6C17.5 6.41421 17.1642 6.75 16.75 6.75C16.3358 6.75 16 6.41421 16 6V2.81066L7.28033 11.5303C6.98744 11.8232 6.51256 11.8232 6.21967 11.5303C5.92678 11.2374 5.92678 10.7626 6.21967 10.4697L14.9393 1.75H11.75C11.3358 1.75 11 1.41421 11 1ZM0.805456 4.05546C1.32118 3.53973 2.02065 3.25 2.75 3.25H7.75C8.16421 3.25 8.5 3.58579 8.5 4C8.5 4.41421 8.16421 4.75 7.75 4.75H2.75C2.41848 4.75 2.10054 4.8817 1.86612 5.11612C1.6317 5.35054 1.5 5.66848 1.5 6V15C1.5 15.3315 1.6317 15.6495 1.86612 15.8839C2.10054 16.1183 2.41848 16.25 2.75 16.25H11.75C12.0815 16.25 12.3995 16.1183 12.6339 15.8839C12.8683 15.6495 13 15.3315 13 15V10C13 9.58579 13.3358 9.25 13.75 9.25C14.1642 9.25 14.5 9.58579 14.5 10V15C14.5 15.7293 14.2103 16.4288 13.6945 16.9445C13.1788 17.4603 12.4793 17.75 11.75 17.75H2.75C2.02065 17.75 1.32118 17.4603 0.805456 16.9445C0.289731 16.4288 0 15.7293 0 15V6C0 5.27065 0.289731 4.57118 0.805456 4.05546Z",fill:"currentColor"}));function ThemeBuilderCustomization({state:e,settingKey:t,onStateChange:n,data:o,disabled:i,tooltip:l=!1}){const c=o.hasOwnProperty("uploadedData"),[d,p]=(0,r.useState)([]),[f,m]=(0,r.useState)(!1);(0,r.useEffect)((()=>{e?.enabled&&c?loadConflicts():(p([]),m(!1))}),[e?.enabled,c,o]);const loadConflicts=async()=>{m(!0);try{const r=(o?.uploadedData?.conflicts?Object.entries(o.uploadedData.conflicts):[]).map((([e,t])=>{const n=o?.uploadedData?.manifest?.templates?.[e],r=t[0];return{template_id:r.template_id,template_name:r.template_title,edit_url:r.edit_url,imported_template_id:parseInt(e),imported_template_name:n?.title||"Unknown Template",location:n?.location||"",location_label:getTemplateTypeLabel(e)}}));if(p(r),!e?.overrideConditions||0===e.overrideConditions.length){const o=r.map((e=>e.imported_template_id));n(t,{...e,overrideConditions:o})}}catch(e){p([])}finally{m(!1)}},getTemplateTypeLabel=e=>{const t=o?.uploadedData?.manifest?.templates?.[e];if(!t)return"Unknown Template";const n=t.doc_type,r=elementorAppConfig?.["import-export-customization"]?.summaryTitles?.templates?.[n];return r?.single||n},handleConflictChoice=(o,r,i)=>{const a=e?.overrideConditions||[];let s;s="imported"===r?a.includes(i)?a:[...a,i]:a.filter((e=>e!==i)),n(t,{...e,overrideConditions:s})},getConflictChoice=t=>(e?.overrideConditions||[]).includes(t)?"imported":"current";return r.default.createElement(a.Box,{sx:{mb:3,border:1,borderRadius:1,borderColor:"action.focus",p:2.5}},r.default.createElement(a.Box,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center"}},r.default.createElement(a.Stack,{spacing:1},r.default.createElement(a.Typography,{variant:"h6"},(0,s.__)("Theme builder","elementor-pro")),r.default.createElement(a.Link,{href:elementorAppConfig.base_url+"#/site-editor/templates",target:"_blank",rel:"noopener noreferrer",color:"info.light",underline:"hover",sx:{display:"inline-flex",alignItems:"center",gap:.5}},(0,s.__)("Check your themes builder","elementor-pro"),r.default.createElement(ExternalLinkIcon,null))),r.default.createElement(u.UpgradeTooltip,{disabled:i,tooltip:l},r.default.createElement(a.Switch,{"data-testid":`${t}-switch`,checked:e?.enabled||!1,disabled:i,onChange:()=>{const o={enabled:!e?.enabled};c&&(o.overrideConditions=e?.enabled?[]:e?.overrideConditions||[]),n(t,o)},color:"info",size:"medium",sx:{alignSelf:"center",...i&&l&&{cursor:"pointer"}}}))),e?.enabled&&c&&0r.default.createElement(a.TableRow,{key:t},r.default.createElement(a.TableCell,null,r.default.createElement(a.Typography,{variant:"body2",fontWeight:"medium"},getTemplateTypeLabel(e.imported_template_id))),r.default.createElement(a.TableCell,null,r.default.createElement(a.FormControlLabel,{control:r.default.createElement(a.Radio,{checked:"current"===getConflictChoice(e.imported_template_id,e.location),onChange:()=>handleConflictChoice(e.location,"current",e.imported_template_id),size:"small"}),label:e.template_name})),r.default.createElement(a.TableCell,null,r.default.createElement(a.FormControlLabel,{control:r.default.createElement(a.Radio,{checked:"imported"===getConflictChoice(e.imported_template_id,e.location),onChange:()=>handleConflictChoice(e.location,"imported",e.imported_template_id),size:"small"}),label:e.imported_template_name})))))))))))}ThemeBuilderCustomization.propTypes={state:l.object.isRequired,settingKey:l.string.isRequired,onStateChange:l.func.isRequired,data:l.object.isRequired,disabled:l.bool,tooltip:l.bool}},6919:(e,t,n)=>{"use strict";var o=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.UpgradeNoticeBanner=function UpgradeNoticeBanner(){if((0,s.isHighTier)())return null;return r.default.createElement(i.Paper,{sx:{position:"sticky",bottom:0,marginLeft:-3,marginRight:-3,zIndex:1e3,py:2,px:3}},r.default.createElement(i.Paper,{elevation:0,color:"promotion",sx:{borderRadius:1,p:2}},r.default.createElement(i.Box,{sx:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:2}},r.default.createElement(i.Box,{sx:{flex:1,minWidth:0}},r.default.createElement(i.Typography,{variant:"body2",color:"text.secondary"},(0,a.__)("Take control of your workflow. The Expert plan lets you decide exactly what's included in your export/import kits, from themes to experiments so nothing gets left behind.","elementor"))),r.default.createElement(i.Button,{variant:"outlined",color:"promotion",onClick:()=>window.open("https://go.elementor.com/go-pro-import-export","_blank"),startIcon:r.default.createElement("span",{className:"eicon-upgrade-crown"}),sx:{flexShrink:0,whiteSpace:"nowrap"}},(0,a.__)("Check Expert plan","elementor")))))};var r=o(n(1594)),i=n(6956),a=n(2470),s=n(8551)},3101:(e,t,n)=>{"use strict";var o=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.UpgradeTooltip=void 0;var r=o(n(1594)),i=o(n(8304)),a=n(6956),s=n(2470),l=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const UpgradeTooltip=({children:e,disabled:t=!1,tooltip:n=!1,...o})=>t&&n?r.default.createElement(a.Tooltip,(0,i.default)({title:(0,s.__)("Upgrade your plan to choose which elements to adjust.","elementor"),placement:"top",arrow:!0,componentsProps:{tooltip:{sx:{maxWidth:200,fontSize:"12px",fontWeight:500,lineHeight:1.4,textAlign:"center",backgroundColor:"background.paper",color:"text.secondary",padding:1.5,boxShadow:"0 4px 20px rgba(0, 0, 0, 0.15)"}},arrow:{sx:{fontSize:"1.2rem",color:"background.paper",filter:"drop-shadow(0 2px 8px rgba(0, 0, 0, 0.15))","&::before":{backgroundColor:"background.paper"}}}}},o),r.default.createElement(a.Box,{component:"span"},e)):e;t.UpgradeTooltip=UpgradeTooltip,UpgradeTooltip.propTypes={children:l.node.isRequired,disabled:l.bool,tooltip:l.bool}},225:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.UpgradeVersionBanner=function UpgradeVersionBanner(){return i.default.createElement(a.Paper,{color:"info",elevation:0,variant:"elevation"},i.default.createElement(a.Stack,{direction:"row",sx:{alignItems:"center",justifyContent:"space-between",gap:"5px",py:1.5,px:2.5}},i.default.createElement(a.Stack,{direction:"row",sx:{alignItems:"center",gap:"5px"}},i.default.createElement(a.SvgIcon,{viewBox:"0 0 22 22",sx:{fontSize:16,color:"info.light"}},i.default.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M4.58268 4.35352C4.5219 4.35352 4.46361 4.37766 4.42064 4.42064C4.37766 4.46361 4.35352 4.5219 4.35352 4.58268V6.64518H6.64518V4.35352H4.58268ZM4.58268 2.97852C4.15723 2.97852 3.7492 3.14753 3.44837 3.44837C3.14753 3.7492 2.97852 4.15723 2.97852 4.58268V17.416C2.97852 17.8415 3.14753 18.2495 3.44837 18.5503C3.74921 18.8512 4.15723 19.0202 4.58268 19.0202H17.416C17.8415 19.0202 18.2495 18.8512 18.5503 18.5503C18.8512 18.2495 19.0202 17.8415 19.0202 17.416V4.58268C19.0202 4.15723 18.8512 3.74921 18.5503 3.44837C18.2495 3.14753 17.8415 2.97852 17.416 2.97852H4.58268ZM8.02018 4.35352V6.64518H17.6452V4.58268C17.6452 4.5219 17.621 4.46361 17.5781 4.42064C17.5351 4.37766 17.4768 4.35352 17.416 4.35352H8.02018ZM17.6452 8.02018H4.35352V17.416C4.35352 17.4768 4.37766 17.5351 4.42064 17.5781C4.46361 17.621 4.5219 17.6452 4.58268 17.6452H17.416C17.4768 17.6452 17.5351 17.621 17.5781 17.5781C17.621 17.5351 17.6452 17.4768 17.6452 17.416V8.02018Z",fill:"currentColor"})),i.default.createElement(a.Typography,{variant:"body2"},o("You’re using an older Elementor version. Update for full customization.","elementor"))),i.default.createElement(a.Button,{variant:"outlined",onClick:()=>window.open(elementorAppConfig["import-export-customization"]?.upgradeVersionUrl,"_blank"),color:"info"},o("Update version","elementor"))))};var i=r(n(1594)),a=n(6956)},8267:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useCustomPostTypes=function useCustomPostTypes({include:e=[]}={}){const[t,n]=(0,o.useState)([]);return(0,o.useEffect)((()=>{const t=Object.assign({},elementorAppConfig["import-export-customization"]?.summaryTitles?.content?.customPostTypes||{});e.length&&Object.entries(elementorAppConfig["import-export-customization"]?.summaryTitles?.content||{}).forEach((([n,o])=>{e.includes(n)&&(t[n]=o)})),Object.keys(t).length&&n(Object.entries(t).map((([e,t])=>({value:e,label:t.single}))))}),[]),{customPostTypes:t}};var o=n(1594)},6662:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useKitCustomizationCustomPostTypes=function useKitCustomizationCustomPostTypes({data:e}){const t=e?.hasOwnProperty("uploadedData"),{customPostTypes:n}=(0,r.useCustomPostTypes)({include:["post"]});return{customPostTypes:(0,o.useMemo)((()=>{if(!t)return n;const o=Object.values(e?.uploadedData?.manifest?.["custom-post-type-title"]||{}).map((e=>({value:e.name,label:e.label})));o.some((e=>"post"===e.value))||o.push({value:"post",label:"Post"});const r=e?.uploadedData?.manifest?.["wp-content"]||{},i=e?.uploadedData?.manifest?.content||{};return o.filter((e=>{const t=e.value,n=r[t],o=n&&"object"==typeof n&&Object.keys(n).length>0,a=i[t],s=a&&"object"==typeof a&&Object.keys(a).length>0;return o||s}))}),[t,e?.uploadedData,n])}},n(5724);var o=n(1594),r=n(8267)},7050:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useKitCustomizationPages=function useKitCustomizationPages({data:e,open:t}){const n=e?.hasOwnProperty("uploadedData"),{isLoading:i,pageOptions:a,isLoaded:s}=(0,r.usePages)({skipLoading:n||!t}),l=(0,o.useMemo)((()=>{if(!n)return a;return[...Object.entries(e?.uploadedData?.manifest?.content?.page||{}).map((([e,t])=>({value:e,label:t.title}))),...Object.entries(e?.uploadedData?.manifest?.["wp-content"]?.page||{}).map((([e,t])=>({value:e,label:t.title})))]}),[a,n,e?.uploadedData]);return{isLoading:i,pageOptions:l,isLoaded:s}};var o=n(1594),r=n(1699)},2771:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useKitCustomizationTaxonomies=function useKitCustomizationTaxonomies({data:e,open:t}){const n=e?.hasOwnProperty("uploadedData"),{isLoading:i,taxonomyOptions:a,isLoaded:s}=(0,r.useTaxonomies)({skipLoading:n||!t,exclude:["nav_menu"]});return{taxonomyOptions:(0,o.useMemo)((()=>{if(!n)return a;const t={};return Object.values(e?.uploadedData?.manifest?.taxonomies||{}).forEach((e=>{e.forEach((e=>{const n="string"==typeof e?{name:e,label:e.split("_").join(" ")}:e;t[n.name]||(t[n.name]={value:n.name,label:n.label})}))})),Object.values(t)}),[e?.uploadedData,n,a]),isLoading:i,isLoaded:s}};var o=n(1594),r=n(8372)},1699:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.usePages=function usePages({skipLoading:e=!1}={}){const[t,n]=(0,o.useState)([]),[r,i]=(0,o.useState)(!1),[a,s]=(0,o.useState)(null),[l,u]=(0,o.useState)(!0),c=(0,o.useRef)(null),d=(0,o.useCallback)((async()=>{if(!c.current)try{i(!0),s(null),n([]),u(!0);let e=1,t=[];for(;l||1===e;){const n=new URL(elementorCommon.config.urls.rest,window.location.origin),o="index.php"===n.pathname.replace(/\//g,"");n.pathname=o?n.pathname:`${n.pathname}wp/v2/pages`,o&&n.searchParams.set("rest_route","/wp/v2/pages"),n.searchParams.append("page",1),n.searchParams.append("per_page",100),n.searchParams.append("_embed","");const r=await fetch(n.toString(),{method:"GET",headers:{"Content-Type":"application/json","X-WP-Nonce":window.wpApiSettings?.nonce||""}});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);const i=await r.json(),a=parseInt(r.headers.get("X-WP-TotalPages")||"1");if(t=[...t,...i],a<=e){u(!1);break}e++}n(t),c.current=!0}catch(e){s(e.message)}finally{i(!1)}}),[l]),p=(0,o.useCallback)((()=>{d()}),[d]),f=(0,o.useMemo)((()=>t.map((e=>({value:e.id,label:e.title.rendered})))),[t]);return(0,o.useEffect)((()=>{e||d()}),[e]),{pages:t,isLoading:r,error:a,refreshPages:p,pageOptions:f,isLoaded:c.current}};var o=n(1594)},8372:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useTaxonomies=function useTaxonomies({skipLoading:e=!1,exclude:t=[]}={}){const[n,r]=(0,o.useState)([]),[i,a]=(0,o.useState)(!1),[s,l]=(0,o.useState)(null),u=(0,o.useRef)(null),c=(0,o.useCallback)((async()=>{if(!u.current)try{a(!0),l(null);const e=await fetchTaxonomies();r(t.length?e.filter((e=>!t.includes(e.slug))):e),u.current=!0}catch(e){l(e.message)}finally{a(!1)}}),[]),d=(0,o.useCallback)((()=>{c()}),[c]),p=(0,o.useMemo)((()=>n.map((e=>({value:e.slug,label:e.name})))),[n]);return(0,o.useEffect)((()=>{e||c()}),[e]),{taxonomies:n,isLoading:i,error:s,refreshTaxonomies:d,taxonomyOptions:p,isLoaded:u.current}};var o=n(1594);const fetchTaxonomies=async()=>{const e=`${elementorCommon.config.urls.rest}wp/v2/taxonomies`,t=await fetch(e,{headers:{"Content-Type":"application/json","X-WP-Nonce":window.wpApiSettings?.nonce||""}}),n=await t.json();if(!t.ok){throw new Error(n?.data?.message||`HTTP error! with the following code: ${n?.data?.code}`)}return Object.values(n)}},8551:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isHighTier=void 0;t.isHighTier=()=>{try{return"expert"===elementorCommon?.config?.library_connect?.plan_type||"agency"===elementorCommon?.config?.library_connect?.plan_type}catch(e){return!1}}},1052:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(8856),r=n(7450),i=n(8706);t.default=class Module{constructor(){this.registerCustomizationDialogs()}registerCustomizationDialogs(){if(!elementorCommon?.config?.experimentalFeatures?.["import-export-customization"])return;const e=window.elementorModules?.importExport?.customizationDialogsRegistry;e&&(e.register({key:"content",title:"Content Dialog",component:o.KitContentCustomizationDialog}),e.register({key:"templates",title:"Templates Dialog",component:r.KitTemplatesCustomizationDialog}),e.register({key:"settings",title:"Settings Dialog",component:i.KitSettingsCustomizationDialog}))}}},5533:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.transformValueForAnalytics=t.getTotalAvailableCount=t.ANALYTICS_TRANSFORM_RULES=void 0;const n=t.ANALYTICS_TRANSFORM_RULES={STRING:e=>e,BOOLEAN:e=>e,EMPTY_ARRAY:()=>"None",FULL_ARRAY:()=>"All",PARTIAL_ARRAY:()=>"Partial"},getTotalAvailableCount=(e,t)=>t.reduce(((e,{key:t,options:n})=>(e[t]=n.length,e)),{})[e]||0;t.getTotalAvailableCount=getTotalAvailableCount;t.transformValueForAnalytics=(e,t,o)=>{if("string"==typeof t||"boolean"==typeof t)return n[(typeof t).toUpperCase()](t);if("object"==typeof t&&null!==t&&!Array.isArray(t)&&"enabled"in t)return t.enabled;if(Array.isArray(t)){if(0===t.length)return n.EMPTY_ARRAY();const r=getTotalAvailableCount(e,o);return t.length===r?n.FULL_ARRAY():n.PARTIAL_ARRAY()}return t}},9844:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.Indicator=void 0;var i=r(n(1594));n(4047);const Indicator=e=>{let t="eps-indicator-bullet";return e.active&&(t+=` ${t}--active`),i.default.createElement("i",{className:t})};t.Indicator=Indicator,Indicator.propTypes={active:o.bool}},9303:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=PreviewIFrame;var i=r(n(1594));function PreviewIFrame(e){const t=i.default.useRef(null),[n,o]=i.default.useState(1),[r,a]=i.default.useState(0);return i.default.useEffect((()=>{const e=t.current.clientWidth/1200;o(e),a(t.current.clientHeight/e)}),[]),i.default.createElement("div",{ref:t,className:`site-editor__preview-iframe site-editor__preview-iframe--${e.templateType}`},i.default.createElement("iframe",{title:"preview",src:e.src,className:"site-editor__preview-iframe__iframe",style:{transform:`scale(${n})`,height:r,width:1200}}))}n(1260),PreviewIFrame.propTypes={src:o.string.isRequired,templateType:o.string.isRequired}},9804:(e,t,n)=>{"use strict";var o=n(1594);Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.BaseContext=void 0;class BaseContext extends o.Component{constructor(e){super(e),this.state={action:{current:null,loading:!1,error:null,errorMeta:{}},updateActionState:this.updateActionState.bind(this),resetActionState:this.resetActionState.bind(this)}}executeAction(e,t){return this.updateActionState({current:e,loading:!0,error:null,errorMeta:{}}),t().then((e=>(this.resetActionState(),Promise.resolve(e)))).catch((t=>(this.updateActionState({current:e,loading:!1,error:t.message,errorMeta:t}),Promise.reject(t))))}updateActionState(e){return this.setState((t=>({action:{...t.action,...e}})))}resetActionState(){this.updateActionState({current:null,loading:!1,error:null,errorMeta:{}})}}t.BaseContext=BaseContext;t.default=BaseContext},4737:(e,t,n)=>{"use strict";var o=n(2688),r=n(2470).__,i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Context=t.ConditionsProvider=void 0;var a=i(n(1594)),s=i(n(8067)),l=i(n(2075)),u=i(n(9804)),c=n(5559);const d=t.Context=a.default.createContext();class ConditionsProvider extends u.default{static propTypes={children:o.any.isRequired,currentTemplate:o.object.isRequired,onConditionsSaved:o.func.isRequired,validateConflicts:o.bool};static defaultProps={validateConflicts:!0};static actions={FETCH_CONFIG:"fetch-config",SAVE:"save",CHECK_CONFLICTS:"check-conflicts"};conditionsConfig=null;constructor(e){super(e),this.state={...this.state,conditionsFetched:!1,conditions:{},updateConditionItemState:this.updateConditionItemState.bind(this),removeConditionItemInState:this.removeConditionItemInState.bind(this),createConditionItemInState:this.createConditionItemInState.bind(this),findConditionItemInState:this.findConditionItemInState.bind(this),saveConditions:this.saveConditions.bind(this)}}componentDidMount(){this.executeAction(ConditionsProvider.actions.FETCH_CONFIG,(()=>l.default.create())).then((e=>this.conditionsConfig=e)).then(this.normalizeConditionsState.bind(this)).then((()=>{this.setSubIdTitles.bind(this),this.setState({conditionsFetched:!0})}))}componentDidUpdate(e,t){!t.conditionsFetched&&this.state.conditionsFetched&&this.setSubIdTitles()}saveConditions(){const e=Object.values(this.state.conditions).map((e=>e.forDb()));return this.executeAction(ConditionsProvider.actions.SAVE,(()=>$e.data.update(c.TemplatesConditions.signature,{conditions:e},{id:this.props.currentTemplate.id}))).then((()=>{const e=Object.values(this.state.conditions).map((e=>e.forContext()));this.props.onConditionsSaved(this.props.currentTemplate.id,{conditions:e,instances:this.conditionsConfig.calculateInstances(Object.values(this.state.conditions)),isActive:!(!Object.keys(this.state.conditions).length||"publish"!==this.props.currentTemplate.status)})}))}checkConflicts(e){return this.executeAction(ConditionsProvider.actions.CHECK_CONFLICTS,(()=>$e.data.get(c.TemplatesConditionsConflicts.signature,{post_id:this.props.currentTemplate.id,condition:e.clone().toString()}))).then((t=>this.updateConditionItemState(e.id,{conflictErrors:Object.values(t.data)},!1)))}fetchSubIdsTitles(e){return new Promise((t=>elementorCommon.ajax.loadObjects({action:"query_control_value_titles",ids:_.isArray(e.subId)?e.subId:[e.subId],data:{get_titles:e.subIdAutocomplete,unique_id:elementorCommon.helpers.getUniqueId()},success(e){t(e)}})))}normalizeConditionsState(){this.updateConditionsState((()=>this.props.currentTemplate.conditions.reduce(((e,t)=>{const n=new s.default({...t,default:this.props.currentTemplate.defaultCondition,options:this.conditionsConfig.getOptions(),subOptions:this.conditionsConfig.getSubOptions(t.name),subIdAutocomplete:this.conditionsConfig.getSubIdAutocomplete(t.sub),subIdOptions:t.subId?[{value:t.subId,label:""}]:[]});return{...e,[n.id]:n}}),{}))).then((()=>{Object.values(this.state.conditions).forEach((e=>this.checkConflicts(e)))}))}setSubIdTitles(){return Object.values(this.state.conditions).forEach((e=>{if(e.subId)return this.fetchSubIdsTitles(e).then((t=>this.updateConditionItemState(e.id,{subIdOptions:[{label:Object.values(t)[0],value:e.subId}]},!1)))}))}updateConditionItemState(e,t,n=!0){t.name&&(t.subOptions=this.conditionsConfig.getSubOptions(t.name)),(t.sub||t.name)&&(t.subIdAutocomplete=this.conditionsConfig.getSubIdAutocomplete(t.sub),t.subIdOptions=[]),this.updateConditionsState((n=>{const o=n[e];return{...n,[e]:o.clone().set(t)}})).then((()=>{n&&this.checkConflicts(this.findConditionItemInState(e))}))}removeConditionItemInState(e){this.updateConditionsState((t=>{const n={...t};return delete n[e],n}))}createConditionItemInState(e=!0){const t=this.props.currentTemplate.defaultCondition,n=new s.default({name:t,default:t,options:this.conditionsConfig.getOptions(),subOptions:this.conditionsConfig.getSubOptions(t),subIdAutocomplete:this.conditionsConfig.getSubIdAutocomplete("")});this.updateConditionsState((e=>({...e,[n.id]:n}))).then((()=>{e&&this.checkConflicts(n)}))}findConditionItemInState(e){return Object.values(this.state.conditions).find((t=>t.id===e))}updateConditionsState(e){return new Promise((t=>this.setState((t=>({conditions:e(t.conditions)})),t)))}render(){if(this.state.action.current===ConditionsProvider.actions.FETCH_CONFIG){if(this.state.error)return a.default.createElement("h3",null,r("Error:","elementor-pro")," ",this.state.error);if(this.state.loading)return a.default.createElement("h3",null,r("Loading","elementor-pro"),"...")}return a.default.createElement(d.Provider,{value:this.state},this.props.children)}}t.ConditionsProvider=ConditionsProvider;t.default=ConditionsProvider},8067:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class Condition{id=elementorCommon.helpers.getUniqueId();default="";type="include";name="";sub="";subId="";options=[];subOptions=[];subIdAutocomplete=[];subIdOptions=[];conflictErrors=[];constructor(e){this.set(e)}set(e){return Object.assign(this,e),this}clone(){return Object.assign(new Condition,this)}remove(e){return Array.isArray(e)||(e=[e]),e.forEach((e=>{delete this[e]})),this}only(e){Array.isArray(e)||(e=[e]);const t=Object.keys(this).filter((t=>!e.includes(t)));return this.remove(t),this}toJson(){return JSON.stringify(this)}toString(){return this.forDb().filter((e=>e)).join("/")}forDb(){return[this.type,this.name,this.sub,this.subId]}forContext(){return{type:this.type,name:this.name,sub:this.sub,subId:this.subId}}}t.default=Condition},2075:(e,t,n)=>{"use strict";var o=n(2470).__;Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.ConditionsConfig=void 0;var r=n(5559);class ConditionsConfig{static instance;config=null;constructor(e){this.config=e}static create(){return ConditionsConfig.instance?Promise.resolve(ConditionsConfig.instance):$e.data.get(r.ConditionsConfig.signature,{},{refresh:!0}).then((e=>(ConditionsConfig.instance=new ConditionsConfig(e.data),ConditionsConfig.instance)))}getOptions(){return this.getSubOptions("general",!0).map((({label:e,value:t})=>({label:e,value:t})))}getSubOptions(e,t=!1){const n=this.config[e];return n?[{label:n.all_label,value:t?e:""},...n.sub_conditions.map((e=>{const t=this.config[e];return{label:t.label,value:e,children:t.sub_conditions.length?this.getSubOptions(e,!0):null}}))]:[]}getSubIdAutocomplete(e){const t=this.config[e];if(!t||"object"!=typeof t.controls)return{};const n=Object.values(t.controls);return n?.[0]?.autocomplete?n[0].autocomplete:{}}calculateInstances(e){let t=e.reduce(((e,t)=>{if("exclude"===t.type)return e;const n=t.sub||t.name,o=this.config[n];if(!o)return e;const r=t.subId?`${o.label} #${t.subId}`:o.all_label;return{...e,[n]:r}}),{});return 0===Object.keys(t).length&&(t=[o("No instances","elementor-pro")]),t}}t.ConditionsConfig=ConditionsConfig;t.default=ConditionsConfig},1500:(e,t,n)=>{"use strict";var o=n(2688),r=n(2470).__,i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesProvider=t.Context=void 0;var a=i(n(1594)),s=i(n(9804)),l=n(5559),u=i(n(2239));const c=t.Context=a.default.createContext();class TemplatesProvider extends s.default{static propTypes={children:o.object.isRequired};static actions={FETCH:"fetch",DELETE:"delete",UPDATE:"update",IMPORT:"import"};constructor(e){super(e),this.state={...this.state,action:{...this.state.action,current:TemplatesProvider.actions.FETCH,loading:!0},templates:{},updateTemplateItemState:this.updateTemplateItemState.bind(this),findTemplateItemInState:this.findTemplateItemInState.bind(this),fetchTemplates:this.fetchTemplates.bind(this),deleteTemplate:this.deleteTemplate.bind(this),updateTemplate:this.updateTemplate.bind(this),importTemplates:this.importTemplates.bind(this)}}componentDidMount(){this.fetchTemplates()}importTemplates({fileName:e,fileData:t}){return this.executeAction(TemplatesProvider.actions.IMPORT,(()=>$e.data.create(l.Templates.signature,{fileName:e,fileData:t}))).then((e=>(this.updateTemplatesState((t=>({...t,...Object.values(e.data).reduce(((e,t)=>t.supportsSiteEditor?{...e,[t.id]:t}:e),{})}))),e)))}deleteTemplate(e){return this.executeAction(TemplatesProvider.actions.DELETE,(()=>$e.data.delete(l.Templates.signature,{id:e}))).then((()=>{this.updateTemplatesState((t=>{const n={...t};return delete n[e],n}))}))}updateTemplate(e,t){return this.executeAction(TemplatesProvider.actions.UPDATE,(()=>$e.data.update(l.Templates.signature,t,{id:e}))).then((t=>{this.updateTemplateItemState(e,t.data)}))}fetchTemplates(){return this.executeAction(TemplatesProvider.actions.FETCH,(()=>$e.data.get(l.Templates.signature,{},{refresh:!0}))).then((e=>{this.updateTemplatesState((()=>Object.values(e.data).reduce(((e,t)=>({...e,[t.id]:t})),{})),!1)}))}updateTemplateItemState(e,t){return this.updateTemplatesState((n=>{const o={...n[e],...t};return{...n,[e]:o}}))}updateTemplatesState(e,t=!0){return t&&$e.data.deleteCache($e.components.get(u.default.namespace),l.Templates.signature),this.setState((t=>({templates:e(t.templates)})))}findTemplateItemInState(e){return this.state.templates[e]}render(){if(this.state.action.current===TemplatesProvider.actions.FETCH){if(this.state.action.error)return a.default.createElement("h3",null,r("Error:","elementor-pro")," ",this.state.action.error);if(this.state.action.loading)return a.default.createElement("h3",null,r("Loading","elementor-pro"),"...")}return a.default.createElement(c.Provider,{value:this.state},this.props.children)}}t.TemplatesProvider=TemplatesProvider;t.default=TemplatesProvider},7952:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.ConditionsConfig=void 0;class ConditionsConfig extends $e.modules.CommandData{static signature="site-editor/conditions-config";static getEndpointFormat(){return"site-editor/conditions-config/{id}"}}t.ConditionsConfig=ConditionsConfig;t.default=ConditionsConfig},5559:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ConditionsConfig",{enumerable:!0,get:function(){return r.ConditionsConfig}}),Object.defineProperty(t,"Templates",{enumerable:!0,get:function(){return o.Templates}}),Object.defineProperty(t,"TemplatesConditions",{enumerable:!0,get:function(){return i.TemplatesConditions}}),Object.defineProperty(t,"TemplatesConditionsConflicts",{enumerable:!0,get:function(){return a.TemplatesConditionsConflicts}});var o=n(7636),r=n(7952),i=n(9591),a=n(7821)},7821:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditionsConflicts=void 0;class TemplatesConditionsConflicts extends $e.modules.CommandData{static signature="site-editor/templates-conditions-conflicts";static getEndpointFormat(){return`${TemplatesConditionsConflicts.signature}/{id}`}}t.TemplatesConditionsConflicts=TemplatesConditionsConflicts;t.default=TemplatesConditionsConflicts},9591:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditions=void 0;class TemplatesConditions extends $e.modules.CommandData{static signature="site-editor/templates-conditions";static getEndpointFormat(){return"site-editor/templates-conditions/{id}"}}t.TemplatesConditions=TemplatesConditions;t.default=TemplatesConditions},7636:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Templates=void 0;class Templates extends $e.modules.CommandData{static signature="site-editor/templates";static getEndpointFormat(){return"site-editor/templates/{id}"}}t.Templates=Templates;t.default=Templates},2239:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(5559));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}class Component extends $e.modules.ComponentBase{static namespace="site-editor";getNamespace(){return this.constructor.namespace}defaultData(){return this.importCommands(o)}}t.default=Component},2138:(e,t,n)=>{"use strict";var o=n(1594);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function useTemplatesScreenshot(e=null){const{updateTemplateItemState:t,templates:n}=o.useContext(r.Context),a=Object.values(n).filter((t=>function shouldScreenshotTemplate(e,t=null){if(t)return!1;return"publish"===e.status&&!e.thumbnail&&e.screenshot_url}(t,e))),s=(0,i.default)(a);return o.useEffect((()=>{s.posts.filter((e=>e.status===i.SCREENSHOT_STATUS_SUCCEED)).forEach((e=>t(e.id,{thumbnail:e.imageUrl})))}),[s.succeed]),o.useEffect((()=>{s.posts.filter((e=>e.status===i.SCREENSHOT_STATUS_FAILED)).forEach((e=>t(e.id,{screenshot_url:null})))}),[s.failed]),s};var r=n(1500),i=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(6930));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}},7579:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=BackButton;var a=i(n(1594)),s=n(7401);function BackButton(e){return a.default.createElement("div",{className:"back-button-wrapper"},a.default.createElement(s.Button,{className:"eps-back-button",text:o("Back","elementor-pro"),icon:"eicon-chevron-left",onClick:e.onClick}))}n(9652),BackButton.propTypes={onClick:r.func},BackButton.defaultProps={onClick:()=>history.back()}},6558:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.SiteTemplateBody=void 0;var i=r(n(1594)),a=n(7401),s=r(n(6620)),l=r(n(9303));const SiteTemplateBody=e=>i.default.createElement(a.CardBody,null,e.extended?i.default.createElement(l.default,{src:e.previewUrl,templateType:e.type}):i.default.createElement(s.default,{id:e.id,title:e.title,type:e.type,thumbnail:e.thumbnail,placeholder:e.placeholderUrl}));t.SiteTemplateBody=SiteTemplateBody,SiteTemplateBody.propTypes={extended:o.bool,id:o.number,title:o.string,thumbnail:o.string,placeholderUrl:o.string,type:o.string,previewUrl:o.string}},6085:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.SiteTemplateFooter=void 0;var a=i(n(1594)),s=n(7401);const SiteTemplateFooter=e=>{const t=Object.values(e.instances).join(", ");return a.default.createElement(s.CardFooter,null,a.default.createElement("div",{className:"e-site-template__instances"},a.default.createElement(s.Icon,{className:"eicon-flow"}),a.default.createElement(s.Text,{tag:"span",variant:"sm"},a.default.createElement("b",null,o("Instances","elementor-pro"),":")),a.default.createElement(s.Text,{className:"e-site-template__instances-list",tag:"span",variant:"xxs"}," ",t),a.default.createElement(s.Button,{text:o("Edit Conditions","elementor-pro"),className:"e-site-template__edit-conditions",url:`/site-editor/conditions/${e.id}`})))};t.SiteTemplateFooter=SiteTemplateFooter,SiteTemplateFooter.propTypes={id:r.number.isRequired,instances:r.any}},508:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.SiteTemplateHeader=void 0;var a=i(n(1594)),s=n(7401),l=i(n(7146)),u=n(9844);const SiteTemplateHeader=e=>{const t=e.status&&"publish"!==e.status?` (${e.status})`:"",n=e.title+t,ActionButtons=()=>a.default.createElement(a.default.Fragment,null,a.default.createElement(s.Button,{text:o("Edit","elementor-pro"),icon:"eicon-edit",className:"e-site-template__edit-btn",size:"sm",url:e.editURL}),a.default.createElement(l.default,e)),MetaDataIcon=e=>a.default.createElement(s.Text,{tag:"span",className:"e-site-template__meta-data"},a.default.createElement(s.Icon,{className:e.icon}),e.content),MetaData=()=>a.default.createElement(a.default.Fragment,null,a.default.createElement(MetaDataIcon,{icon:"eicon-user-circle-o",content:e.author}),a.default.createElement(MetaDataIcon,{icon:"eicon-clock-o",content:e.modifiedDate})),r=e.showInstances?a.default.createElement(u.Indicator,{active:e.isActive}):"";return a.default.createElement(s.CardHeader,null,r,a.default.createElement(s.Heading,{tag:"h1",title:n,variant:"text-sm",className:"eps-card__headline"},n),e.extended&&a.default.createElement(MetaData,null),e.extended&&a.default.createElement(ActionButtons,null))};t.SiteTemplateHeader=SiteTemplateHeader,SiteTemplateHeader.propTypes={isActive:r.bool,author:r.string,editURL:r.string,extended:r.bool,modifiedDate:r.string,status:r.string,title:r.string,showInstances:r.bool}},6620:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=SiteTemplateThumbnail;var a=i(n(1594)),s=n(7401);function SiteTemplateThumbnail(e){return a.default.createElement(s.CardImage,{alt:e.title,src:e.thumbnail||e.placeholder,className:e.thumbnail?"":"e-site-template__placeholder"},a.default.createElement(s.CardOverlay,{className:"e-site-template__overlay-preview"},a.default.createElement(s.Button,{className:"e-site-template__overlay-preview-button",text:o("Preview","elementor-pro"),icon:"eicon-preview-medium",url:`/site-editor/templates/${e.type}/${e.id}`})))}SiteTemplateThumbnail.propTypes={id:r.number,title:r.string,type:r.string,thumbnail:r.string,placeholder:r.string}},6789:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=SiteTemplate;var i=r(n(1594));n(5724);var a=n(7401),s=n(508),l=n(6558),u=n(6085);function SiteTemplate(e){const t="e-site-template",n=[t],o=i.default.useRef(null);i.default.useEffect((()=>{e.isSelected&&o.current.scrollIntoView({behavior:"smooth",block:"start"})}),[e.isSelected]),e.extended&&n.push(`${t}--extended`),e.aspectRatio&&n.push(`${t}--${e.aspectRatio}`);const r=e.extended&&e.showInstances?i.default.createElement(u.SiteTemplateFooter,e):"";return i.default.createElement(a.Card,{className:n.join(" "),ref:o},i.default.createElement(s.SiteTemplateHeader,e),i.default.createElement(l.SiteTemplateBody,e),r)}n(3762),SiteTemplate.propTypes={aspectRatio:o.string,className:o.string,extended:o.bool,id:o.number.isRequired,isActive:o.bool.isRequired,status:o.string,thumbnail:o.string.isRequired,title:o.string.isRequired,isSelected:o.bool,type:o.string.isRequired,showInstances:o.bool},SiteTemplate.defaultProps={isSelected:!1}},3192:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=SiteTemplates;var a=i(n(1594)),s=i(n(8304)),l=n(7401),u=i(n(6789)),c=n(7146),d=n(1500),p=i(n(2138));function SiteTemplates(e){const{templates:t,action:n,resetActionState:r}=a.default.useContext(d.Context);let i,f;f=a.default.useMemo((()=>Object.values(t).sort(((e,t)=>t.isActive||e.isActive?t.isActive&&e.isActive?t.datet.type===e.type)),m.extended=!0,m.type=e.type,e.type){case"header":case"footer":i=1,m.aspectRatio="wide";break;default:i=2}return f&&f.length?a.default.createElement("section",{className:"e-site-editor__site-templates"},a.default.createElement(c.PartActionsDialogs,null),n.error&&a.default.createElement(l.Dialog,{text:n.error,dismissButtonText:o("Go Back","elementor-pro"),dismissButtonOnClick:r,approveButtonText:o("Learn More","elementor-pro"),approveButtonColor:"link",approveButtonUrl:"https://go.elementor.com/app-theme-builder-template-load-issue",approveButtonTarget:"_target"}),a.default.createElement(l.CssGrid,{columns:i,spacing:24,colMinWidth:200},f.map((t=>a.default.createElement(u.default,(0,s.default)({key:t.id},t,m,{isSelected:parseInt(e.id)===t.id})))))):a.default.createElement("h3",null,o("No Templates found. Want to create one?","elementor-pro"),"...")}SiteTemplates.propTypes={type:r.string,id:r.string}},6400:(e,t,n)=>{"use strict";var o=n(2688),r=n(2470).__,i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function AddNew(){const{templates:e}=a.default.useContext(u.Context),t=1<=Object.keys(e).length,{isLocked:n,ConnectButton:i}=(0,d.default)("site-editor"),HoverElement=e=>n?a.default.createElement(s.CardOverlay,{className:"e-site-editor__promotion-overlay"},a.default.createElement("div",{className:"e-site-editor__promotion-overlay__link"},a.default.createElement("i",{className:"e-site-editor__promotion-overlay__icon eicon-lock"}))):a.default.createElement("a",{href:e.urls.create,className:"eps-card__image-overlay eps-add-new__overlay"},a.default.createElement(s.AddNewButton,{hideText:!0}));return HoverElement.propTypes={urls:o.object.isRequired},a.default.createElement("section",{className:"e-site-editor__add-new"},a.default.createElement(s.Grid,{container:!0,direction:"column",className:"e-site-editor__header"},t&&a.default.createElement(s.Grid,{item:!0},a.default.createElement(c.default,null)),a.default.createElement(s.Grid,{item:!0,container:!0,justify:"space-between",alignItems:"start"},a.default.createElement(s.Heading,{variant:"h1"},r("Start customizing every part of your site","elementor-pro")),n&&a.default.createElement(i,null))),a.default.createElement(l.SiteParts,{hoverElement:HoverElement}))};var a=i(n(1594)),s=n(7401),l=n(858);n(8515);var u=n(1500),c=i(n(7579)),d=i(n(4292))},7010:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(5206),r=n(1594),i=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const ConditionButtonPortal=e=>{const[t,n]=(0,r.useState)(!1),i=document.getElementById("portal-root");return(0,r.useEffect)((()=>{n(!!i)}),[i]),t?(0,o.createPortal)(e.children,i):null};ConditionButtonPortal.propTypes={children:i.oneOfType([i.node,i.string])};t.default=ConditionButtonPortal},7624:(e,t,n)=>{"use strict";var o=n(2470).sprintf,r=n(2470).__,i=n(2688),a=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionConflicts;var s=a(n(1594)),l=n(7401);function ConditionConflicts(e){if(!e.conflicts.length)return"";const t=e.conflicts.map((e=>s.default.createElement(l.Button,{key:e.template_id,target:"_blank",url:e.edit_url,text:e.template_title})));return s.default.createElement(l.Text,{className:"e-site-editor-conditions__conflict",variant:"sm"},o(r("We noticed that you already applied %s with the same condition.","elementor-pro"),t),s.default.createElement("br",null),r("To continue, set different conditions for each so they don't conflict.","elementor-pro"))}ConditionConflicts.propTypes={conflicts:i.array.isRequired}},1360:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionName;var i=r(n(1594)),a=n(7401);function ConditionName(e){if("general"!==e.default)return"";return i.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},i.default.createElement(a.Select,{options:e.options,value:e.name,onChange:t=>e.updateConditions(e.id,{name:t.target.value,sub:"",subId:""})}))}ConditionName.propTypes={updateConditions:o.func.isRequired,id:o.string.isRequired,name:o.string.isRequired,options:o.array.isRequired,default:o.string.isRequired},ConditionName.defaultProps={name:""}},2943:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionSubId;var a=i(n(1594)),s=n(7401);function ConditionSubId(e){const t=a.default.useMemo((()=>Object.keys(e.subIdAutocomplete).length?function getSettings(e){return{allowClear:!1,placeholder:o("All","elementor-pro"),dir:elementorCommon.config.isRTL?"rtl":"ltr",ajax:{transport:(t,n,o)=>elementorCommon.ajax.addRequest("pro_panel_posts_control_filter_autocomplete",{data:{q:t.data.q,autocomplete:e},success:n,error:o}),data:e=>({q:e.term,page:e.page}),cache:!0},escapeMarkup:e=>e,minimumInputLength:1}}(e.subIdAutocomplete):null),[e.subIdAutocomplete]);if(!e.sub||!t)return"";return a.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},a.default.createElement(s.Select2,{onChange:t=>e.updateConditions(e.id,{subId:t.target.value}),value:e.subId,settings:t,options:e.subIdOptions}))}ConditionSubId.propTypes={subIdAutocomplete:r.object,id:r.string.isRequired,sub:r.string,subId:r.string,updateConditions:r.func,subIdOptions:r.array},ConditionSubId.defaultProps={subId:"",subIdOptions:[]}},2437:(e,t,n)=>{"use strict";var o=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionSub;var i=r(n(1594)),a=n(7401);function ConditionSub(e){if("general"===e.name||!e.subOptions.length)return"";return i.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},i.default.createElement(a.Select,{options:e.subOptions,value:e.sub,onChange:t=>e.updateConditions(e.id,{sub:t.target.value,subId:""})}))}ConditionSub.propTypes={updateConditions:o.func.isRequired,id:o.string.isRequired,name:o.string.isRequired,sub:o.string.isRequired,subOptions:o.array.isRequired},ConditionSub.defaultProps={sub:"",subOptions:{}}},1303:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionType;var a=i(n(1594)),s=n(7401);function ConditionType(e){const t=a.default.createRef(),n=[{label:o("Include","elementor-pro"),value:"include"},{label:o("Exclude","elementor-pro"),value:"exclude"}];return a.default.useEffect((()=>{t.current.setAttribute("data-elementor-condition-type",e.type)})),a.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper e-site-editor-conditions__input-wrapper--condition-type",ref:t},a.default.createElement(s.Select,{options:n,value:e.type,onChange:t=>{e.updateConditions(e.id,{type:t.target.value})}}))}ConditionType.propTypes={updateConditions:r.func.isRequired,id:r.string.isRequired,type:r.string.isRequired},ConditionType.defaultProps={type:""}},8927:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionsRows;var a=i(n(1594)),s=i(n(8304)),l=n(4737),u=n(7401),c=i(n(1303)),d=i(n(1360)),p=i(n(2437)),f=i(n(2943)),m=i(n(7624)),h=i(n(7010));function ConditionsRows(e){const{conditions:t,createConditionItemInState:n,updateConditionItemState:r,removeConditionItemInState:i,saveConditions:g,action:v,resetActionState:b}=a.default.useContext(l.Context),y=Object.values(t).map((e=>a.default.createElement("div",{key:e.id},a.default.createElement("div",{className:"e-site-editor-conditions__row"},a.default.createElement("div",{className:`e-site-editor-conditions__row-controls ${e.conflictErrors.length&&"e-site-editor-conditions__row-controls--error"}`},a.default.createElement(c.default,(0,s.default)({},e,{updateConditions:r})),a.default.createElement("div",{className:"e-site-editor-conditions__row-controls-inner"},a.default.createElement(d.default,(0,s.default)({},e,{updateConditions:r})),a.default.createElement(p.default,(0,s.default)({},e,{updateConditions:r})),a.default.createElement(f.default,(0,s.default)({},e,{updateConditions:r})))),a.default.createElement(u.Button,{className:"e-site-editor-conditions__remove-condition",text:o("Delete","elementor-pro"),icon:"eicon-close",hideText:!0,onClick:()=>i(e.id)})),a.default.createElement(m.default,{conflicts:e.conflictErrors})))),SaveButton=()=>a.default.createElement(u.Button,{variant:"contained",color:"primary",size:"lg",hideText:_,icon:_?"eicon-loading eicon-animation-spin":"",text:o("Save & Close","elementor-pro"),onClick:()=>g().then(e.onAfterSave)}),_=v.current===l.ConditionsProvider.actions.SAVE&&v.loading;return a.default.createElement(a.default.Fragment,null,v.error&&a.default.createElement(u.Dialog,{text:v.error,dismissButtonText:o("Go Back","elementor-pro"),dismissButtonOnClick:b,approveButtonText:o("Learn More","elementor-pro"),approveButtonColor:"link",approveButtonUrl:"https://go.elementor.com/app-theme-builder-conditions-load-issue",approveButtonTarget:"_target"}),a.default.createElement("div",{className:"e-site-editor-conditions__rows"},y),a.default.createElement("div",{className:"e-site-editor-conditions__add-button-container"},a.default.createElement(u.Button,{className:"e-site-editor-conditions__add-button",variant:"contained",size:"lg",text:o("Add Condition","elementor-pro"),onClick:n})),a.default.createElement("div",{className:"e-site-editor-conditions__footer"},e?.loadPortal?a.default.createElement(h.default,null,a.default.createElement(SaveButton,null)):a.default.createElement(SaveButton,null)))}ConditionsRows.propTypes={onAfterSave:r.func,loadPortal:r.bool}},4933:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=Conditions;var a=i(n(1594)),s=n(7401),l=i(n(4737)),u=n(1500),c=i(n(8927));n(734);var d=i(n(7579));function Conditions(e){const{findTemplateItemInState:t,updateTemplateItemState:n}=a.default.useContext(u.Context),r=t(parseInt(e.id));return r?a.default.createElement("section",{className:"e-site-editor-conditions"},a.default.createElement(d.default,null),a.default.createElement("div",{className:"e-site-editor-conditions__header"},a.default.createElement("img",{className:"e-site-editor-conditions__header-image",src:`${elementorAppProConfig.baseUrl}/modules/theme-builder/assets/images/conditions-tab.svg`,alt:o("Import template","elementor-pro")}),a.default.createElement(s.Heading,{variant:"h1",tag:"h1"},o("Where do you want to display your template?","elementor-pro")),a.default.createElement(s.Text,{variant:"p"},o("Set the conditions that determine where your template is used throughout your site.","elementor-pro"),a.default.createElement("br",null),o("For example, choose 'Entire Site' to display the template across your site.","elementor-pro"))),a.default.createElement(l.default,{currentTemplate:r,onConditionsSaved:n},a.default.createElement(c.default,{onAfterSave:()=>history.back(),loadPortal:!0}))):a.default.createElement("div",null,o("Not Found","elementor-pro"))}Conditions.propTypes={id:r.string}},3147:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function Import(){const{importTemplates:e,action:t,resetActionState:n}=i.default.useContext(s.Context),[r,c]=i.default.useState(null),d=t.current===s.TemplatesProvider.actions.IMPORT,p=d&&t.loading,f=d&&t.error,m=i.default.useCallback((t=>{p||function readFile(e){return new Promise((t=>{const n=new FileReader;n.readAsDataURL(e),n.onload=e=>{t(e.target.result.replace(/^[^,]+,/,""))}}))}(t).then((n=>e({fileName:t.name,fileData:n}))).then((e=>{c(e.data[0])}))}),[]),{runAction:h,dialog:g,checkbox:v}=u({doNotShowAgainKey:"upload_json_warning_generic_message",action:m});return i.default.createElement("section",{className:"site-editor__import"},r&&i.default.createElement(a.Dialog,{title:o("Your template was imported","elementor-pro"),approveButtonText:o("Preview","elementor-pro"),approveButtonUrl:r.url,approveButtonTarget:"_blank",dismissButtonText:o("Edit","elementor-pro"),dismissButtonUrl:r.editURL,dismissButtonTarget:"_top",onClose:()=>c(null)}),f&&i.default.createElement(a.Dialog,{title:t.error,approveButtonText:o("Learn More","elementor-pro"),approveButtonUrl:"https://go.elementor.com/app-theme-builder-import-issue",approveButtonTarget:"_blank",approveButtonColor:"link",dismissButtonText:o("Go Back","elementor-pro"),dismissButtonOnClick:n,onClose:n}),g.isOpen&&i.default.createElement(a.Dialog,{title:o("Warning: JSON or ZIP files may be unsafe","elementor-pro"),text:o("Uploading JSON or ZIP files from unknown sources can be harmful and put your site at risk. For maximum safety, upload only JSON or ZIP files from trusted sources.","elementor-pro"),approveButtonColor:"link",approveButtonText:o("Continue","elementor-pro"),approveButtonOnClick:g.approve,dismissButtonText:o("Cancel","elementor-pro"),dismissButtonOnClick:g.dismiss,onClose:g.dismiss},i.default.createElement("label",{htmlFor:"do-not-show-upload-json-warning-again",style:{display:"flex",alignItems:"center",gap:"5px"}},i.default.createElement(a.Checkbox,{id:"do-not-show-upload-json-warning-again",type:"checkbox",value:v.isChecked,onChange:e=>v.setIsChecked(!!e.target.checked)}),o("Do not show this message again","elementor-pro"))),i.default.createElement(l.default,null),i.default.createElement(a.DropZone,{heading:o("Import Template To Your Library","elementor-pro"),text:o("Drag & Drop your .JSON or .zip template file","elementor-pro"),secondaryText:o("or","elementor-pro"),onFileSelect:h,isLoading:p,filetypes:["zip","json"]}))};var i=r(n(1594)),a=n(7401),s=n(1500),l=r(n(7579));const u=n(8276).useConfirmAction??(({action:e})=>({runAction:e,dialog:{isOpen:!1}}))},157:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=TemplateType;var a=i(n(1594)),s=n(858),l=n(7401),u=i(n(3192)),c=i(n(4292));function TemplateType(e){const{templateTypes:t}=a.default.useContext(s.TemplateTypesContext),n=t.find((t=>t.type===e.type)),{isLocked:r,ConnectButton:i}=(0,c.default)("site-editor");return n?a.default.createElement("section",{className:`e-site-editor__templates e-site-editor__templates--type-${e.type}`},a.default.createElement(l.Grid,{className:"page-header",container:!0,justify:"space-between"},a.default.createElement(l.Heading,{variant:"h1"},n.page_title),r?a.default.createElement(i,null):a.default.createElement(l.AddNewButton,{url:n.urls.create,text:o("Add New","elementor-pro")})),a.default.createElement("hr",{className:"eps-separator"}),a.default.createElement(u.default,{type:n.type,id:e.id})):a.default.createElement(l.NotFound,null)}n(1402),TemplateType.propTypes={type:r.string,page_title:r.string,id:r.string}},8519:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=function Templates(){const{isLocked:e,ConnectButton:t}=(0,l.default)("site-editor");return i.default.createElement("section",{className:"e-site-editor__site-templates"},i.default.createElement(s.Grid,{container:!0,justify:"space-between",alignItems:"start",className:"page-header"},i.default.createElement("h1",null,o("Your Site's Global Parts","elementor-pro")),e?i.default.createElement(t,null):i.default.createElement(s.AddNewButton,{url:"/site-editor/add-new"})),i.default.createElement("hr",{className:"eps-separator"}),i.default.createElement(a.default,null))};var i=r(n(1594)),a=r(n(3192)),s=n(7401),l=r(n(4292))},8031:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=DialogDelete;var a=i(n(1594)),s=n(7401),l=n(1500);function DialogDelete(e){const{deleteTemplate:t,findTemplateItemInState:n}=a.default.useContext(l.Context),closeDialog=n=>{e.setId(null),n&&t(e.id)};if(!e.id)return"";const r=n(e.id);return a.default.createElement(s.Dialog,{title:o("Move Item To Trash","elementor-pro"),text:o("Are you sure you want to move this item to trash:","elementor-pro")+` "${r.title}"`,onSubmit:()=>closeDialog(!0),approveButtonText:o("Move to Trash","elementor-pro"),approveButtonOnClick:()=>closeDialog(!0),approveButtonColor:"danger",dismissButtonText:o("Cancel","elementor-pro"),dismissButtonOnClick:()=>closeDialog(),onClose:()=>closeDialog()})}DialogDelete.propTypes={id:r.number,setId:r.func.isRequired}},7730:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688);Object.defineProperty(t,"__esModule",{value:!0}),t.default=DialogRename;var i=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(1594)),a=n(7401),s=n(1500);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function DialogRename(e){const{findTemplateItemInState:t,updateTemplate:n}=i.default.useContext(s.Context),r=t(e.id),[l,u]=i.default.useState("");(0,i.useEffect)((()=>{r&&u(r.title)}),[r]);const closeDialog=t=>{e.setId(null),t&&n(e.id,{post_title:l})};return e.id?i.default.createElement(a.Dialog,{title:o("Rename Site Part","elementor-pro"),approveButtonText:o("Change","elementor-pro"),onSubmit:()=>closeDialog(!0),approveButtonOnClick:()=>closeDialog(!0),approveButtonColor:"primary",dismissButtonText:o("Cancel","elementor-pro"),dismissButtonOnClick:()=>closeDialog(),onClose:()=>closeDialog()},i.default.createElement("input",{type:"text",className:"eps-input eps-input-text eps-input--block",autoFocus:!0,value:l,onChange:e=>u(e.target.value)})):""}DialogRename.propTypes={id:r.number,setId:r.func.isRequired}},7146:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.PartActionsDialogs=function PartActionsDialogs(){const[e,t]=a.default.useState(null),[n,o]=a.default.useState(null);return c.rename=t,c.delete=o,a.default.createElement(a.default.Fragment,null,a.default.createElement(s.default,{id:e,setId:t}),a.default.createElement(l.default,{id:n,setId:o}))},t.default=PartActionsButtons,t.handlers=void 0;var a=i(n(1594)),s=i(n(7730)),l=i(n(8031)),u=n(7401);const c=t.handlers={rename:null,delete:null};function PartActionsButtons(e){const[t,n]=a.default.useState(!1);let r="";return t&&(r=a.default.createElement(u.Popover,{closeFunction:()=>n(!t)},a.default.createElement("li",null,a.default.createElement(u.Button,{className:"eps-popover__item",icon:"eicon-sign-out",text:o("Export","elementor-pro"),url:e.exportLink})),a.default.createElement("li",null,a.default.createElement(u.Button,{className:"eps-popover__item eps-popover__item--danger",icon:"eicon-trash-o",text:o("Trash","elementor-pro"),onClick:()=>c.delete(e.id)})),a.default.createElement("li",null,a.default.createElement(u.Button,{className:"eps-popover__item",icon:"eicon-edit",text:o("Rename","elementor-pro"),onClick:()=>c.rename(e.id)})))),a.default.createElement("div",{className:"eps-popover__container"},a.default.createElement(u.Button,{text:o("Toggle","elementor-pro"),hideText:!0,icon:"eicon-ellipsis-h",size:"lg",onClick:()=>n(!t)}),r)}PartActionsButtons.propTypes={id:r.number.isRequired,exportLink:r.string.isRequired}},2808:(e,t,n)=>{"use strict";var o=n(2470).__,r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=r(n(1594)),a=n(3040),s=r(n(8519)),l=r(n(157)),u=r(n(6400)),c=r(n(4933)),d=r(n(3147)),p=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var a=r?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(o,i,a):o[i]=e[i]}return o.default=e,n&&n.set(e,o),o}(n(1500)),f=n(858),m=n(7401),h=r(n(7485)),g=r(n(2239)),v=r(n(4292));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function SiteEditor(){const{isLocked:e}=(0,v.default)("site-editor"),t="site-editor",n=[{id:"import",text:o("import","elementor-pro"),hideText:!0,icon:"eicon-upload-circle-o",onClick:()=>h.default.appHistory.navigate(t+"/import")}];elementorCommon.ajax.invalidateCache({unique_id:"app_site_editor_template_types"});const SiteEditorDefault=()=>{const{templates:e}=i.default.useContext(p.Context);return Object.keys(e).length?i.default.createElement(a.Redirect,{from:"/",to:"/"+t+"/templates",noThrow:!0}):i.default.createElement(a.Redirect,{from:"/",to:"/"+t+"/add-new",noThrow:!0})};return i.default.createElement(m.ErrorBoundary,{title:o("Theme Builder could not be loaded","elementor-pro"),learnMoreUrl:"https://go.elementor.com/app-theme-builder-load-issue"},i.default.createElement(f.Layout,{allPartsButton:i.default.createElement(f.AllPartsButton,{url:"/"+t}),headerButtons:n,titleRedirectRoute:"/"+t,promotion:e},i.default.createElement(m.Grid,{container:!0,className:"e-site-editor__content_container"},i.default.createElement(m.Grid,{item:!0,className:"e-site-editor__content_container_main"},i.default.createElement(p.default,null,i.default.createElement(a.LocationProvider,{history:h.default.appHistory},i.default.createElement(a.Router,null,i.default.createElement(SiteEditorDefault,{path:t}),i.default.createElement(s.default,{path:t+"/templates"}),i.default.createElement(l.default,{path:t+"/templates/:type/*id"}),i.default.createElement(u.default,{path:t+"/add-new"}),i.default.createElement(c.default,{path:t+"/conditions/:id"}),i.default.createElement(d.default,{path:t+"/import"}),i.default.createElement(f.NotFound,{default:!0}))))),i.default.createElement(m.Grid,{container:!0,justify:"space-between",className:"e-site-editor__content_container_secondary"},i.default.createElement(m.Button,{text:o("Switch to table view","elementor-pro"),url:elementorAppProConfig["site-editor"]?.urls?.legacy_view}),-1!==window.location.href.indexOf("conditions")&&i.default.createElement("div",{id:"portal-root"})))))}n(5043);t.default=class Module{constructor(){elementorCommon.debug.addURLToWatch("elementor-pro/assets"),$e.components.register(new g.default),h.default.addRoute({path:"/site-editor/*",component:SiteEditor})}}},6930:(e,t,n)=>{"use strict";var o=n(1594);Object.defineProperty(t,"__esModule",{value:!0}),t.SCREENSHOT_STATUS_SUCCEED=t.SCREENSHOT_STATUS_QUEUE=t.SCREENSHOT_STATUS_IN_PROGRESS=t.SCREENSHOT_STATUS_FAILED=void 0,t.default=function useScreenshot(e,{numberOfScreenshotInParallel:t}=p){const[n,o]=r([]),f=a((()=>filterPostByStatus(n,l)),[n]),m=a((()=>filterPostByStatus(n,u)),[n]),h=a((()=>filterPostByStatus(n,c)),[n]),g=a((()=>filterPostByStatus(n,d)),[n]);i((()=>{const t=e.filter((e=>!n.find((t=>t.id===e.id))));t.length&&o((e=>[...e,...normalizeInitialPosts(t)]))}),[e]);const v=function useIFrameMessageListener(e,t){return s((n=>{const{data:o}=n;if(!o.name||"capture-screenshot-done"!==o.name)return;const r=e.find((e=>e.id===parseInt(o.id)));r&&(r.iframe.remove(),t((e=>updatePostsAttrs(e,r.id,{status:o.success?c:d,imageUrl:o.imageUrl}))))}),[e])}(m,o);return i((()=>(window.addEventListener("message",v,!1),()=>{window.removeEventListener("message",v)})),[v]),i((()=>{if(0===f.length||m.length>=t)return;const[e]=f,n=function createScreenshotIframe(e){const t=document.createElement("iframe");return t.src=e.screenshot_url,t.width="1200",t.style="visibility: hidden;",document.body.appendChild(t),t}(e);o((t=>updatePostsAttrs(t,e.id,{status:u,iframe:n})))}),[n]),{posts:n,queue:f,inProgress:m,succeed:h,failed:g}};const{useState:r,useEffect:i,useMemo:a,useCallback:s}=o,l=t.SCREENSHOT_STATUS_QUEUE="queue",u=t.SCREENSHOT_STATUS_IN_PROGRESS="in-progress",c=t.SCREENSHOT_STATUS_SUCCEED="succeed",d=t.SCREENSHOT_STATUS_FAILED="failed",p={numberOfScreenshotInParallel:1};function filterPostByStatus(e,t){return e.filter((e=>t===e.status))}function normalizeInitialPosts(e){return e.map((e=>({id:e.id,screenshot_url:e.screenshot_url,status:"queue",iframe:null,imageUrl:null})))}function updatePostsAttrs(e,t,n={}){return e.map((e=>e.id!==t?e:{...e,...n}))}},8127:(e,t,n)=>{"use strict";var o="__global_unique_id__";e.exports=function(){return n.g[o]=(n.g[o]||0)+1}},2091:e=>{"use strict";e.exports=function(e,t,n,o,r,i,a,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,o,r,i,a,s],c=0;(l=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},362:(e,t,n)=>{"use strict";var o=n(6441);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,e.exports=function(){function shim(e,t,n,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function getShim(){return shim}shim.isRequired=shim;var e={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return e.PropTypes=e,e}},2688:(e,t,n)=>{e.exports=n(362)()},6441:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},567:e=>{"use strict";var warning=function(){};e.exports=warning},1594:e=>{"use strict";e.exports=React},5206:e=>{"use strict";e.exports=ReactDOM},7401:e=>{"use strict";e.exports=elementorAppPackages.appUi},8276:e=>{"use strict";e.exports=elementorAppPackages.hooks},7485:e=>{"use strict";e.exports=elementorAppPackages.router},858:e=>{"use strict";e.exports=elementorAppPackages.siteEditor},6956:e=>{"use strict";e.exports=elementorV2.ui},2470:e=>{"use strict";e.exports=wp.i18n},8304:e=>{function _extends(){return e.exports=_extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t{e.exports=function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports},8120:(e,t,n)=>{"use strict";var o=n(1483),r=n(8761),i=TypeError;e.exports=function(e){if(o(e))return e;throw new i(r(e)+" is not a function")}},2293:(e,t,n)=>{"use strict";var o=n(1704),r=String,i=TypeError;e.exports=function(e){if(o(e))return e;throw new i(r(e)+" is not an object")}},6651:(e,t,n)=>{"use strict";var o=n(5599),r=n(3392),i=n(6960),createMethod=function(e){return function(t,n,a){var s=o(t),l=i(s);if(0===l)return!e&&-1;var u,c=r(a,l);if(e&&n!=n){for(;l>c;)if((u=s[c++])!=u)return!0}else for(;l>c;c++)if((e||c in s)&&s[c]===n)return e||c||0;return!e&&-1}};e.exports={includes:createMethod(!0),indexOf:createMethod(!1)}},9273:(e,t,n)=>{"use strict";var o=n(382),r=n(4914),i=TypeError,a=Object.getOwnPropertyDescriptor,s=o&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=s?function(e,t){if(r(e)&&!a(e,"length").writable)throw new i("Cannot set read only .length");return e.length=t}:function(e,t){return e.length=t}},1278:(e,t,n)=>{"use strict";var o=n(4762),r=o({}.toString),i=o("".slice);e.exports=function(e){return i(r(e),8,-1)}},6726:(e,t,n)=>{"use strict";var o=n(5755),r=n(9497),i=n(4961),a=n(5835);e.exports=function(e,t,n){for(var s=r(t),l=a.f,u=i.f,c=0;c{"use strict";var o=n(382),r=n(5835),i=n(7738);e.exports=o?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},7738:e=>{"use strict";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},7914:(e,t,n)=>{"use strict";var o=n(1483),r=n(5835),i=n(169),a=n(2095);e.exports=function(e,t,n,s){s||(s={});var l=s.enumerable,u=void 0!==s.name?s.name:t;if(o(n)&&i(n,u,s),s.global)l?e[t]=n:a(t,n);else{try{s.unsafe?e[t]&&(l=!0):delete e[t]}catch(e){}l?e[t]=n:r.f(e,t,{value:n,enumerable:!1,configurable:!s.nonConfigurable,writable:!s.nonWritable})}return e}},2095:(e,t,n)=>{"use strict";var o=n(5578),r=Object.defineProperty;e.exports=function(e,t){try{r(o,e,{value:t,configurable:!0,writable:!0})}catch(n){o[e]=t}return t}},382:(e,t,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},3145:(e,t,n)=>{"use strict";var o=n(5578),r=n(1704),i=o.document,a=r(i)&&r(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},1091:e=>{"use strict";var t=TypeError;e.exports=function(e){if(e>9007199254740991)throw t("Maximum allowed index exceeded");return e}},4741:e=>{"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},9461:(e,t,n)=>{"use strict";var o=n(5578).navigator,r=o&&o.userAgent;e.exports=r?String(r):""},6477:(e,t,n)=>{"use strict";var o,r,i=n(5578),a=n(9461),s=i.process,l=i.Deno,u=s&&s.versions||l&&l.version,c=u&&u.v8;c&&(r=(o=c.split("."))[0]>0&&o[0]<4?1:+(o[0]+o[1])),!r&&a&&(!(o=a.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=a.match(/Chrome\/(\d+)/))&&(r=+o[1]),e.exports=r},8612:(e,t,n)=>{"use strict";var o=n(5578),r=n(4961).f,i=n(9037),a=n(7914),s=n(2095),l=n(6726),u=n(8730);e.exports=function(e,t){var n,c,d,p,f,m=e.target,h=e.global,g=e.stat;if(n=h?o:g?o[m]||s(m,{}):o[m]&&o[m].prototype)for(c in t){if(p=t[c],d=e.dontCallGetSet?(f=r(n,c))&&f.value:n[c],!u(h?c:m+(g?".":"#")+c,e.forced)&&void 0!==d){if(typeof p==typeof d)continue;l(p,d)}(e.sham||d&&d.sham)&&i(p,"sham",!0),a(n,c,p,e)}}},8473:e=>{"use strict";e.exports=function(e){try{return!!e()}catch(e){return!0}}},274:(e,t,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},1807:(e,t,n)=>{"use strict";var o=n(274),r=Function.prototype.call;e.exports=o?r.bind(r):function(){return r.apply(r,arguments)}},2048:(e,t,n)=>{"use strict";var o=n(382),r=n(5755),i=Function.prototype,a=o&&Object.getOwnPropertyDescriptor,s=r(i,"name"),l=s&&"something"===function something(){}.name,u=s&&(!o||o&&a(i,"name").configurable);e.exports={EXISTS:s,PROPER:l,CONFIGURABLE:u}},4762:(e,t,n)=>{"use strict";var o=n(274),r=Function.prototype,i=r.call,a=o&&r.bind.bind(i,i);e.exports=o?a:function(e){return function(){return i.apply(e,arguments)}}},1409:(e,t,n)=>{"use strict";var o=n(5578),r=n(1483);e.exports=function(e,t){return arguments.length<2?(n=o[e],r(n)?n:void 0):o[e]&&o[e][t];var n}},2564:(e,t,n)=>{"use strict";var o=n(8120),r=n(5983);e.exports=function(e,t){var n=e[t];return r(n)?void 0:o(n)}},5578:function(e,t,n){"use strict";var check=function(e){return e&&e.Math===Math&&e};e.exports=check("object"==typeof globalThis&&globalThis)||check("object"==typeof window&&window)||check("object"==typeof self&&self)||check("object"==typeof n.g&&n.g)||check("object"==typeof this&&this)||function(){return this}()||Function("return this")()},5755:(e,t,n)=>{"use strict";var o=n(4762),r=n(2347),i=o({}.hasOwnProperty);e.exports=Object.hasOwn||function hasOwn(e,t){return i(r(e),t)}},1507:e=>{"use strict";e.exports={}},1799:(e,t,n)=>{"use strict";var o=n(382),r=n(8473),i=n(3145);e.exports=!o&&!r((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},2121:(e,t,n)=>{"use strict";var o=n(4762),r=n(8473),i=n(1278),a=Object,s=o("".split);e.exports=r((function(){return!a("z").propertyIsEnumerable(0)}))?function(e){return"String"===i(e)?s(e,""):a(e)}:a},7268:(e,t,n)=>{"use strict";var o=n(4762),r=n(1483),i=n(1831),a=o(Function.toString);r(i.inspectSource)||(i.inspectSource=function(e){return a(e)}),e.exports=i.inspectSource},4483:(e,t,n)=>{"use strict";var o,r,i,a=n(4644),s=n(5578),l=n(1704),u=n(9037),c=n(5755),d=n(1831),p=n(5409),f=n(1507),m="Object already initialized",h=s.TypeError,g=s.WeakMap;if(a||d.state){var v=d.state||(d.state=new g);v.get=v.get,v.has=v.has,v.set=v.set,o=function(e,t){if(v.has(e))throw new h(m);return t.facade=e,v.set(e,t),t},r=function(e){return v.get(e)||{}},i=function(e){return v.has(e)}}else{var b=p("state");f[b]=!0,o=function(e,t){if(c(e,b))throw new h(m);return t.facade=e,u(e,b,t),t},r=function(e){return c(e,b)?e[b]:{}},i=function(e){return c(e,b)}}e.exports={set:o,get:r,has:i,enforce:function(e){return i(e)?r(e):o(e,{})},getterFor:function(e){return function(t){var n;if(!l(t)||(n=r(t)).type!==e)throw new h("Incompatible receiver, "+e+" required");return n}}}},4914:(e,t,n)=>{"use strict";var o=n(1278);e.exports=Array.isArray||function isArray(e){return"Array"===o(e)}},1483:e=>{"use strict";var t="object"==typeof document&&document.all;e.exports=void 0===t&&void 0!==t?function(e){return"function"==typeof e||e===t}:function(e){return"function"==typeof e}},8730:(e,t,n)=>{"use strict";var o=n(8473),r=n(1483),i=/#|\.prototype\./,isForced=function(e,t){var n=s[a(e)];return n===u||n!==l&&(r(t)?o(t):!!t)},a=isForced.normalize=function(e){return String(e).replace(i,".").toLowerCase()},s=isForced.data={},l=isForced.NATIVE="N",u=isForced.POLYFILL="P";e.exports=isForced},5983:e=>{"use strict";e.exports=function(e){return null==e}},1704:(e,t,n)=>{"use strict";var o=n(1483);e.exports=function(e){return"object"==typeof e?null!==e:o(e)}},9557:e=>{"use strict";e.exports=!1},1423:(e,t,n)=>{"use strict";var o=n(1409),r=n(1483),i=n(4815),a=n(5022),s=Object;e.exports=a?function(e){return"symbol"==typeof e}:function(e){var t=o("Symbol");return r(t)&&i(t.prototype,s(e))}},6960:(e,t,n)=>{"use strict";var o=n(8324);e.exports=function(e){return o(e.length)}},169:(e,t,n)=>{"use strict";var o=n(4762),r=n(8473),i=n(1483),a=n(5755),s=n(382),l=n(2048).CONFIGURABLE,u=n(7268),c=n(4483),d=c.enforce,p=c.get,f=String,m=Object.defineProperty,h=o("".slice),g=o("".replace),v=o([].join),b=s&&!r((function(){return 8!==m((function(){}),"length",{value:8}).length})),y=String(String).split("String"),_=e.exports=function(e,t,n){"Symbol("===h(f(t),0,7)&&(t="["+g(f(t),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),n&&n.getter&&(t="get "+t),n&&n.setter&&(t="set "+t),(!a(e,"name")||l&&e.name!==t)&&(s?m(e,"name",{value:t,configurable:!0}):e.name=t),b&&n&&a(n,"arity")&&e.length!==n.arity&&m(e,"length",{value:n.arity});try{n&&a(n,"constructor")&&n.constructor?s&&m(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var o=d(e);return a(o,"source")||(o.source=v(y,"string"==typeof t?t:"")),e};Function.prototype.toString=_((function toString(){return i(this)&&p(this).source||u(this)}),"toString")},1703:e=>{"use strict";var t=Math.ceil,n=Math.floor;e.exports=Math.trunc||function trunc(e){var o=+e;return(o>0?n:t)(o)}},5835:(e,t,n)=>{"use strict";var o=n(382),r=n(1799),i=n(3896),a=n(2293),s=n(3815),l=TypeError,u=Object.defineProperty,c=Object.getOwnPropertyDescriptor,d="enumerable",p="configurable",f="writable";t.f=o?i?function defineProperty(e,t,n){if(a(e),t=s(t),a(n),"function"==typeof e&&"prototype"===t&&"value"in n&&f in n&&!n[f]){var o=c(e,t);o&&o[f]&&(e[t]=n.value,n={configurable:p in n?n[p]:o[p],enumerable:d in n?n[d]:o[d],writable:!1})}return u(e,t,n)}:u:function defineProperty(e,t,n){if(a(e),t=s(t),a(n),r)try{return u(e,t,n)}catch(e){}if("get"in n||"set"in n)throw new l("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},4961:(e,t,n)=>{"use strict";var o=n(382),r=n(1807),i=n(7611),a=n(7738),s=n(5599),l=n(3815),u=n(5755),c=n(1799),d=Object.getOwnPropertyDescriptor;t.f=o?d:function getOwnPropertyDescriptor(e,t){if(e=s(e),t=l(t),c)try{return d(e,t)}catch(e){}if(u(e,t))return a(!r(i.f,e,t),e[t])}},2278:(e,t,n)=>{"use strict";var o=n(6742),r=n(4741).concat("length","prototype");t.f=Object.getOwnPropertyNames||function getOwnPropertyNames(e){return o(e,r)}},4347:(e,t)=>{"use strict";t.f=Object.getOwnPropertySymbols},4815:(e,t,n)=>{"use strict";var o=n(4762);e.exports=o({}.isPrototypeOf)},6742:(e,t,n)=>{"use strict";var o=n(4762),r=n(5755),i=n(5599),a=n(6651).indexOf,s=n(1507),l=o([].push);e.exports=function(e,t){var n,o=i(e),u=0,c=[];for(n in o)!r(s,n)&&r(o,n)&&l(c,n);for(;t.length>u;)r(o,n=t[u++])&&(~a(c,n)||l(c,n));return c}},7611:(e,t)=>{"use strict";var n={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,r=o&&!n.call({1:2},1);t.f=r?function propertyIsEnumerable(e){var t=o(this,e);return!!t&&t.enumerable}:n},348:(e,t,n)=>{"use strict";var o=n(1807),r=n(1483),i=n(1704),a=TypeError;e.exports=function(e,t){var n,s;if("string"===t&&r(n=e.toString)&&!i(s=o(n,e)))return s;if(r(n=e.valueOf)&&!i(s=o(n,e)))return s;if("string"!==t&&r(n=e.toString)&&!i(s=o(n,e)))return s;throw new a("Can't convert object to primitive value")}},9497:(e,t,n)=>{"use strict";var o=n(1409),r=n(4762),i=n(2278),a=n(4347),s=n(2293),l=r([].concat);e.exports=o("Reflect","ownKeys")||function ownKeys(e){var t=i.f(s(e)),n=a.f;return n?l(t,n(e)):t}},3312:(e,t,n)=>{"use strict";var o=n(5983),r=TypeError;e.exports=function(e){if(o(e))throw new r("Can't call method on "+e);return e}},5409:(e,t,n)=>{"use strict";var o=n(7255),r=n(1866),i=o("keys");e.exports=function(e){return i[e]||(i[e]=r(e))}},1831:(e,t,n)=>{"use strict";var o=n(9557),r=n(5578),i=n(2095),a="__core-js_shared__",s=e.exports=r[a]||i(a,{});(s.versions||(s.versions=[])).push({version:"3.38.1",mode:o?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE",source:"https://github.com/zloirock/core-js"})},7255:(e,t,n)=>{"use strict";var o=n(1831);e.exports=function(e,t){return o[e]||(o[e]=t||{})}},6029:(e,t,n)=>{"use strict";var o=n(6477),r=n(8473),i=n(5578).String;e.exports=!!Object.getOwnPropertySymbols&&!r((function(){var e=Symbol("symbol detection");return!i(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&o&&o<41}))},3392:(e,t,n)=>{"use strict";var o=n(3005),r=Math.max,i=Math.min;e.exports=function(e,t){var n=o(e);return n<0?r(n+t,0):i(n,t)}},5599:(e,t,n)=>{"use strict";var o=n(2121),r=n(3312);e.exports=function(e){return o(r(e))}},3005:(e,t,n)=>{"use strict";var o=n(1703);e.exports=function(e){var t=+e;return t!=t||0===t?0:o(t)}},8324:(e,t,n)=>{"use strict";var o=n(3005),r=Math.min;e.exports=function(e){var t=o(e);return t>0?r(t,9007199254740991):0}},2347:(e,t,n)=>{"use strict";var o=n(3312),r=Object;e.exports=function(e){return r(o(e))}},2355:(e,t,n)=>{"use strict";var o=n(1807),r=n(1704),i=n(1423),a=n(2564),s=n(348),l=n(1),u=TypeError,c=l("toPrimitive");e.exports=function(e,t){if(!r(e)||i(e))return e;var n,l=a(e,c);if(l){if(void 0===t&&(t="default"),n=o(l,e,t),!r(n)||i(n))return n;throw new u("Can't convert object to primitive value")}return void 0===t&&(t="number"),s(e,t)}},3815:(e,t,n)=>{"use strict";var o=n(2355),r=n(1423);e.exports=function(e){var t=o(e,"string");return r(t)?t:t+""}},8761:e=>{"use strict";var t=String;e.exports=function(e){try{return t(e)}catch(e){return"Object"}}},1866:(e,t,n)=>{"use strict";var o=n(4762),r=0,i=Math.random(),a=o(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+a(++r+i,36)}},5022:(e,t,n)=>{"use strict";var o=n(6029);e.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},3896:(e,t,n)=>{"use strict";var o=n(382),r=n(8473);e.exports=o&&r((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},4644:(e,t,n)=>{"use strict";var o=n(5578),r=n(1483),i=o.WeakMap;e.exports=r(i)&&/native code/.test(String(i))},1:(e,t,n)=>{"use strict";var o=n(5578),r=n(7255),i=n(5755),a=n(1866),s=n(6029),l=n(5022),u=o.Symbol,c=r("wks"),d=l?u.for||u:u&&u.withoutSetter||a;e.exports=function(e){return i(c,e)||(c[e]=s&&i(u,e)?u[e]:d("Symbol."+e)),c[e]}},5724:(e,t,n)=>{"use strict";var o=n(8612),r=n(2347),i=n(6960),a=n(9273),s=n(1091);o({target:"Array",proto:!0,arity:1,forced:n(8473)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function push(e){var t=r(this),n=i(t),o=arguments.length;s(n+o);for(var l=0;l{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{"use strict";var e=__webpack_require__(6784),t=e(__webpack_require__(2808)),n=e(__webpack_require__(1052));new t.default,new n.default})()})(); \ No newline at end of file diff --git a/assets/js/archive-posts.16a93245d08246e5e540.bundle.min.js b/assets/js/archive-posts.16a93245d08246e5e540.bundle.min.js new file mode 100644 index 00000000..3904d78a --- /dev/null +++ b/assets/js/archive-posts.16a93245d08246e5e540.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[345,396],{7907:(e,t,s)=>{var n=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(s(2195));t.default=o.default.extend({getSkinPrefix:()=>"cards_"})},2078:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class LoadMore extends elementorModules.frontend.handlers.Base{getDefaultSettings(){return{selectors:{postsContainer:".elementor-posts-container",postWrapperTag:"article",loadMoreButton:".elementor-button",loadMoreSpinnerWrapper:".e-load-more-spinner",loadMoreSpinner:".e-load-more-spinner i, .e-load-more-spinner svg",loadMoreAnchor:".e-load-more-anchor"},classes:{loadMoreSpin:"eicon-animation-spin",loadMoreIsLoading:"e-load-more-pagination-loading",loadMorePaginationEnd:"e-load-more-pagination-end",loadMoreNoSpinner:"e-load-more-no-spinner"}}}getDefaultElements(){const e=this.getSettings("selectors");return{postsWidgetWrapper:this.$element[0],postsContainer:this.$element[0].querySelector(e.postsContainer),loadMoreButton:this.$element[0].querySelector(e.loadMoreButton),loadMoreSpinnerWrapper:this.$element[0].querySelector(e.loadMoreSpinnerWrapper),loadMoreSpinner:this.$element[0].querySelector(e.loadMoreSpinner),loadMoreAnchor:this.$element[0].querySelector(e.loadMoreAnchor)}}bindEvents(){super.bindEvents(),this.elements.loadMoreButton&&this.elements.loadMoreButton.addEventListener("click",(e=>{this.isLoading||(e.preventDefault(),this.handlePostsQuery())}))}onInit(){super.onInit(),this.classes=this.getSettings("classes"),this.isLoading=!1;const e=this.getElementSettings("pagination_type");"load_more_on_click"!==e&&"load_more_infinite_scroll"!==e||(this.isInfinteScroll="load_more_infinite_scroll"===e,this.isSpinnerAvailable=this.getElementSettings("load_more_spinner").value,this.isSpinnerAvailable||this.elements.postsWidgetWrapper.classList.add(this.classes.loadMoreNoSpinner),this.isInfinteScroll?this.handleInfiniteScroll():this.elements.loadMoreSpinnerWrapper&&this.elements.loadMoreButton&&this.elements.loadMoreButton.insertAdjacentElement("beforeEnd",this.elements.loadMoreSpinnerWrapper),this.elementId=this.getID(),this.postId=elementorFrontendConfig.post.id,this.elements.loadMoreAnchor&&(this.currentPage=parseInt(this.elements.loadMoreAnchor.getAttribute("data-page")),this.maxPage=parseInt(this.elements.loadMoreAnchor.getAttribute("data-max-page")),this.currentPage!==this.maxPage&&this.currentPage||this.handleUiWhenNoPosts()))}handleInfiniteScroll(){this.isEdit||(this.observer=elementorModules.utils.Scroll.scrollObserver({callback:e=>{e.isInViewport&&!this.isLoading&&(this.observer.unobserve(this.elements.loadMoreAnchor),this.handlePostsQuery().then((()=>{this.currentPage!==this.maxPage&&this.observer.observe(this.elements.loadMoreAnchor)})))}}),this.observer.observe(this.elements.loadMoreAnchor))}handleUiBeforeLoading(){this.isLoading=!0,this.elements.loadMoreSpinner&&this.elements.loadMoreSpinner.classList.add(this.classes.loadMoreSpin),this.elements.postsWidgetWrapper.classList.add(this.classes.loadMoreIsLoading)}handleUiAfterLoading(){this.isLoading=!1,this.elements.loadMoreSpinner&&this.elements.loadMoreSpinner.classList.remove(this.classes.loadMoreSpin),this.isInfinteScroll&&this.elements.loadMoreSpinnerWrapper&&this.elements.loadMoreAnchor&&this.elements.loadMoreAnchor.insertAdjacentElement("afterend",this.elements.loadMoreSpinnerWrapper),this.elements.postsWidgetWrapper.classList.remove(this.classes.loadMoreIsLoading)}handleUiWhenNoPosts(){this.elements.postsWidgetWrapper.classList.add(this.classes.loadMorePaginationEnd)}afterInsertPosts(){}handleSuccessFetch(e){this.handleUiAfterLoading();const t=this.getSettings("selectors"),s=e.querySelectorAll(`[data-id="${this.elementId}"] ${t.postsContainer} > ${t.postWrapperTag}`),n=e.querySelector(`[data-id="${this.elementId}"] .e-load-more-anchor`).getAttribute("data-next-page");s.forEach((e=>this.elements.postsContainer.append(e))),this.elements.loadMoreAnchor.setAttribute("data-page",this.currentPage),this.elements.loadMoreAnchor.setAttribute("data-next-page",n),this.currentPage===this.maxPage&&this.handleUiWhenNoPosts(),this.afterInsertPosts(s,e)}handlePostsQuery(){this.handleUiBeforeLoading(),this.currentPage++;const e=this.elements.loadMoreAnchor.getAttribute("data-next-page");return fetch(e).then((e=>e.text())).then((e=>{const t=(new DOMParser).parseFromString(e,"text/html");this.handleSuccessFetch(t)}))}}t.default=LoadMore},2195:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default=elementorModules.frontend.handlers.Base.extend({getSkinPrefix:()=>"classic_",bindEvents(){elementorFrontend.addListenerOnce(this.getModelCID(),"resize",this.onWindowResize)},unbindEvents(){elementorFrontend.removeListeners(this.getModelCID(),"resize",this.onWindowResize)},getClosureMethodsNames(){return elementorModules.frontend.handlers.Base.prototype.getClosureMethodsNames.apply(this,arguments).concat(["fitImages","onWindowResize","runMasonry"])},getDefaultSettings:()=>({classes:{fitHeight:"elementor-fit-height",hasItemRatio:"elementor-has-item-ratio"},selectors:{postsContainer:".elementor-posts-container",post:".elementor-post",postThumbnail:".elementor-post__thumbnail",postThumbnailImage:".elementor-post__thumbnail img"}}),getDefaultElements(){var e=this.getSettings("selectors");return{$postsContainer:this.$element.find(e.postsContainer),$posts:this.$element.find(e.post)}},fitImage(e){var t=this.getSettings(),s=e.find(t.selectors.postThumbnail),n=s.find("img")[0];if(n){var o=s.outerHeight()/s.outerWidth(),i=n.naturalHeight/n.naturalWidth;s.toggleClass(t.classes.fitHeight,i=2;if(e.$postsContainer.toggleClass("elementor-posts-masonry",s),!s)return void e.$postsContainer.height("");const n=this.getVerticalSpaceBetween();new elementorModules.utils.Masonry({container:e.$postsContainer,items:e.$posts.filter(":visible"),columnsCount:this.getSettings("colsCount"),verticalSpaceBetween:n||0}).run()},run(){setTimeout(this.fitImages,0),this.initMasonry()},onInit(){elementorModules.frontend.handlers.Base.prototype.onInit.apply(this,arguments),this.bindEvents(),this.run()},onWindowResize(){this.fitImages(),this.runMasonry()},onElementChange(){this.fitImages(),setTimeout(this.runMasonry)}})},439:(e,t,s)=>{var n=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(s(2078));class ArchivePostsLoadMore extends o.default{}t.default=ArchivePostsLoadMore},2718:(e,t,s)=>{var n=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(s(7907));t.default=o.default.extend({getSkinPrefix:()=>"archive_cards_"})},6629:(e,t,s)=>{var n=s(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(s(2195));t.default=o.default.extend({getSkinPrefix:()=>"archive_classic_"})}}]); \ No newline at end of file diff --git a/assets/js/archive-posts.6e398ddd4a81a78bcea3.bundle.js b/assets/js/archive-posts.6e398ddd4a81a78bcea3.bundle.js new file mode 100644 index 00000000..14e2a522 --- /dev/null +++ b/assets/js/archive-posts.6e398ddd4a81a78bcea3.bundle.js @@ -0,0 +1,401 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["archive-posts"],{ + +/***/ "../modules/posts/assets/js/frontend/handlers/cards.js": +/*!*************************************************************!*\ + !*** ../modules/posts/assets/js/frontend/handlers/cards.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _posts = _interopRequireDefault(__webpack_require__(/*! ./posts */ "../modules/posts/assets/js/frontend/handlers/posts.js")); +var _default = exports["default"] = _posts.default.extend({ + getSkinPrefix() { + return 'cards_'; + } +}); + +/***/ }), + +/***/ "../modules/posts/assets/js/frontend/handlers/load-more.js": +/*!*****************************************************************!*\ + !*** ../modules/posts/assets/js/frontend/handlers/load-more.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class LoadMore extends elementorModules.frontend.handlers.Base { + getDefaultSettings() { + return { + selectors: { + postsContainer: '.elementor-posts-container', + postWrapperTag: 'article', + loadMoreButton: '.elementor-button', + loadMoreSpinnerWrapper: '.e-load-more-spinner', + loadMoreSpinner: '.e-load-more-spinner i, .e-load-more-spinner svg', + loadMoreAnchor: '.e-load-more-anchor' + }, + classes: { + loadMoreSpin: 'eicon-animation-spin', + loadMoreIsLoading: 'e-load-more-pagination-loading', + loadMorePaginationEnd: 'e-load-more-pagination-end', + loadMoreNoSpinner: 'e-load-more-no-spinner' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + postsWidgetWrapper: this.$element[0], + postsContainer: this.$element[0].querySelector(selectors.postsContainer), + loadMoreButton: this.$element[0].querySelector(selectors.loadMoreButton), + loadMoreSpinnerWrapper: this.$element[0].querySelector(selectors.loadMoreSpinnerWrapper), + loadMoreSpinner: this.$element[0].querySelector(selectors.loadMoreSpinner), + loadMoreAnchor: this.$element[0].querySelector(selectors.loadMoreAnchor) + }; + } + bindEvents() { + super.bindEvents(); + + // Handle load more functionality for on-click type. + if (!this.elements.loadMoreButton) { + return; + } + this.elements.loadMoreButton.addEventListener('click', event => { + if (this.isLoading) { + return; + } + event.preventDefault(); + this.handlePostsQuery(); + }); + } + onInit() { + super.onInit(); + this.classes = this.getSettings('classes'); + this.isLoading = false; + const paginationType = this.getElementSettings('pagination_type'); + if ('load_more_on_click' !== paginationType && 'load_more_infinite_scroll' !== paginationType) { + return; + } + this.isInfinteScroll = 'load_more_infinite_scroll' === paginationType; + + // When spinner is not available, the button's text should not be hidden. + this.isSpinnerAvailable = this.getElementSettings('load_more_spinner').value; + if (!this.isSpinnerAvailable) { + this.elements.postsWidgetWrapper.classList.add(this.classes.loadMoreNoSpinner); + } + if (this.isInfinteScroll) { + this.handleInfiniteScroll(); + } else if (this.elements.loadMoreSpinnerWrapper && this.elements.loadMoreButton) { + // Instead of creating 2 spinners for on-click and infinity-scroll, one spinner will be used so it should be appended to the button in on-click mode. + this.elements.loadMoreButton.insertAdjacentElement('beforeEnd', this.elements.loadMoreSpinnerWrapper); + } + + // Set the post id and element id for the ajax request. + this.elementId = this.getID(); + this.postId = elementorFrontendConfig.post.id; + + // Set the current page and last page for handling the load more post and when no more posts to show. + if (this.elements.loadMoreAnchor) { + this.currentPage = parseInt(this.elements.loadMoreAnchor.getAttribute('data-page')); + this.maxPage = parseInt(this.elements.loadMoreAnchor.getAttribute('data-max-page')); + if (this.currentPage === this.maxPage || !this.currentPage) { + this.handleUiWhenNoPosts(); + } + } + } + + // Handle load more functionality for infinity-scroll type. + handleInfiniteScroll() { + if (this.isEdit) { + return; + } + this.observer = elementorModules.utils.Scroll.scrollObserver({ + callback: event => { + if (!event.isInViewport || this.isLoading) { + return; + } + + // When the observer is triggered it won't be triggered without scrolling, but sometimes there will be no scrollbar to trigger it again. + this.observer.unobserve(this.elements.loadMoreAnchor); + this.handlePostsQuery().then(() => { + if (this.currentPage !== this.maxPage) { + this.observer.observe(this.elements.loadMoreAnchor); + } + }); + } + }); + this.observer.observe(this.elements.loadMoreAnchor); + } + handleUiBeforeLoading() { + this.isLoading = true; + if (this.elements.loadMoreSpinner) { + this.elements.loadMoreSpinner.classList.add(this.classes.loadMoreSpin); + } + this.elements.postsWidgetWrapper.classList.add(this.classes.loadMoreIsLoading); + } + handleUiAfterLoading() { + this.isLoading = false; + if (this.elements.loadMoreSpinner) { + this.elements.loadMoreSpinner.classList.remove(this.classes.loadMoreSpin); + } + if (this.isInfinteScroll && this.elements.loadMoreSpinnerWrapper && this.elements.loadMoreAnchor) { + // Since the spinner has to be shown after the new content (posts), it should be appended after the anchor element. + this.elements.loadMoreAnchor.insertAdjacentElement('afterend', this.elements.loadMoreSpinnerWrapper); + } + this.elements.postsWidgetWrapper.classList.remove(this.classes.loadMoreIsLoading); + } + handleUiWhenNoPosts() { + this.elements.postsWidgetWrapper.classList.add(this.classes.loadMorePaginationEnd); + } + afterInsertPosts() {} + handleSuccessFetch(result) { + this.handleUiAfterLoading(); + const selectors = this.getSettings('selectors'); + + // Grabbing only the new articles from the response without the existing ones (prevent posts duplication). + const postsElements = result.querySelectorAll(`[data-id="${this.elementId}"] ${selectors.postsContainer} > ${selectors.postWrapperTag}`); + const nextPageUrl = result.querySelector(`[data-id="${this.elementId}"] .e-load-more-anchor`).getAttribute('data-next-page'); + postsElements.forEach(element => this.elements.postsContainer.append(element)); + this.elements.loadMoreAnchor.setAttribute('data-page', this.currentPage); + this.elements.loadMoreAnchor.setAttribute('data-next-page', nextPageUrl); + if (this.currentPage === this.maxPage) { + this.handleUiWhenNoPosts(); + } + this.afterInsertPosts(postsElements, result); + } + handlePostsQuery() { + this.handleUiBeforeLoading(); + this.currentPage++; + const nextPageUrl = this.elements.loadMoreAnchor.getAttribute('data-next-page'); + return fetch(nextPageUrl).then(response => response.text()).then(html => { + // Convert the HTML string into a document object + const parser = new DOMParser(); + const doc = parser.parseFromString(html, 'text/html'); + this.handleSuccessFetch(doc); + }); + } +} +exports["default"] = LoadMore; + +/***/ }), + +/***/ "../modules/posts/assets/js/frontend/handlers/posts.js": +/*!*************************************************************!*\ + !*** ../modules/posts/assets/js/frontend/handlers/posts.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = exports["default"] = elementorModules.frontend.handlers.Base.extend({ + getSkinPrefix() { + return 'classic_'; + }, + bindEvents() { + elementorFrontend.addListenerOnce(this.getModelCID(), 'resize', this.onWindowResize); + }, + unbindEvents() { + elementorFrontend.removeListeners(this.getModelCID(), 'resize', this.onWindowResize); + }, + getClosureMethodsNames() { + return elementorModules.frontend.handlers.Base.prototype.getClosureMethodsNames.apply(this, arguments).concat(['fitImages', 'onWindowResize', 'runMasonry']); + }, + getDefaultSettings() { + return { + classes: { + fitHeight: 'elementor-fit-height', + hasItemRatio: 'elementor-has-item-ratio' + }, + selectors: { + postsContainer: '.elementor-posts-container', + post: '.elementor-post', + postThumbnail: '.elementor-post__thumbnail', + postThumbnailImage: '.elementor-post__thumbnail img' + } + }; + }, + getDefaultElements() { + var selectors = this.getSettings('selectors'); + return { + $postsContainer: this.$element.find(selectors.postsContainer), + $posts: this.$element.find(selectors.post) + }; + }, + fitImage($post) { + var settings = this.getSettings(), + $imageParent = $post.find(settings.selectors.postThumbnail), + $image = $imageParent.find('img'), + image = $image[0]; + if (!image) { + return; + } + var imageParentRatio = $imageParent.outerHeight() / $imageParent.outerWidth(), + imageRatio = image.naturalHeight / image.naturalWidth; + $imageParent.toggleClass(settings.classes.fitHeight, imageRatio < imageParentRatio); + }, + fitImages() { + var $ = jQuery, + self = this, + itemRatio = getComputedStyle(this.$element[0], ':after').content, + settings = this.getSettings(); + if (self.isMasonryEnabled()) { + this.elements.$postsContainer.removeClass(settings.classes.hasItemRatio); + return; + } + this.elements.$postsContainer.toggleClass(settings.classes.hasItemRatio, !!itemRatio.match(/\d/)); + this.elements.$posts.each(function () { + var $post = $(this), + $image = $post.find(settings.selectors.postThumbnailImage); + self.fitImage($post); + $image.on('load', function () { + self.fitImage($post); + }); + }); + }, + setColsCountSettings() { + const settings = this.getElementSettings(), + skinPrefix = this.getSkinPrefix(), + colsCount = elementorProFrontend.utils.controls.getResponsiveControlValue(settings, `${skinPrefix}columns`); + this.setSettings('colsCount', colsCount); + }, + isMasonryEnabled() { + return !!this.getElementSettings(this.getSkinPrefix() + 'masonry'); + }, + initMasonry() { + imagesLoaded(this.elements.$posts, this.runMasonry); + }, + getVerticalSpaceBetween() { + /* The `verticalSpaceBetween` variable is set up in a way that supports older versions of the portfolio widget */ + let verticalSpaceBetween = elementorProFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(), `${this.getSkinPrefix()}row_gap`, 'size'); + if ('' === this.getSkinPrefix() && '' === verticalSpaceBetween) { + verticalSpaceBetween = this.getElementSettings('item_gap.size'); + } + return verticalSpaceBetween; + }, + runMasonry() { + var elements = this.elements; + elements.$posts.css({ + marginTop: '', + transitionDuration: '' + }); + this.setColsCountSettings(); + var colsCount = this.getSettings('colsCount'), + hasMasonry = this.isMasonryEnabled() && colsCount >= 2; + elements.$postsContainer.toggleClass('elementor-posts-masonry', hasMasonry); + if (!hasMasonry) { + elements.$postsContainer.height(''); + return; + } + const verticalSpaceBetween = this.getVerticalSpaceBetween(); + var masonry = new elementorModules.utils.Masonry({ + container: elements.$postsContainer, + items: elements.$posts.filter(':visible'), + columnsCount: this.getSettings('colsCount'), + verticalSpaceBetween: verticalSpaceBetween || 0 + }); + masonry.run(); + }, + run() { + // For slow browsers + setTimeout(this.fitImages, 0); + this.initMasonry(); + }, + onInit() { + elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments); + this.bindEvents(); + this.run(); + }, + onWindowResize() { + this.fitImages(); + this.runMasonry(); + }, + onElementChange() { + this.fitImages(); + setTimeout(this.runMasonry); + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/frontend/handlers/archive-posts-load-more.js": +/*!***************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/frontend/handlers/archive-posts-load-more.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _loadMore = _interopRequireDefault(__webpack_require__(/*! ../../../../../posts/assets/js/frontend/handlers/load-more */ "../modules/posts/assets/js/frontend/handlers/load-more.js")); +class ArchivePostsLoadMore extends _loadMore.default {} +exports["default"] = ArchivePostsLoadMore; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/frontend/handlers/archive-posts-skin-cards.js": +/*!****************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/frontend/handlers/archive-posts-skin-cards.js ***! + \****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _cards = _interopRequireDefault(__webpack_require__(/*! ../../../../../posts/assets/js/frontend/handlers/cards */ "../modules/posts/assets/js/frontend/handlers/cards.js")); +var _default = exports["default"] = _cards.default.extend({ + getSkinPrefix() { + return 'archive_cards_'; + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/frontend/handlers/archive-posts-skin-classic.js": +/*!******************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/frontend/handlers/archive-posts-skin-classic.js ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _posts = _interopRequireDefault(__webpack_require__(/*! modules/posts/assets/js/frontend/handlers/posts */ "../modules/posts/assets/js/frontend/handlers/posts.js")); +var _default = exports["default"] = _posts.default.extend({ + getSkinPrefix() { + return 'archive_classic_'; + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=archive-posts.6e398ddd4a81a78bcea3.bundle.js.map \ No newline at end of file diff --git a/assets/js/carousel.298f1fc9c115422aad0e.bundle.js b/assets/js/carousel.298f1fc9c115422aad0e.bundle.js new file mode 100644 index 00000000..4a70ebdd --- /dev/null +++ b/assets/js/carousel.298f1fc9c115422aad0e.bundle.js @@ -0,0 +1,294 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["carousel"],{ + +/***/ "../modules/carousel/assets/js/frontend/handlers/base.js": +/*!***************************************************************!*\ + !*** ../modules/carousel/assets/js/frontend/handlers/base.js ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class CarouselBase extends elementorModules.frontend.handlers.SwiperBase { + getDefaultSettings() { + return { + selectors: { + swiperContainer: '.elementor-main-swiper', + swiperSlide: '.swiper-slide' + }, + slidesPerView: { + widescreen: 3, + desktop: 3, + laptop: 3, + tablet_extra: 3, + tablet: 2, + mobile_extra: 2, + mobile: 1 + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'), + elements = { + $swiperContainer: this.$element.find(selectors.swiperContainer) + }; + elements.$slides = elements.$swiperContainer.find(selectors.swiperSlide); + return elements; + } + getEffect() { + return this.getElementSettings('effect'); + } + getDeviceSlidesPerView(device) { + const slidesPerViewKey = 'slides_per_view' + ('desktop' === device ? '' : '_' + device); + return Math.min(this.getSlidesCount(), +this.getElementSettings(slidesPerViewKey) || this.getSettings('slidesPerView')[device]); + } + getSlidesPerView(device) { + if ('slide' === this.getEffect()) { + return this.getDeviceSlidesPerView(device); + } + return 1; + } + getDeviceSlidesToScroll(device) { + const slidesToScrollKey = 'slides_to_scroll' + ('desktop' === device ? '' : '_' + device); + return Math.min(this.getSlidesCount(), +this.getElementSettings(slidesToScrollKey) || 1); + } + getSlidesToScroll(device) { + if ('slide' === this.getEffect()) { + return this.getDeviceSlidesToScroll(device); + } + return 1; + } + getSpaceBetween(device) { + let propertyName = 'space_between'; + if (device && 'desktop' !== device) { + propertyName += '_' + device; + } + return this.getElementSettings(propertyName).size || 0; + } + getSwiperOptions() { + const elementSettings = this.getElementSettings(); + const swiperOptions = { + grabCursor: true, + initialSlide: this.getInitialSlide(), + slidesPerView: this.getSlidesPerView('desktop'), + slidesPerGroup: this.getSlidesToScroll('desktop'), + spaceBetween: this.getSpaceBetween(), + loop: 'yes' === elementSettings.loop, + speed: elementSettings.speed, + effect: this.getEffect(), + preventClicksPropagation: false, + slideToClickedSlide: true, + handleElementorBreakpoints: true + }; + if ('yes' === elementSettings.lazyload) { + swiperOptions.lazy = { + loadPrevNext: true, + loadPrevNextAmount: 1 + }; + } + if (elementSettings.show_arrows) { + swiperOptions.navigation = { + prevEl: '.elementor-swiper-button-prev', + nextEl: '.elementor-swiper-button-next' + }; + } + if (elementSettings.pagination) { + swiperOptions.pagination = { + el: '.swiper-pagination', + type: elementSettings.pagination, + clickable: true + }; + } + if ('cube' !== this.getEffect()) { + const breakpointsSettings = {}, + breakpoints = elementorFrontend.config.responsive.activeBreakpoints; + Object.keys(breakpoints).forEach(breakpointName => { + breakpointsSettings[breakpoints[breakpointName].value] = { + slidesPerView: this.getSlidesPerView(breakpointName), + slidesPerGroup: this.getSlidesToScroll(breakpointName), + spaceBetween: this.getSpaceBetween(breakpointName) + }; + }); + swiperOptions.breakpoints = breakpointsSettings; + } + if (!this.isEdit && elementSettings.autoplay) { + swiperOptions.autoplay = { + delay: elementSettings.autoplay_speed, + disableOnInteraction: !!elementSettings.pause_on_interaction + }; + } + return swiperOptions; + } + getDeviceBreakpointValue(device) { + if (!this.breakpointsDictionary) { + const breakpoints = elementorFrontend.config.responsive.activeBreakpoints; + this.breakpointsDictionary = {}; + Object.keys(breakpoints).forEach(breakpointName => { + this.breakpointsDictionary[breakpointName] = breakpoints[breakpointName].value; + }); + } + return this.breakpointsDictionary[device]; + } + updateSpaceBetween(propertyName) { + const deviceMatch = propertyName.match('space_between_(.*)'), + device = deviceMatch ? deviceMatch[1] : 'desktop', + newSpaceBetween = this.getSpaceBetween(device); + if ('desktop' !== device) { + this.swiper.params.breakpoints[this.getDeviceBreakpointValue(device)].spaceBetween = newSpaceBetween; + } else { + this.swiper.params.spaceBetween = newSpaceBetween; + } + this.swiper.params.spaceBetween = newSpaceBetween; + this.swiper.update(); + } + async onInit() { + elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments); + if (1 >= this.getSlidesCount()) { + return; + } + const Swiper = elementorFrontend.utils.swiper; + this.swiper = await new Swiper(this.elements.$swiperContainer, this.getSwiperOptions()); + const elementSettings = this.getElementSettings(); + if ('yes' === elementSettings.pause_on_hover) { + this.togglePauseOnHover(true); + } + + // Expose the swiper instance in the frontend + this.elements.$swiperContainer.data('swiper', this.swiper); + } + getChangeableProperties() { + return { + autoplay: 'autoplay', + pause_on_hover: 'pauseOnHover', + pause_on_interaction: 'disableOnInteraction', + autoplay_speed: 'delay', + speed: 'speed', + width: 'width' + }; + } + updateSwiperOption(propertyName) { + if (0 === propertyName.indexOf('width')) { + this.swiper.update(); + return; + } + const elementSettings = this.getElementSettings(), + newSettingValue = elementSettings[propertyName], + changeableProperties = this.getChangeableProperties(); + let propertyToUpdate = changeableProperties[propertyName], + valueToUpdate = newSettingValue; + + // Handle special cases where the value to update is not the value that the Swiper library accepts + switch (propertyName) { + case 'autoplay': + if (newSettingValue) { + valueToUpdate = { + delay: elementSettings.autoplay_speed, + disableOnInteraction: 'yes' === elementSettings.pause_on_interaction + }; + } else { + valueToUpdate = false; + } + break; + case 'autoplay_speed': + propertyToUpdate = 'autoplay'; + valueToUpdate = { + delay: newSettingValue, + disableOnInteraction: 'yes' === elementSettings.pause_on_interaction + }; + break; + case 'pause_on_hover': + this.togglePauseOnHover('yes' === newSettingValue); + break; + case 'pause_on_interaction': + valueToUpdate = 'yes' === newSettingValue; + break; + } + + // 'pause_on_hover' is implemented by the handler with event listeners, not the Swiper library + if ('pause_on_hover' !== propertyName) { + this.swiper.params[propertyToUpdate] = valueToUpdate; + } + this.swiper.update(); + } + onElementChange(propertyName) { + if (1 >= this.getSlidesCount()) { + return; + } + if (0 === propertyName.indexOf('width')) { + this.swiper.update(); + + // If there is another thumbs slider, like in the Media Carousel widget. + if (this.thumbsSwiper) { + this.thumbsSwiper.update(); + } + return; + } + + // This is for handling the responsive control 'space_between'. + // Responsive controls require a separate way of handling, and some currently don't work + // (Swiper bug, currently exists in v5.3.6) TODO: update Swiper when bug is fixed and handle responsive controls + if (0 === propertyName.indexOf('space_between')) { + this.updateSpaceBetween(propertyName); + return; + } + const changeableProperties = this.getChangeableProperties(); + if (Object.prototype.hasOwnProperty.call(changeableProperties, propertyName)) { + this.updateSwiperOption(propertyName); + } + } + onEditSettingsChange(propertyName) { + if (1 >= this.getSlidesCount()) { + return; + } + if ('activeItemIndex' === propertyName) { + this.swiper.slideToLoop(this.getEditSettings('activeItemIndex') - 1); + } + } +} +exports["default"] = CarouselBase; + +/***/ }), + +/***/ "../modules/carousel/assets/js/frontend/handlers/testimonial-carousel.js": +/*!*******************************************************************************!*\ + !*** ../modules/carousel/assets/js/frontend/handlers/testimonial-carousel.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! ./base */ "../modules/carousel/assets/js/frontend/handlers/base.js")); +class TestimonialCarousel extends _base.default { + getDefaultSettings() { + const defaultSettings = super.getDefaultSettings(); + defaultSettings.slidesPerView = { + desktop: 1 + }; + Object.keys(elementorFrontend.config.responsive.activeBreakpoints).forEach(breakpointName => { + defaultSettings.slidesPerView[breakpointName] = 1; + }); + if (defaultSettings.loop) { + defaultSettings.loopedSlides = this.getSlidesCount(); + } + return defaultSettings; + } + getEffect() { + return 'slide'; + } +} +exports["default"] = TestimonialCarousel; + +/***/ }) + +}]); +//# sourceMappingURL=carousel.298f1fc9c115422aad0e.bundle.js.map \ No newline at end of file diff --git a/assets/js/carousel.3620fca501cb18163600.bundle.min.js b/assets/js/carousel.3620fca501cb18163600.bundle.min.js new file mode 100644 index 00000000..a66240d0 --- /dev/null +++ b/assets/js/carousel.3620fca501cb18163600.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[897],{5456:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class CarouselBase extends elementorModules.frontend.handlers.SwiperBase{getDefaultSettings(){return{selectors:{swiperContainer:".elementor-main-swiper",swiperSlide:".swiper-slide"},slidesPerView:{widescreen:3,desktop:3,laptop:3,tablet_extra:3,tablet:2,mobile_extra:2,mobile:1}}}getDefaultElements(){const e=this.getSettings("selectors"),t={$swiperContainer:this.$element.find(e.swiperContainer)};return t.$slides=t.$swiperContainer.find(e.swiperSlide),t}getEffect(){return this.getElementSettings("effect")}getDeviceSlidesPerView(e){const t="slides_per_view"+("desktop"===e?"":"_"+e);return Math.min(this.getSlidesCount(),+this.getElementSettings(t)||this.getSettings("slidesPerView")[e])}getSlidesPerView(e){return"slide"===this.getEffect()?this.getDeviceSlidesPerView(e):1}getDeviceSlidesToScroll(e){const t="slides_to_scroll"+("desktop"===e?"":"_"+e);return Math.min(this.getSlidesCount(),+this.getElementSettings(t)||1)}getSlidesToScroll(e){return"slide"===this.getEffect()?this.getDeviceSlidesToScroll(e):1}getSpaceBetween(e){let t="space_between";return e&&"desktop"!==e&&(t+="_"+e),this.getElementSettings(t).size||0}getSwiperOptions(){const e=this.getElementSettings(),t={grabCursor:!0,initialSlide:this.getInitialSlide(),slidesPerView:this.getSlidesPerView("desktop"),slidesPerGroup:this.getSlidesToScroll("desktop"),spaceBetween:this.getSpaceBetween(),loop:"yes"===e.loop,speed:e.speed,effect:this.getEffect(),preventClicksPropagation:!1,slideToClickedSlide:!0,handleElementorBreakpoints:!0};if("yes"===e.lazyload&&(t.lazy={loadPrevNext:!0,loadPrevNextAmount:1}),e.show_arrows&&(t.navigation={prevEl:".elementor-swiper-button-prev",nextEl:".elementor-swiper-button-next"}),e.pagination&&(t.pagination={el:".swiper-pagination",type:e.pagination,clickable:!0}),"cube"!==this.getEffect()){const e={},i=elementorFrontend.config.responsive.activeBreakpoints;Object.keys(i).forEach((t=>{e[i[t].value]={slidesPerView:this.getSlidesPerView(t),slidesPerGroup:this.getSlidesToScroll(t),spaceBetween:this.getSpaceBetween(t)}})),t.breakpoints=e}return!this.isEdit&&e.autoplay&&(t.autoplay={delay:e.autoplay_speed,disableOnInteraction:!!e.pause_on_interaction}),t}getDeviceBreakpointValue(e){if(!this.breakpointsDictionary){const e=elementorFrontend.config.responsive.activeBreakpoints;this.breakpointsDictionary={},Object.keys(e).forEach((t=>{this.breakpointsDictionary[t]=e[t].value}))}return this.breakpointsDictionary[e]}updateSpaceBetween(e){const t=e.match("space_between_(.*)"),i=t?t[1]:"desktop",s=this.getSpaceBetween(i);"desktop"!==i?this.swiper.params.breakpoints[this.getDeviceBreakpointValue(i)].spaceBetween=s:this.swiper.params.spaceBetween=s,this.swiper.params.spaceBetween=s,this.swiper.update()}async onInit(){if(elementorModules.frontend.handlers.Base.prototype.onInit.apply(this,arguments),1>=this.getSlidesCount())return;const e=elementorFrontend.utils.swiper;this.swiper=await new e(this.elements.$swiperContainer,this.getSwiperOptions());"yes"===this.getElementSettings().pause_on_hover&&this.togglePauseOnHover(!0),this.elements.$swiperContainer.data("swiper",this.swiper)}getChangeableProperties(){return{autoplay:"autoplay",pause_on_hover:"pauseOnHover",pause_on_interaction:"disableOnInteraction",autoplay_speed:"delay",speed:"speed",width:"width"}}updateSwiperOption(e){if(0===e.indexOf("width"))return void this.swiper.update();const t=this.getElementSettings(),i=t[e];let s=this.getChangeableProperties()[e],n=i;switch(e){case"autoplay":n=!!i&&{delay:t.autoplay_speed,disableOnInteraction:"yes"===t.pause_on_interaction};break;case"autoplay_speed":s="autoplay",n={delay:i,disableOnInteraction:"yes"===t.pause_on_interaction};break;case"pause_on_hover":this.togglePauseOnHover("yes"===i);break;case"pause_on_interaction":n="yes"===i}"pause_on_hover"!==e&&(this.swiper.params[s]=n),this.swiper.update()}onElementChange(e){if(1>=this.getSlidesCount())return;if(0===e.indexOf("width"))return this.swiper.update(),void(this.thumbsSwiper&&this.thumbsSwiper.update());if(0===e.indexOf("space_between"))return void this.updateSpaceBetween(e);const t=this.getChangeableProperties();Object.prototype.hasOwnProperty.call(t,e)&&this.updateSwiperOption(e)}onEditSettingsChange(e){1>=this.getSlidesCount()||"activeItemIndex"===e&&this.swiper.slideToLoop(this.getEditSettings("activeItemIndex")-1)}}t.default=CarouselBase},7181:(e,t,i)=>{var s=i(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=s(i(5456));class TestimonialCarousel extends n.default{getDefaultSettings(){const e=super.getDefaultSettings();return e.slidesPerView={desktop:1},Object.keys(elementorFrontend.config.responsive.activeBreakpoints).forEach((t=>{e.slidesPerView[t]=1})),e.loop&&(e.loopedSlides=this.getSlidesCount()),e}getEffect(){return"slide"}}t.default=TestimonialCarousel}}]); \ No newline at end of file diff --git a/assets/js/code-highlight.7121ad6fca6bf899bbb5.bundle.js b/assets/js/code-highlight.7121ad6fca6bf899bbb5.bundle.js new file mode 100644 index 00000000..3e2a09d6 --- /dev/null +++ b/assets/js/code-highlight.7121ad6fca6bf899bbb5.bundle.js @@ -0,0 +1,32 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["code-highlight"],{ + +/***/ "../modules/code-highlight/assets/js/frontend/handler.js": +/*!***************************************************************!*\ + !*** ../modules/code-highlight/assets/js/frontend/handler.js ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class codeHighlightHandler extends elementorModules.frontend.handlers.Base { + onInit(...args) { + super.onInit(...args); + Prism.highlightAllUnder(this.$element[0], false); + } + onElementChange() { + // Handle the changes for "Word Wrap" feature + Prism.highlightAllUnder(this.$element[0], false); + } +} +exports["default"] = codeHighlightHandler; + +/***/ }) + +}]); +//# sourceMappingURL=code-highlight.7121ad6fca6bf899bbb5.bundle.js.map \ No newline at end of file diff --git a/assets/js/code-highlight.b9addbc842a50347c9ab.bundle.min.js b/assets/js/code-highlight.b9addbc842a50347c9ab.bundle.min.js new file mode 100644 index 00000000..1ef82f45 --- /dev/null +++ b/assets/js/code-highlight.b9addbc842a50347c9ab.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[635],{7193:(e,l)=>{Object.defineProperty(l,"__esModule",{value:!0}),l.default=void 0;class codeHighlightHandler extends elementorModules.frontend.handlers.Base{onInit(...e){super.onInit(...e),Prism.highlightAllUnder(this.$element[0],!1)}onElementChange(){Prism.highlightAllUnder(this.$element[0],!1)}}l.default=codeHighlightHandler}}]); \ No newline at end of file diff --git a/assets/js/contact-buttons-var-10.16cf733dc3d3b250fef4.bundle.min.js b/assets/js/contact-buttons-var-10.16cf733dc3d3b250fef4.bundle.min.js new file mode 100644 index 00000000..be843f7c --- /dev/null +++ b/assets/js/contact-buttons-var-10.16cf733dc3d3b250fef4.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[61],{7263:(t,e,n)=>{var s=n(6784);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i=s(n(8562)),o=s(n(8243));class ContactButtonsv10Handler extends i.default{getDefaultSettings(){return{selectors:{main:".e-contact-buttons-var-10",links:".e-contact-buttons__contact-icon-link"},constants:{active:"active"}}}getDefaultElements(){const t=this.getSettings("selectors");return{main:this.$element[0].querySelector(t.main),links:this.$element[0].querySelectorAll(t.links)}}isMobileDevice(){return["mobile","mobile_extra"].includes(elementorFrontend.getCurrentDeviceMode())}handleLinkClick(t){t.preventDefault();const{active:e}=this.getSettings("constants");if(t.currentTarget.classList.contains(e)){const n=t.currentTarget.getAttribute("href"),s=t.currentTarget.getAttribute("target");s?window.open(n,s):n&&(window.location.href=n),t.currentTarget.classList.remove(e)}else this.closeAllLinks(),t.currentTarget.classList.add(e)}closeAllLinks(){const{active:t}=this.getSettings("constants");this.elements.links.forEach((e=>e.classList.remove(t)))}linksEventListeners(){this.elements.links.length&&this.isMobileDevice()&&(this.elements.links.forEach((t=>{t.addEventListener("click",(t=>{this.handleLinkClick(t)}))})),document.addEventListener("click",(t=>{this.elements.main.contains(t.target)||this.closeAllLinks()})))}bindEvents(){this.linksEventListeners()}setupInnerContainer(){this.elements.main.closest(".e-con-inner").classList.add("e-con-inner--floating-buttons")}onInit(...t){super.onInit(...t),this.clickTrackingHandler=new o.default({$element:this.$element}),this.setupInnerContainer()}}e.default=ContactButtonsv10Handler},8243:(t,e,n)=>{var s=n(6784);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i=s(n(8562));class ClickTrackingHandler extends i.default{clicks=[];getDefaultSettings(){return{selectors:{contentWrapper:".e-contact-buttons__content-wrapper",contentWrapperFloatingBars:".e-floating-bars",floatingBarCouponButton:".e-floating-bars__coupon-button",floatingBarsHeadline:".e-floating-bars__headline",contactButtonsVar4:".e-contact-buttons__contact-icon-link",contactButtonsVar5:".e-contact-buttons__chat-button",contactButtonsVar6:".e-contact-buttons-var-6",contactButtonsVar8:".e-contact-buttons-var-8",elementorWrapper:'[data-elementor-type="floating-buttons"]',contactButtonCore:".e-contact-buttons__send-button"}}}getDefaultElements(){const t=this.getSettings("selectors");return{contentWrapper:this.$element[0].querySelector(t.contentWrapper),contentWrapperFloatingBars:this.$element[0].querySelector(t.contentWrapperFloatingBars),contactButtonsVar5:this.$element[0].querySelector(t.contactButtonsVar5),contactButtonsVar6:this.$element[0].querySelector(t.contactButtonsVar6)}}bindEvents(){this.elements.contentWrapper&&this.elements.contentWrapper.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contactButtonsVar5&&this.elements.contactButtonsVar5.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contactButtonsVar6&&this.elements.contactButtonsVar6.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contentWrapperFloatingBars&&this.elements.contentWrapperFloatingBars.addEventListener("click",this.onChatButtonTrackClick.bind(this)),window.addEventListener("beforeunload",(()=>{this.clicks.length>0&&this.sendClicks()}))}onChatButtonTrackClick(t){const e=t.target||t.srcElement,n=this.getSettings("selectors"),s=[n.contactButtonsVar4,n.contactButtonsVar6,n.floatingBarCouponButton,n.floatingBarsHeadline,n.contactButtonCore];for(const t of s)(e.matches(t)||e.closest(t))&&this.getDocumentIdAndTrack(e,n);(e.matches(n.contactButtonsVar5)||e.closest(n.contactButtonsVar5))&&e.closest(".e-contact-buttons-var-5")&&this.getDocumentIdAndTrack(e,n)}getDocumentIdAndTrack(t,e){const n=t.closest(e.elementorWrapper).dataset.elementorId;this.trackClick(n)}trackClick(t){t&&(this.clicks.push(t),this.clicks.length>=10&&this.sendClicks())}sendClicks(){const t=new FormData;t.append("action","elementor_send_clicks"),t.append("_nonce",elementorFrontendConfig?.nonces?.floatingButtonsClickTracking),this.clicks.forEach((e=>t.append("clicks[]",e))),fetch(elementorFrontendConfig?.urls?.ajaxurl,{method:"POST",body:t}).then((()=>{this.clicks=[]}))}}e.default=ClickTrackingHandler},8562:t=>{t.exports=elementorModules.ViewModule.extend({$element:null,editorListeners:null,onElementChange:null,onEditSettingsChange:null,onPageSettingsChange:null,isEdit:null,__construct(t){this.isActive(t)&&(this.$element=t.$element,this.isEdit=this.$element.hasClass("elementor-element-edit-mode"),this.isEdit&&this.addEditorListeners())},isActive:()=>!0,isElementInTheCurrentDocument(){return!!elementorFrontend.isEditMode()&&elementor.documents.currentDocument.id.toString()===this.$element[0].closest(".elementor").dataset.elementorId},findElement(t){var e=this.$element;return e.find(t).filter((function(){return jQuery(this).parent().closest(".elementor-element").is(e)}))},getUniqueHandlerID(t,e){return t||(t=this.getModelCID()),e||(e=this.$element),t+e.attr("data-element_type")+this.getConstructorID()},initEditorListeners(){var t=this;if(t.editorListeners=[{event:"element:destroy",to:elementor.channels.data,callback(e){e.cid===t.getModelCID()&&t.onDestroy()}}],t.onElementChange){const e=t.getWidgetType()||t.getElementType();let n="change";"global"!==e&&(n+=":"+e),t.editorListeners.push({event:n,to:elementor.channels.editor,callback(e,n){t.getUniqueHandlerID(n.model.cid,n.$el)===t.getUniqueHandlerID()&&t.onElementChange(e.model.get("name"),e,n)}})}t.onEditSettingsChange&&t.editorListeners.push({event:"change:editSettings",to:elementor.channels.editor,callback(e,n){if(n.model.cid!==t.getModelCID())return;const s=Object.keys(e.changed)[0];t.onEditSettingsChange(s,e.changed[s])}}),["page"].forEach((function(e){var n="on"+e[0].toUpperCase()+e.slice(1)+"SettingsChange";t[n]&&t.editorListeners.push({event:"change",to:elementor.settings[e].model,callback(e){t[n](e.changed)}})}))},getEditorListeners(){return this.editorListeners||this.initEditorListeners(),this.editorListeners},addEditorListeners(){var t=this.getUniqueHandlerID();this.getEditorListeners().forEach((function(e){elementorFrontend.addListenerOnce(t,e.event,e.callback,e.to)}))},removeEditorListeners(){var t=this.getUniqueHandlerID();this.getEditorListeners().forEach((function(e){elementorFrontend.removeListeners(t,e.event,null,e.to)}))},getElementType(){return this.$element.data("element_type")},getWidgetType(){const t=this.$element.data("widget_type");if(t)return t.split(".")[0]},getID(){return this.$element.data("id")},getModelCID(){return this.$element.data("model-cid")},getElementSettings(t){let e={};const n=this.getModelCID();if(this.isEdit&&n){const t=elementorFrontend.config.elements.data[n],s=t.attributes;let i=s.widgetType||s.elType;s.isInner&&(i="inner-"+i);let o=elementorFrontend.config.elements.keys[i];o||(o=elementorFrontend.config.elements.keys[i]=[],jQuery.each(t.controls,((t,e)=>{(e.frontend_available||e.editor_available)&&o.push(t)}))),jQuery.each(t.getActiveControls(),(function(t){if(-1!==o.indexOf(t)){let n=s[t];n.toJSON&&(n=n.toJSON()),e[t]=n}}))}else e=this.$element.data("settings")||{};return this.getItems(e,t)},getEditSettings(t){var e={};return this.isEdit&&(e=elementorFrontend.config.elements.editSettings[this.getModelCID()].attributes),this.getItems(e,t)},getCurrentDeviceSetting(t){return elementorFrontend.getCurrentDeviceSetting(this.getElementSettings(),t)},onInit(){this.isActive(this.getSettings())&&elementorModules.ViewModule.prototype.onInit.apply(this,arguments)},onDestroy(){this.isEdit&&this.removeEditorListeners(),this.unbindEvents&&this.unbindEvents()}})}}]); \ No newline at end of file diff --git a/assets/js/contact-buttons-var-10.44dafff87cd10dfffc68.bundle.js b/assets/js/contact-buttons-var-10.44dafff87cd10dfffc68.bundle.js new file mode 100644 index 00000000..c5277b79 --- /dev/null +++ b/assets/js/contact-buttons-var-10.44dafff87cd10dfffc68.bundle.js @@ -0,0 +1,411 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["contact-buttons-var-10"],{ + +/***/ "../modules/floating-buttons/assets/js/frontend/handlers/contact-buttons-v10.js": +/*!**************************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/frontend/handlers/contact-buttons-v10.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../../elementor/assets/dev/js/frontend/handlers/base.js")); +var _clickTracking = _interopRequireDefault(__webpack_require__(/*! ../../shared/frontend/handlers/click-tracking */ "../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js")); +class ContactButtonsv10Handler extends _base.default { + getDefaultSettings() { + return { + selectors: { + main: '.e-contact-buttons-var-10', + links: '.e-contact-buttons__contact-icon-link' + }, + constants: { + active: 'active' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + main: this.$element[0].querySelector(selectors.main), + links: this.$element[0].querySelectorAll(selectors.links) + }; + } + isMobileDevice() { + const mobileDevices = ['mobile', 'mobile_extra']; + return mobileDevices.includes(elementorFrontend.getCurrentDeviceMode()); + } + handleLinkClick(event) { + event.preventDefault(); + const { + active + } = this.getSettings('constants'); + if (event.currentTarget.classList.contains(active)) { + const href = event.currentTarget.getAttribute('href'); + const target = event.currentTarget.getAttribute('target'); + + // If the target is set, open in a new window, otherwise just change location + if (target) { + window.open(href, target); + } else if (href) { + window.location.href = href; + } + event.currentTarget.classList.remove(active); + } else { + this.closeAllLinks(); + event.currentTarget.classList.add(active); + } + } + closeAllLinks() { + const { + active + } = this.getSettings('constants'); + this.elements.links.forEach(link => link.classList.remove(active)); + } + linksEventListeners() { + if (!this.elements.links.length) { + return; + } + if (this.isMobileDevice()) { + this.elements.links.forEach(link => { + link.addEventListener('click', event => { + this.handleLinkClick(event); + }); + }); + + // Click outside will close all the links + document.addEventListener('click', event => { + if (!this.elements.main.contains(event.target)) { + this.closeAllLinks(); + } + }); + } + } + bindEvents() { + this.linksEventListeners(); + } + setupInnerContainer() { + this.elements.main.closest('.e-con-inner').classList.add('e-con-inner--floating-buttons'); + } + onInit(...args) { + super.onInit(...args); + this.clickTrackingHandler = new _clickTracking.default({ + $element: this.$element + }); + this.setupInnerContainer(); + } +} +exports["default"] = ContactButtonsv10Handler; + +/***/ }), + +/***/ "../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js": +/*!****************************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js ***! + \****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../../elementor/assets/dev/js/frontend/handlers/base.js")); +class ClickTrackingHandler extends _base.default { + clicks = []; + getDefaultSettings() { + return { + selectors: { + contentWrapper: '.e-contact-buttons__content-wrapper', + contentWrapperFloatingBars: '.e-floating-bars', + floatingBarCouponButton: '.e-floating-bars__coupon-button', + floatingBarsHeadline: '.e-floating-bars__headline', + contactButtonsVar4: '.e-contact-buttons__contact-icon-link', + contactButtonsVar5: '.e-contact-buttons__chat-button', + contactButtonsVar6: '.e-contact-buttons-var-6', + contactButtonsVar8: '.e-contact-buttons-var-8', + elementorWrapper: '[data-elementor-type="floating-buttons"]', + contactButtonCore: '.e-contact-buttons__send-button' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + contentWrapper: this.$element[0].querySelector(selectors.contentWrapper), + contentWrapperFloatingBars: this.$element[0].querySelector(selectors.contentWrapperFloatingBars), + contactButtonsVar5: this.$element[0].querySelector(selectors.contactButtonsVar5), + contactButtonsVar6: this.$element[0].querySelector(selectors.contactButtonsVar6) + }; + } + bindEvents() { + if (this.elements.contentWrapper) { + this.elements.contentWrapper.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar5) { + this.elements.contactButtonsVar5.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar6) { + this.elements.contactButtonsVar6.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contentWrapperFloatingBars) { + this.elements.contentWrapperFloatingBars.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + window.addEventListener('beforeunload', () => { + if (this.clicks.length > 0) { + this.sendClicks(); + } + }); + } + onChatButtonTrackClick(event) { + const targetElement = event.target || event.srcElement; + const selectors = this.getSettings('selectors'); + const buttonSelectors = [selectors.contactButtonsVar4, selectors.contactButtonsVar6, selectors.floatingBarCouponButton, selectors.floatingBarsHeadline, selectors.contactButtonCore]; + for (const selector of buttonSelectors) { + if (targetElement.matches(selector) || targetElement.closest(selector)) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + if ((targetElement.matches(selectors.contactButtonsVar5) || targetElement.closest(selectors.contactButtonsVar5)) && targetElement.closest('.e-contact-buttons-var-5')) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + getDocumentIdAndTrack(targetElement, selectors) { + const documentId = targetElement.closest(selectors.elementorWrapper).dataset.elementorId; + this.trackClick(documentId); + } + trackClick(documentId) { + if (!documentId) { + return; + } + this.clicks.push(documentId); + if (this.clicks.length >= 10) { + this.sendClicks(); + } + } + sendClicks() { + const formData = new FormData(); + formData.append('action', 'elementor_send_clicks'); + formData.append('_nonce', elementorFrontendConfig?.nonces?.floatingButtonsClickTracking); + this.clicks.forEach(documentId => formData.append('clicks[]', documentId)); + fetch(elementorFrontendConfig?.urls?.ajaxurl, { + method: 'POST', + body: formData + }).then(() => { + this.clicks = []; + }); + } +} +exports["default"] = ClickTrackingHandler; + +/***/ }), + +/***/ "../../elementor/assets/dev/js/frontend/handlers/base.js": +/*!***************************************************************!*\ + !*** ../../elementor/assets/dev/js/frontend/handlers/base.js ***! + \***************************************************************/ +/***/ ((module) => { + + + +module.exports = elementorModules.ViewModule.extend({ + $element: null, + editorListeners: null, + onElementChange: null, + onEditSettingsChange: null, + onPageSettingsChange: null, + isEdit: null, + __construct(settings) { + if (!this.isActive(settings)) { + return; + } + this.$element = settings.$element; + this.isEdit = this.$element.hasClass('elementor-element-edit-mode'); + if (this.isEdit) { + this.addEditorListeners(); + } + }, + isActive() { + return true; + }, + isElementInTheCurrentDocument() { + if (!elementorFrontend.isEditMode()) { + return false; + } + return elementor.documents.currentDocument.id.toString() === this.$element[0].closest('.elementor').dataset.elementorId; + }, + findElement(selector) { + var $mainElement = this.$element; + return $mainElement.find(selector).filter(function () { + // Start `closest` from parent since self can be `.elementor-element`. + return jQuery(this).parent().closest('.elementor-element').is($mainElement); + }); + }, + getUniqueHandlerID(cid, $element) { + if (!cid) { + cid = this.getModelCID(); + } + if (!$element) { + $element = this.$element; + } + return cid + $element.attr('data-element_type') + this.getConstructorID(); + }, + initEditorListeners() { + var self = this; + self.editorListeners = [{ + event: 'element:destroy', + to: elementor.channels.data, + callback(removedModel) { + if (removedModel.cid !== self.getModelCID()) { + return; + } + self.onDestroy(); + } + }]; + if (self.onElementChange) { + const elementType = self.getWidgetType() || self.getElementType(); + let eventName = 'change'; + if ('global' !== elementType) { + eventName += ':' + elementType; + } + self.editorListeners.push({ + event: eventName, + to: elementor.channels.editor, + callback(controlView, elementView) { + var elementViewHandlerID = self.getUniqueHandlerID(elementView.model.cid, elementView.$el); + if (elementViewHandlerID !== self.getUniqueHandlerID()) { + return; + } + self.onElementChange(controlView.model.get('name'), controlView, elementView); + } + }); + } + if (self.onEditSettingsChange) { + self.editorListeners.push({ + event: 'change:editSettings', + to: elementor.channels.editor, + callback(changedModel, view) { + if (view.model.cid !== self.getModelCID()) { + return; + } + const propName = Object.keys(changedModel.changed)[0]; + self.onEditSettingsChange(propName, changedModel.changed[propName]); + } + }); + } + ['page'].forEach(function (settingsType) { + var listenerMethodName = 'on' + settingsType[0].toUpperCase() + settingsType.slice(1) + 'SettingsChange'; + if (self[listenerMethodName]) { + self.editorListeners.push({ + event: 'change', + to: elementor.settings[settingsType].model, + callback(model) { + self[listenerMethodName](model.changed); + } + }); + } + }); + }, + getEditorListeners() { + if (!this.editorListeners) { + this.initEditorListeners(); + } + return this.editorListeners; + }, + addEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.addListenerOnce(uniqueHandlerID, listener.event, listener.callback, listener.to); + }); + }, + removeEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.removeListeners(uniqueHandlerID, listener.event, null, listener.to); + }); + }, + getElementType() { + return this.$element.data('element_type'); + }, + getWidgetType() { + const widgetType = this.$element.data('widget_type'); + if (!widgetType) { + return; + } + return widgetType.split('.')[0]; + }, + getID() { + return this.$element.data('id'); + }, + getModelCID() { + return this.$element.data('model-cid'); + }, + getElementSettings(setting) { + let elementSettings = {}; + const modelCID = this.getModelCID(); + if (this.isEdit && modelCID) { + const settings = elementorFrontend.config.elements.data[modelCID], + attributes = settings.attributes; + let type = attributes.widgetType || attributes.elType; + if (attributes.isInner) { + type = 'inner-' + type; + } + let settingsKeys = elementorFrontend.config.elements.keys[type]; + if (!settingsKeys) { + settingsKeys = elementorFrontend.config.elements.keys[type] = []; + jQuery.each(settings.controls, (name, control) => { + if (control.frontend_available || control.editor_available) { + settingsKeys.push(name); + } + }); + } + jQuery.each(settings.getActiveControls(), function (controlKey) { + if (-1 !== settingsKeys.indexOf(controlKey)) { + let value = attributes[controlKey]; + if (value.toJSON) { + value = value.toJSON(); + } + elementSettings[controlKey] = value; + } + }); + } else { + elementSettings = this.$element.data('settings') || {}; + } + return this.getItems(elementSettings, setting); + }, + getEditSettings(setting) { + var attributes = {}; + if (this.isEdit) { + attributes = elementorFrontend.config.elements.editSettings[this.getModelCID()].attributes; + } + return this.getItems(attributes, setting); + }, + getCurrentDeviceSetting(settingKey) { + return elementorFrontend.getCurrentDeviceSetting(this.getElementSettings(), settingKey); + }, + onInit() { + if (this.isActive(this.getSettings())) { + elementorModules.ViewModule.prototype.onInit.apply(this, arguments); + } + }, + onDestroy() { + if (this.isEdit) { + this.removeEditorListeners(); + } + if (this.unbindEvents) { + this.unbindEvents(); + } + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=contact-buttons-var-10.44dafff87cd10dfffc68.bundle.js.map \ No newline at end of file diff --git a/assets/js/contact-buttons.23b3f042ed41cf9221f4.bundle.js b/assets/js/contact-buttons.23b3f042ed41cf9221f4.bundle.js new file mode 100644 index 00000000..fc6292d4 --- /dev/null +++ b/assets/js/contact-buttons.23b3f042ed41cf9221f4.bundle.js @@ -0,0 +1,659 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["contact-buttons"],{ + +/***/ "../modules/floating-buttons/assets/js/frontend/handlers/contact-buttons.js": +/*!**********************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/frontend/handlers/contact-buttons.js ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../../elementor/assets/dev/js/frontend/handlers/base.js")); +var _clickTracking = _interopRequireDefault(__webpack_require__(/*! ../../shared/frontend/handlers/click-tracking */ "../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js")); +class ContactButtonsHandler extends _base.default { + clicks = []; + getDefaultSettings() { + return { + selectors: { + main: '.e-contact-buttons', + content: '.e-contact-buttons__content', + contentWrapper: '.e-contact-buttons__content-wrapper', + chatButton: '.e-contact-buttons__chat-button', + closeButton: '.e-contact-buttons__close-button', + messageBubbleTime: '.e-contact-buttons__message-bubble-time' + }, + constants: { + entranceAnimation: 'style_chat_box_entrance_animation', + exitAnimation: 'style_chat_box_exit_animation', + chatButtonAnimation: 'style_chat_button_animation', + animated: 'animated', + animatedWrapper: 'animated-wrapper', + visible: 'visible', + reverse: 'reverse', + hidden: 'hidden', + hasAnimations: 'has-animations', + hasEntranceAnimation: 'has-entrance-animation', + none: 'none' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + main: this.$element[0].querySelector(selectors.main), + content: this.$element[0].querySelector(selectors.content), + contentWrapper: this.$element[0].querySelector(selectors.contentWrapper), + chatButton: this.$element[0].querySelector(selectors.chatButton), + closeButton: this.$element[0].querySelector(selectors.closeButton), + messageBubbleTime: this.$element[0].querySelector(selectors.messageBubbleTime) + }; + } + getResponsiveSetting(controlName) { + const currentDevice = elementorFrontend.getCurrentDeviceMode(); + return elementorFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(), controlName, '', currentDevice); + } + bindEvents() { + if (this.elements.closeButton) { + this.elements.closeButton.addEventListener('click', this.closeChatBox.bind(this)); + } + if (this.elements.chatButton) { + this.elements.chatButton.addEventListener('click', this.onChatButtonClick.bind(this)); + this.elements.chatButton.addEventListener('animationend', this.removeChatButtonAnimationClasses.bind(this)); + } + if (this.elements.content) { + this.elements.content.addEventListener('animationend', this.removeAnimationClasses.bind(this)); + } + if (this.elements.contentWrapper) { + window.addEventListener('keyup', this.onDocumentKeyup.bind(this)); + } + } + contentWrapperIsHidden(hide) { + if (!this.elements.contentWrapper) { + return false; + } + const { + hidden + } = this.getSettings('constants'); + + // Set current state + if (true === hide) { + this.elements.contentWrapper.classList.add(hidden); + this.elements.contentWrapper.setAttribute('aria-hidden', 'true'); + return; + } + if (false === hide) { + this.elements.contentWrapper.classList.remove(hidden); + this.elements.contentWrapper.setAttribute('aria-hidden', 'false'); + return; + } + + // Get current state + return this.elements.contentWrapper.classList.contains(hidden); + } + onDocumentKeyup(event) { + // Bail if not ESC key + if (event.keyCode !== 27 || !this.elements.main) { + return; + } + + /* eslint-disable @wordpress/no-global-active-element */ + if (!this.contentWrapperIsHidden() && this.elements.main.contains(document.activeElement)) { + this.closeChatBox(); + } + /* eslint-enable @wordpress/no-global-active-element */ + } + onChatButtonTrackClick(event) { + const targetElement = event.target || event.srcElement; + const selectors = this.getSettings('selectors'); + const buttonSelectors = [selectors.contactButtonsVar4, selectors.contactButtonsVar6, selectors.contactButtonCore]; + for (const selector of buttonSelectors) { + if (targetElement.matches(selector) || targetElement.closest(selector)) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + if ((targetElement.matches(selectors.contactButtonsVar5) || targetElement.closest(selectors.contactButtonsVar5)) && targetElement.closest('.e-contact-buttons-var-5')) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + getDocumentIdAndTrack(targetElement, selectors) { + let documentId = targetElement.closest(selectors.main).dataset.documentId; + if (!documentId) { + documentId = targetElement.closest(selectors.elementorWrapper).dataset.elementorId; + } + this.trackClick(documentId); + } + trackClick(documentId) { + if (!documentId) { + return; + } + this.clicks.push(documentId); + if (this.clicks.length >= 10) { + this.sendClicks(); + } + } + sendClicks() { + const formData = new FormData(); + formData.append('action', 'elementor_send_clicks'); + formData.append('_nonce', elementorFrontendConfig?.nonces?.floatingButtonsClickTracking); + this.clicks.forEach(documentId => formData.append('clicks[]', documentId)); + fetch(elementorFrontendConfig?.urls?.ajaxurl, { + method: 'POST', + body: formData + }).then(() => { + this.clicks = []; + }); + } + removeAnimationClasses() { + if (!this.elements.content) { + return; + } + const { + reverse, + entranceAnimation, + exitAnimation, + animated, + visible + } = this.getSettings('constants'); + const isExitAnimation = this.elements.content.classList.contains(reverse), + openAnimationClass = this.getResponsiveSetting(entranceAnimation), + exitAnimationClass = this.getResponsiveSetting(exitAnimation); + if (isExitAnimation) { + this.elements.content.classList.remove(animated); + this.elements.content.classList.remove(reverse); + if (exitAnimationClass) { + this.elements.content.classList.remove(exitAnimationClass); + } + this.elements.content.classList.remove(visible); + } else { + this.elements.content.classList.remove(animated); + if (openAnimationClass) { + this.elements.content.classList.remove(openAnimationClass); + } + this.elements.content.classList.add(visible); + } + } + chatBoxEntranceAnimation() { + const { + entranceAnimation, + animated, + animatedWrapper, + none + } = this.getSettings('constants'); + const entranceAnimationControl = this.getResponsiveSetting(entranceAnimation); + if (!entranceAnimationControl || none === entranceAnimationControl) { + return; + } + if (this.elements.content) { + this.elements.content.classList.add(animated); + this.elements.content.classList.add(entranceAnimationControl); + } + if (this.elements.contentWrapper) { + this.elements.contentWrapper.classList.remove(animatedWrapper); + } + } + chatBoxExitAnimation() { + const { + reverse, + exitAnimation, + animated, + animatedWrapper, + none + } = this.getSettings('constants'); + const exitAnimationControl = this.getResponsiveSetting(exitAnimation); + if (!exitAnimationControl || none === exitAnimationControl) { + return; + } + if (this.elements.content) { + this.elements.content.classList.add(animated); + this.elements.content.classList.add(reverse); + this.elements.content.classList.add(exitAnimationControl); + } + if (this.elements.contentWrapper) { + this.elements.contentWrapper.classList.add(animatedWrapper); + } + } + openChatBox() { + const { + hasAnimations, + visible + } = this.getSettings('constants'); + if (this.elements.main && this.elements.main.classList.contains(hasAnimations)) { + this.chatBoxEntranceAnimation(); + } else if (this.elements.content) { + this.elements.content.classList.add(visible); + } + if (this.elements.contentWrapper) { + this.contentWrapperIsHidden(false); + if (!elementorFrontend.isEditMode()) { + this.elements.contentWrapper.setAttribute('tabindex', '0'); + this.elements.contentWrapper.focus({ + focusVisible: true + }); + } + } + if (this.elements.chatButton) { + this.elements.chatButton.setAttribute('aria-expanded', 'true'); + } + if (this.elements.closeButton) { + this.elements.closeButton.setAttribute('aria-expanded', 'true'); + } + } + closeChatBox() { + const { + hasAnimations, + visible + } = this.getSettings('constants'); + if (this.elements.main && this.elements.main.classList.contains(hasAnimations)) { + this.chatBoxExitAnimation(); + } else if (this.elements.content) { + this.elements.content.classList.remove(visible); + } + if (this.elements.contentWrapper) { + this.contentWrapperIsHidden(true); + } + if (this.elements.chatButton) { + this.elements.chatButton.setAttribute('aria-expanded', 'false'); + this.elements.chatButton.focus({ + focusVisible: true + }); + } + if (this.elements.closeButton) { + this.elements.closeButton.setAttribute('aria-expanded', 'false'); + } + } + onChatButtonClick() { + if (this.elements.contentWrapper && this.contentWrapperIsHidden()) { + this.openChatBox(); + } else { + this.closeChatBox(); + } + } + initMessageBubbleTime() { + if (!this.elements.messageBubbleTime) { + return; + } + const messageBubbleTimeFormat = this.elements.messageBubbleTime.dataset.timeFormat; + const is12hFormat = '12h' === messageBubbleTimeFormat; + const time = new Intl.DateTimeFormat('default', { + hour12: is12hFormat, + hour: 'numeric', + minute: 'numeric' + }).format(new Date()); + this.elements.messageBubbleTime.innerHTML = time; + } + removeChatButtonAnimationClasses() { + if (!this.elements.chatButton) { + return; + } + const { + chatButtonAnimation, + visible + } = this.getSettings('constants'); + this.elements.chatButton.classList.remove(chatButtonAnimation); + this.elements.chatButton.classList.add(visible); + } + initChatButtonEntranceAnimation() { + const { + none, + chatButtonAnimation + } = this.getSettings('constants'); + const entranceAnimationControl = this.getResponsiveSetting(chatButtonAnimation); + if (!entranceAnimationControl || none === entranceAnimationControl) { + return; + } + this.elements.chatButton.classList.add(entranceAnimationControl); + } + initDefaultState() { + // Manage accessibility + if (this.elements.contentWrapper) { + const isHidden = this.contentWrapperIsHidden(); + if (this.elements.chatButton) { + this.elements.chatButton.setAttribute('aria-expanded', !isHidden); + } + if (this.elements.closeButton) { + this.elements.closeButton.setAttribute('aria-expanded', !isHidden); + } + } + if (elementorFrontend.isEditMode() && 'floating-buttons' === elementor?.config?.document?.type) { + this.openChatBox(); + } + } + setupInnerContainer() { + this.elements.main.closest('.e-con-inner').classList.add('e-con-inner--floating-buttons'); + } + onInit(...args) { + const { + hasEntranceAnimation + } = this.getSettings('constants'); + super.onInit(...args); + this.clickTrackingHandler = new _clickTracking.default({ + $element: this.$element + }); + if (this.elements.messageBubbleTime) { + this.initMessageBubbleTime(); + } + this.initDefaultState(); + if (this.elements.chatButton) { + if (this.elements.chatButton.classList.contains(hasEntranceAnimation)) { + this.initChatButtonEntranceAnimation(); + } + } + this.setupInnerContainer(); + } +} +exports["default"] = ContactButtonsHandler; + +/***/ }), + +/***/ "../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js": +/*!****************************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js ***! + \****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../../elementor/assets/dev/js/frontend/handlers/base.js")); +class ClickTrackingHandler extends _base.default { + clicks = []; + getDefaultSettings() { + return { + selectors: { + contentWrapper: '.e-contact-buttons__content-wrapper', + contentWrapperFloatingBars: '.e-floating-bars', + floatingBarCouponButton: '.e-floating-bars__coupon-button', + floatingBarsHeadline: '.e-floating-bars__headline', + contactButtonsVar4: '.e-contact-buttons__contact-icon-link', + contactButtonsVar5: '.e-contact-buttons__chat-button', + contactButtonsVar6: '.e-contact-buttons-var-6', + contactButtonsVar8: '.e-contact-buttons-var-8', + elementorWrapper: '[data-elementor-type="floating-buttons"]', + contactButtonCore: '.e-contact-buttons__send-button' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + contentWrapper: this.$element[0].querySelector(selectors.contentWrapper), + contentWrapperFloatingBars: this.$element[0].querySelector(selectors.contentWrapperFloatingBars), + contactButtonsVar5: this.$element[0].querySelector(selectors.contactButtonsVar5), + contactButtonsVar6: this.$element[0].querySelector(selectors.contactButtonsVar6) + }; + } + bindEvents() { + if (this.elements.contentWrapper) { + this.elements.contentWrapper.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar5) { + this.elements.contactButtonsVar5.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar6) { + this.elements.contactButtonsVar6.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contentWrapperFloatingBars) { + this.elements.contentWrapperFloatingBars.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + window.addEventListener('beforeunload', () => { + if (this.clicks.length > 0) { + this.sendClicks(); + } + }); + } + onChatButtonTrackClick(event) { + const targetElement = event.target || event.srcElement; + const selectors = this.getSettings('selectors'); + const buttonSelectors = [selectors.contactButtonsVar4, selectors.contactButtonsVar6, selectors.floatingBarCouponButton, selectors.floatingBarsHeadline, selectors.contactButtonCore]; + for (const selector of buttonSelectors) { + if (targetElement.matches(selector) || targetElement.closest(selector)) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + if ((targetElement.matches(selectors.contactButtonsVar5) || targetElement.closest(selectors.contactButtonsVar5)) && targetElement.closest('.e-contact-buttons-var-5')) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + getDocumentIdAndTrack(targetElement, selectors) { + const documentId = targetElement.closest(selectors.elementorWrapper).dataset.elementorId; + this.trackClick(documentId); + } + trackClick(documentId) { + if (!documentId) { + return; + } + this.clicks.push(documentId); + if (this.clicks.length >= 10) { + this.sendClicks(); + } + } + sendClicks() { + const formData = new FormData(); + formData.append('action', 'elementor_send_clicks'); + formData.append('_nonce', elementorFrontendConfig?.nonces?.floatingButtonsClickTracking); + this.clicks.forEach(documentId => formData.append('clicks[]', documentId)); + fetch(elementorFrontendConfig?.urls?.ajaxurl, { + method: 'POST', + body: formData + }).then(() => { + this.clicks = []; + }); + } +} +exports["default"] = ClickTrackingHandler; + +/***/ }), + +/***/ "../../elementor/assets/dev/js/frontend/handlers/base.js": +/*!***************************************************************!*\ + !*** ../../elementor/assets/dev/js/frontend/handlers/base.js ***! + \***************************************************************/ +/***/ ((module) => { + + + +module.exports = elementorModules.ViewModule.extend({ + $element: null, + editorListeners: null, + onElementChange: null, + onEditSettingsChange: null, + onPageSettingsChange: null, + isEdit: null, + __construct(settings) { + if (!this.isActive(settings)) { + return; + } + this.$element = settings.$element; + this.isEdit = this.$element.hasClass('elementor-element-edit-mode'); + if (this.isEdit) { + this.addEditorListeners(); + } + }, + isActive() { + return true; + }, + isElementInTheCurrentDocument() { + if (!elementorFrontend.isEditMode()) { + return false; + } + return elementor.documents.currentDocument.id.toString() === this.$element[0].closest('.elementor').dataset.elementorId; + }, + findElement(selector) { + var $mainElement = this.$element; + return $mainElement.find(selector).filter(function () { + // Start `closest` from parent since self can be `.elementor-element`. + return jQuery(this).parent().closest('.elementor-element').is($mainElement); + }); + }, + getUniqueHandlerID(cid, $element) { + if (!cid) { + cid = this.getModelCID(); + } + if (!$element) { + $element = this.$element; + } + return cid + $element.attr('data-element_type') + this.getConstructorID(); + }, + initEditorListeners() { + var self = this; + self.editorListeners = [{ + event: 'element:destroy', + to: elementor.channels.data, + callback(removedModel) { + if (removedModel.cid !== self.getModelCID()) { + return; + } + self.onDestroy(); + } + }]; + if (self.onElementChange) { + const elementType = self.getWidgetType() || self.getElementType(); + let eventName = 'change'; + if ('global' !== elementType) { + eventName += ':' + elementType; + } + self.editorListeners.push({ + event: eventName, + to: elementor.channels.editor, + callback(controlView, elementView) { + var elementViewHandlerID = self.getUniqueHandlerID(elementView.model.cid, elementView.$el); + if (elementViewHandlerID !== self.getUniqueHandlerID()) { + return; + } + self.onElementChange(controlView.model.get('name'), controlView, elementView); + } + }); + } + if (self.onEditSettingsChange) { + self.editorListeners.push({ + event: 'change:editSettings', + to: elementor.channels.editor, + callback(changedModel, view) { + if (view.model.cid !== self.getModelCID()) { + return; + } + const propName = Object.keys(changedModel.changed)[0]; + self.onEditSettingsChange(propName, changedModel.changed[propName]); + } + }); + } + ['page'].forEach(function (settingsType) { + var listenerMethodName = 'on' + settingsType[0].toUpperCase() + settingsType.slice(1) + 'SettingsChange'; + if (self[listenerMethodName]) { + self.editorListeners.push({ + event: 'change', + to: elementor.settings[settingsType].model, + callback(model) { + self[listenerMethodName](model.changed); + } + }); + } + }); + }, + getEditorListeners() { + if (!this.editorListeners) { + this.initEditorListeners(); + } + return this.editorListeners; + }, + addEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.addListenerOnce(uniqueHandlerID, listener.event, listener.callback, listener.to); + }); + }, + removeEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.removeListeners(uniqueHandlerID, listener.event, null, listener.to); + }); + }, + getElementType() { + return this.$element.data('element_type'); + }, + getWidgetType() { + const widgetType = this.$element.data('widget_type'); + if (!widgetType) { + return; + } + return widgetType.split('.')[0]; + }, + getID() { + return this.$element.data('id'); + }, + getModelCID() { + return this.$element.data('model-cid'); + }, + getElementSettings(setting) { + let elementSettings = {}; + const modelCID = this.getModelCID(); + if (this.isEdit && modelCID) { + const settings = elementorFrontend.config.elements.data[modelCID], + attributes = settings.attributes; + let type = attributes.widgetType || attributes.elType; + if (attributes.isInner) { + type = 'inner-' + type; + } + let settingsKeys = elementorFrontend.config.elements.keys[type]; + if (!settingsKeys) { + settingsKeys = elementorFrontend.config.elements.keys[type] = []; + jQuery.each(settings.controls, (name, control) => { + if (control.frontend_available || control.editor_available) { + settingsKeys.push(name); + } + }); + } + jQuery.each(settings.getActiveControls(), function (controlKey) { + if (-1 !== settingsKeys.indexOf(controlKey)) { + let value = attributes[controlKey]; + if (value.toJSON) { + value = value.toJSON(); + } + elementSettings[controlKey] = value; + } + }); + } else { + elementSettings = this.$element.data('settings') || {}; + } + return this.getItems(elementSettings, setting); + }, + getEditSettings(setting) { + var attributes = {}; + if (this.isEdit) { + attributes = elementorFrontend.config.elements.editSettings[this.getModelCID()].attributes; + } + return this.getItems(attributes, setting); + }, + getCurrentDeviceSetting(settingKey) { + return elementorFrontend.getCurrentDeviceSetting(this.getElementSettings(), settingKey); + }, + onInit() { + if (this.isActive(this.getSettings())) { + elementorModules.ViewModule.prototype.onInit.apply(this, arguments); + } + }, + onDestroy() { + if (this.isEdit) { + this.removeEditorListeners(); + } + if (this.unbindEvents) { + this.unbindEvents(); + } + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=contact-buttons.23b3f042ed41cf9221f4.bundle.js.map \ No newline at end of file diff --git a/assets/js/contact-buttons.99a987d66bcc2ade0ee6.bundle.min.js b/assets/js/contact-buttons.99a987d66bcc2ade0ee6.bundle.min.js new file mode 100644 index 00000000..9c8ccdfc --- /dev/null +++ b/assets/js/contact-buttons.99a987d66bcc2ade0ee6.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[1],{197:(t,e,n)=>{var s=n(6784);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i=s(n(8562)),o=s(n(8243));class ContactButtonsHandler extends i.default{clicks=[];getDefaultSettings(){return{selectors:{main:".e-contact-buttons",content:".e-contact-buttons__content",contentWrapper:".e-contact-buttons__content-wrapper",chatButton:".e-contact-buttons__chat-button",closeButton:".e-contact-buttons__close-button",messageBubbleTime:".e-contact-buttons__message-bubble-time"},constants:{entranceAnimation:"style_chat_box_entrance_animation",exitAnimation:"style_chat_box_exit_animation",chatButtonAnimation:"style_chat_button_animation",animated:"animated",animatedWrapper:"animated-wrapper",visible:"visible",reverse:"reverse",hidden:"hidden",hasAnimations:"has-animations",hasEntranceAnimation:"has-entrance-animation",none:"none"}}}getDefaultElements(){const t=this.getSettings("selectors");return{main:this.$element[0].querySelector(t.main),content:this.$element[0].querySelector(t.content),contentWrapper:this.$element[0].querySelector(t.contentWrapper),chatButton:this.$element[0].querySelector(t.chatButton),closeButton:this.$element[0].querySelector(t.closeButton),messageBubbleTime:this.$element[0].querySelector(t.messageBubbleTime)}}getResponsiveSetting(t){const e=elementorFrontend.getCurrentDeviceMode();return elementorFrontend.utils.controls.getResponsiveControlValue(this.getElementSettings(),t,"",e)}bindEvents(){this.elements.closeButton&&this.elements.closeButton.addEventListener("click",this.closeChatBox.bind(this)),this.elements.chatButton&&(this.elements.chatButton.addEventListener("click",this.onChatButtonClick.bind(this)),this.elements.chatButton.addEventListener("animationend",this.removeChatButtonAnimationClasses.bind(this))),this.elements.content&&this.elements.content.addEventListener("animationend",this.removeAnimationClasses.bind(this)),this.elements.contentWrapper&&window.addEventListener("keyup",this.onDocumentKeyup.bind(this))}contentWrapperIsHidden(t){if(!this.elements.contentWrapper)return!1;const{hidden:e}=this.getSettings("constants");return!0===t?(this.elements.contentWrapper.classList.add(e),void this.elements.contentWrapper.setAttribute("aria-hidden","true")):!1===t?(this.elements.contentWrapper.classList.remove(e),void this.elements.contentWrapper.setAttribute("aria-hidden","false")):this.elements.contentWrapper.classList.contains(e)}onDocumentKeyup(t){27===t.keyCode&&this.elements.main&&!this.contentWrapperIsHidden()&&this.elements.main.contains(document.activeElement)&&this.closeChatBox()}onChatButtonTrackClick(t){const e=t.target||t.srcElement,n=this.getSettings("selectors"),s=[n.contactButtonsVar4,n.contactButtonsVar6,n.contactButtonCore];for(const t of s)(e.matches(t)||e.closest(t))&&this.getDocumentIdAndTrack(e,n);(e.matches(n.contactButtonsVar5)||e.closest(n.contactButtonsVar5))&&e.closest(".e-contact-buttons-var-5")&&this.getDocumentIdAndTrack(e,n)}getDocumentIdAndTrack(t,e){let n=t.closest(e.main).dataset.documentId;n||(n=t.closest(e.elementorWrapper).dataset.elementorId),this.trackClick(n)}trackClick(t){t&&(this.clicks.push(t),this.clicks.length>=10&&this.sendClicks())}sendClicks(){const t=new FormData;t.append("action","elementor_send_clicks"),t.append("_nonce",elementorFrontendConfig?.nonces?.floatingButtonsClickTracking),this.clicks.forEach((e=>t.append("clicks[]",e))),fetch(elementorFrontendConfig?.urls?.ajaxurl,{method:"POST",body:t}).then((()=>{this.clicks=[]}))}removeAnimationClasses(){if(!this.elements.content)return;const{reverse:t,entranceAnimation:e,exitAnimation:n,animated:s,visible:i}=this.getSettings("constants"),o=this.elements.content.classList.contains(t),a=this.getResponsiveSetting(e),c=this.getResponsiveSetting(n);o?(this.elements.content.classList.remove(s),this.elements.content.classList.remove(t),c&&this.elements.content.classList.remove(c),this.elements.content.classList.remove(i)):(this.elements.content.classList.remove(s),a&&this.elements.content.classList.remove(a),this.elements.content.classList.add(i))}chatBoxEntranceAnimation(){const{entranceAnimation:t,animated:e,animatedWrapper:n,none:s}=this.getSettings("constants"),i=this.getResponsiveSetting(t);i&&s!==i&&(this.elements.content&&(this.elements.content.classList.add(e),this.elements.content.classList.add(i)),this.elements.contentWrapper&&this.elements.contentWrapper.classList.remove(n))}chatBoxExitAnimation(){const{reverse:t,exitAnimation:e,animated:n,animatedWrapper:s,none:i}=this.getSettings("constants"),o=this.getResponsiveSetting(e);o&&i!==o&&(this.elements.content&&(this.elements.content.classList.add(n),this.elements.content.classList.add(t),this.elements.content.classList.add(o)),this.elements.contentWrapper&&this.elements.contentWrapper.classList.add(s))}openChatBox(){const{hasAnimations:t,visible:e}=this.getSettings("constants");this.elements.main&&this.elements.main.classList.contains(t)?this.chatBoxEntranceAnimation():this.elements.content&&this.elements.content.classList.add(e),this.elements.contentWrapper&&(this.contentWrapperIsHidden(!1),elementorFrontend.isEditMode()||(this.elements.contentWrapper.setAttribute("tabindex","0"),this.elements.contentWrapper.focus({focusVisible:!0}))),this.elements.chatButton&&this.elements.chatButton.setAttribute("aria-expanded","true"),this.elements.closeButton&&this.elements.closeButton.setAttribute("aria-expanded","true")}closeChatBox(){const{hasAnimations:t,visible:e}=this.getSettings("constants");this.elements.main&&this.elements.main.classList.contains(t)?this.chatBoxExitAnimation():this.elements.content&&this.elements.content.classList.remove(e),this.elements.contentWrapper&&this.contentWrapperIsHidden(!0),this.elements.chatButton&&(this.elements.chatButton.setAttribute("aria-expanded","false"),this.elements.chatButton.focus({focusVisible:!0})),this.elements.closeButton&&this.elements.closeButton.setAttribute("aria-expanded","false")}onChatButtonClick(){this.elements.contentWrapper&&this.contentWrapperIsHidden()?this.openChatBox():this.closeChatBox()}initMessageBubbleTime(){if(!this.elements.messageBubbleTime)return;const t="12h"===this.elements.messageBubbleTime.dataset.timeFormat,e=new Intl.DateTimeFormat("default",{hour12:t,hour:"numeric",minute:"numeric"}).format(new Date);this.elements.messageBubbleTime.innerHTML=e}removeChatButtonAnimationClasses(){if(!this.elements.chatButton)return;const{chatButtonAnimation:t,visible:e}=this.getSettings("constants");this.elements.chatButton.classList.remove(t),this.elements.chatButton.classList.add(e)}initChatButtonEntranceAnimation(){const{none:t,chatButtonAnimation:e}=this.getSettings("constants"),n=this.getResponsiveSetting(e);n&&t!==n&&this.elements.chatButton.classList.add(n)}initDefaultState(){if(this.elements.contentWrapper){const t=this.contentWrapperIsHidden();this.elements.chatButton&&this.elements.chatButton.setAttribute("aria-expanded",!t),this.elements.closeButton&&this.elements.closeButton.setAttribute("aria-expanded",!t)}elementorFrontend.isEditMode()&&"floating-buttons"===elementor?.config?.document?.type&&this.openChatBox()}setupInnerContainer(){this.elements.main.closest(".e-con-inner").classList.add("e-con-inner--floating-buttons")}onInit(...t){const{hasEntranceAnimation:e}=this.getSettings("constants");super.onInit(...t),this.clickTrackingHandler=new o.default({$element:this.$element}),this.elements.messageBubbleTime&&this.initMessageBubbleTime(),this.initDefaultState(),this.elements.chatButton&&this.elements.chatButton.classList.contains(e)&&this.initChatButtonEntranceAnimation(),this.setupInnerContainer()}}e.default=ContactButtonsHandler},8243:(t,e,n)=>{var s=n(6784);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var i=s(n(8562));class ClickTrackingHandler extends i.default{clicks=[];getDefaultSettings(){return{selectors:{contentWrapper:".e-contact-buttons__content-wrapper",contentWrapperFloatingBars:".e-floating-bars",floatingBarCouponButton:".e-floating-bars__coupon-button",floatingBarsHeadline:".e-floating-bars__headline",contactButtonsVar4:".e-contact-buttons__contact-icon-link",contactButtonsVar5:".e-contact-buttons__chat-button",contactButtonsVar6:".e-contact-buttons-var-6",contactButtonsVar8:".e-contact-buttons-var-8",elementorWrapper:'[data-elementor-type="floating-buttons"]',contactButtonCore:".e-contact-buttons__send-button"}}}getDefaultElements(){const t=this.getSettings("selectors");return{contentWrapper:this.$element[0].querySelector(t.contentWrapper),contentWrapperFloatingBars:this.$element[0].querySelector(t.contentWrapperFloatingBars),contactButtonsVar5:this.$element[0].querySelector(t.contactButtonsVar5),contactButtonsVar6:this.$element[0].querySelector(t.contactButtonsVar6)}}bindEvents(){this.elements.contentWrapper&&this.elements.contentWrapper.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contactButtonsVar5&&this.elements.contactButtonsVar5.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contactButtonsVar6&&this.elements.contactButtonsVar6.addEventListener("click",this.onChatButtonTrackClick.bind(this)),this.elements.contentWrapperFloatingBars&&this.elements.contentWrapperFloatingBars.addEventListener("click",this.onChatButtonTrackClick.bind(this)),window.addEventListener("beforeunload",(()=>{this.clicks.length>0&&this.sendClicks()}))}onChatButtonTrackClick(t){const e=t.target||t.srcElement,n=this.getSettings("selectors"),s=[n.contactButtonsVar4,n.contactButtonsVar6,n.floatingBarCouponButton,n.floatingBarsHeadline,n.contactButtonCore];for(const t of s)(e.matches(t)||e.closest(t))&&this.getDocumentIdAndTrack(e,n);(e.matches(n.contactButtonsVar5)||e.closest(n.contactButtonsVar5))&&e.closest(".e-contact-buttons-var-5")&&this.getDocumentIdAndTrack(e,n)}getDocumentIdAndTrack(t,e){const n=t.closest(e.elementorWrapper).dataset.elementorId;this.trackClick(n)}trackClick(t){t&&(this.clicks.push(t),this.clicks.length>=10&&this.sendClicks())}sendClicks(){const t=new FormData;t.append("action","elementor_send_clicks"),t.append("_nonce",elementorFrontendConfig?.nonces?.floatingButtonsClickTracking),this.clicks.forEach((e=>t.append("clicks[]",e))),fetch(elementorFrontendConfig?.urls?.ajaxurl,{method:"POST",body:t}).then((()=>{this.clicks=[]}))}}e.default=ClickTrackingHandler},8562:t=>{t.exports=elementorModules.ViewModule.extend({$element:null,editorListeners:null,onElementChange:null,onEditSettingsChange:null,onPageSettingsChange:null,isEdit:null,__construct(t){this.isActive(t)&&(this.$element=t.$element,this.isEdit=this.$element.hasClass("elementor-element-edit-mode"),this.isEdit&&this.addEditorListeners())},isActive:()=>!0,isElementInTheCurrentDocument(){return!!elementorFrontend.isEditMode()&&elementor.documents.currentDocument.id.toString()===this.$element[0].closest(".elementor").dataset.elementorId},findElement(t){var e=this.$element;return e.find(t).filter((function(){return jQuery(this).parent().closest(".elementor-element").is(e)}))},getUniqueHandlerID(t,e){return t||(t=this.getModelCID()),e||(e=this.$element),t+e.attr("data-element_type")+this.getConstructorID()},initEditorListeners(){var t=this;if(t.editorListeners=[{event:"element:destroy",to:elementor.channels.data,callback(e){e.cid===t.getModelCID()&&t.onDestroy()}}],t.onElementChange){const e=t.getWidgetType()||t.getElementType();let n="change";"global"!==e&&(n+=":"+e),t.editorListeners.push({event:n,to:elementor.channels.editor,callback(e,n){t.getUniqueHandlerID(n.model.cid,n.$el)===t.getUniqueHandlerID()&&t.onElementChange(e.model.get("name"),e,n)}})}t.onEditSettingsChange&&t.editorListeners.push({event:"change:editSettings",to:elementor.channels.editor,callback(e,n){if(n.model.cid!==t.getModelCID())return;const s=Object.keys(e.changed)[0];t.onEditSettingsChange(s,e.changed[s])}}),["page"].forEach((function(e){var n="on"+e[0].toUpperCase()+e.slice(1)+"SettingsChange";t[n]&&t.editorListeners.push({event:"change",to:elementor.settings[e].model,callback(e){t[n](e.changed)}})}))},getEditorListeners(){return this.editorListeners||this.initEditorListeners(),this.editorListeners},addEditorListeners(){var t=this.getUniqueHandlerID();this.getEditorListeners().forEach((function(e){elementorFrontend.addListenerOnce(t,e.event,e.callback,e.to)}))},removeEditorListeners(){var t=this.getUniqueHandlerID();this.getEditorListeners().forEach((function(e){elementorFrontend.removeListeners(t,e.event,null,e.to)}))},getElementType(){return this.$element.data("element_type")},getWidgetType(){const t=this.$element.data("widget_type");if(t)return t.split(".")[0]},getID(){return this.$element.data("id")},getModelCID(){return this.$element.data("model-cid")},getElementSettings(t){let e={};const n=this.getModelCID();if(this.isEdit&&n){const t=elementorFrontend.config.elements.data[n],s=t.attributes;let i=s.widgetType||s.elType;s.isInner&&(i="inner-"+i);let o=elementorFrontend.config.elements.keys[i];o||(o=elementorFrontend.config.elements.keys[i]=[],jQuery.each(t.controls,((t,e)=>{(e.frontend_available||e.editor_available)&&o.push(t)}))),jQuery.each(t.getActiveControls(),(function(t){if(-1!==o.indexOf(t)){let n=s[t];n.toJSON&&(n=n.toJSON()),e[t]=n}}))}else e=this.$element.data("settings")||{};return this.getItems(e,t)},getEditSettings(t){var e={};return this.isEdit&&(e=elementorFrontend.config.elements.editSettings[this.getModelCID()].attributes),this.getItems(e,t)},getCurrentDeviceSetting(t){return elementorFrontend.getCurrentDeviceSetting(this.getElementSettings(),t)},onInit(){this.isActive(this.getSettings())&&elementorModules.ViewModule.prototype.onInit.apply(this,arguments)},onDestroy(){this.isEdit&&this.removeEditorListeners(),this.unbindEvents&&this.unbindEvents()}})}}]); \ No newline at end of file diff --git a/assets/js/countdown.0e9e688751d29d07a8d3.bundle.min.js b/assets/js/countdown.0e9e688751d29d07a8d3.bundle.min.js new file mode 100644 index 00000000..7b6ca5fb --- /dev/null +++ b/assets/js/countdown.0e9e688751d29d07a8d3.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[416],{475:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default=elementorModules.frontend.handlers.Base.extend({cache:null,cacheElements(){const e=this.$element.find(".elementor-countdown-wrapper");this.cache={$countDown:e,timeInterval:null,elements:{$countdown:e.find(".elementor-countdown-wrapper"),$daysSpan:e.find(".elementor-countdown-days"),$hoursSpan:e.find(".elementor-countdown-hours"),$minutesSpan:e.find(".elementor-countdown-minutes"),$secondsSpan:e.find(".elementor-countdown-seconds"),$expireMessage:e.parent().find(".elementor-countdown-expire--message")},data:{id:this.$element.data("id"),endTime:new Date(1e3*e.data("date")),actions:e.data("expire-actions"),evergreenInterval:e.data("evergreen-interval")}}},onInit(){elementorModules.frontend.handlers.Base.prototype.onInit.apply(this,arguments),this.cacheElements(),00&&parseInt(o.interval,10)===n?o.dueDate:void 0}})}}]); \ No newline at end of file diff --git a/assets/js/countdown.6e87ca40d36793d92aea.bundle.js b/assets/js/countdown.6e87ca40d36793d92aea.bundle.js new file mode 100644 index 00000000..8092c777 --- /dev/null +++ b/assets/js/countdown.6e87ca40d36793d92aea.bundle.js @@ -0,0 +1,148 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["countdown"],{ + +/***/ "../modules/countdown/assets/js/frontend/handlers/countdown.js": +/*!*********************************************************************!*\ + !*** ../modules/countdown/assets/js/frontend/handlers/countdown.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = exports["default"] = elementorModules.frontend.handlers.Base.extend({ + cache: null, + cacheElements() { + const $countDown = this.$element.find('.elementor-countdown-wrapper'); + this.cache = { + $countDown, + timeInterval: null, + elements: { + $countdown: $countDown.find('.elementor-countdown-wrapper'), + $daysSpan: $countDown.find('.elementor-countdown-days'), + $hoursSpan: $countDown.find('.elementor-countdown-hours'), + $minutesSpan: $countDown.find('.elementor-countdown-minutes'), + $secondsSpan: $countDown.find('.elementor-countdown-seconds'), + $expireMessage: $countDown.parent().find('.elementor-countdown-expire--message') + }, + data: { + id: this.$element.data('id'), + endTime: new Date($countDown.data('date') * 1000), + actions: $countDown.data('expire-actions'), + evergreenInterval: $countDown.data('evergreen-interval') + } + }; + }, + onInit() { + elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments); + this.cacheElements(); + if (0 < this.cache.data.evergreenInterval) { + this.cache.data.endTime = this.getEvergreenDate(); + } + this.initializeClock(); + }, + updateClock() { + const self = this, + timeRemaining = this.getTimeRemaining(this.cache.data.endTime); + jQuery.each(timeRemaining.parts, function (timePart) { + const $element = self.cache.elements['$' + timePart + 'Span']; + let partValue = this.toString(); + if (1 === partValue.length) { + partValue = 0 + partValue; + } + if ($element.length) { + $element.text(partValue); + } + }); + if (timeRemaining.total <= 0) { + clearInterval(this.cache.timeInterval); + this.runActions(); + } + }, + initializeClock() { + const self = this; + this.updateClock(); + this.cache.timeInterval = setInterval(function () { + self.updateClock(); + }, 1000); + }, + runActions() { + const self = this; + + // Trigger general event for 3rd patry actions + self.$element.trigger('countdown_expire', self.$element); + if (!this.cache.data.actions) { + return; + } + this.cache.data.actions.forEach(function (action) { + switch (action.type) { + case 'hide': + self.cache.$countDown.hide(); + break; + case 'redirect': + if (action.redirect_url && action.redirect_url.startsWith('http')) { + window.location.href = action.redirect_url; + } + break; + case 'message': + self.cache.elements.$expireMessage.show(); + break; + } + }); + }, + getTimeRemaining(endTime) { + const timeRemaining = endTime - new Date(); + let seconds = Math.floor(timeRemaining / 1000 % 60), + minutes = Math.floor(timeRemaining / 1000 / 60 % 60), + hours = Math.floor(timeRemaining / (1000 * 60 * 60) % 24), + days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24)); + if (days < 0 || hours < 0 || minutes < 0) { + seconds = minutes = hours = days = 0; + } + return { + total: timeRemaining, + parts: { + days, + hours, + minutes, + seconds + } + }; + }, + getEvergreenDate() { + const self = this, + id = this.cache.data.id, + interval = this.cache.data.evergreenInterval, + dueDateKey = id + '-evergreen_due_date', + intervalKey = id + '-evergreen_interval', + localData = { + dueDate: localStorage.getItem(dueDateKey), + interval: localStorage.getItem(intervalKey) + }, + initEvergreen = function () { + var evergreenDueDate = new Date(); + self.cache.data.endTime = evergreenDueDate.setSeconds(evergreenDueDate.getSeconds() + interval); + localStorage.setItem(dueDateKey, self.cache.data.endTime); + localStorage.setItem(intervalKey, interval); + return self.cache.data.endTime; + }; + if (null === localData.dueDate && null === localData.interval) { + return initEvergreen(); + } + if (null !== localData.dueDate && interval !== parseInt(localData.interval, 10)) { + return initEvergreen(); + } + if (localData.dueDate > 0 && parseInt(localData.interval, 10) === interval) { + return localData.dueDate; + } + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=countdown.6e87ca40d36793d92aea.bundle.js.map \ No newline at end of file diff --git a/assets/js/custom-code.js b/assets/js/custom-code.js new file mode 100644 index 00000000..7902bd12 --- /dev/null +++ b/assets/js/custom-code.js @@ -0,0 +1,2706 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../core/app/modules/site-editor/assets/js/context/base-context.js": +/*!*************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/base-context.js ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var React = __webpack_require__(/*! react */ "react"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.BaseContext = void 0; +class BaseContext extends React.Component { + constructor(props) { + super(props); + this.state = { + action: { + current: null, + loading: false, + error: null, + errorMeta: {} + }, + updateActionState: this.updateActionState.bind(this), + resetActionState: this.resetActionState.bind(this) + }; + } + executeAction(name, handler) { + this.updateActionState({ + current: name, + loading: true, + error: null, + errorMeta: {} + }); + return handler().then(response => { + this.resetActionState(); + return Promise.resolve(response); + }).catch(error => { + this.updateActionState({ + current: name, + loading: false, + error: error.message, + errorMeta: error + }); + return Promise.reject(error); + }); + } + updateActionState(data) { + return this.setState(prev => ({ + action: { + ...prev.action, + ...data + } + })); + } + resetActionState() { + this.updateActionState({ + current: null, + loading: false, + error: null, + errorMeta: {} + }); + } +} +exports.BaseContext = BaseContext; +var _default = exports["default"] = BaseContext; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/conditions.js": +/*!***********************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/conditions.js ***! + \***********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Context = exports.ConditionsProvider = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _condition = _interopRequireDefault(__webpack_require__(/*! ./models/condition */ "../core/app/modules/site-editor/assets/js/context/models/condition.js")); +var _conditionsConfig = _interopRequireDefault(__webpack_require__(/*! ./services/conditions-config */ "../core/app/modules/site-editor/assets/js/context/services/conditions-config.js")); +var _baseContext = _interopRequireDefault(__webpack_require__(/*! ./base-context */ "../core/app/modules/site-editor/assets/js/context/base-context.js")); +var _commands = __webpack_require__(/*! ../data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +const Context = exports.Context = _react.default.createContext(); +class ConditionsProvider extends _baseContext.default { + static propTypes = { + children: PropTypes.any.isRequired, + currentTemplate: PropTypes.object.isRequired, + onConditionsSaved: PropTypes.func.isRequired, + validateConflicts: PropTypes.bool + }; + static defaultProps = { + validateConflicts: true + }; + static actions = { + FETCH_CONFIG: 'fetch-config', + SAVE: 'save', + CHECK_CONFLICTS: 'check-conflicts' + }; + + /** + * Holds the conditions config object. + * + * @type {ConditionsConfig} + */ + conditionsConfig = null; + + /** + * ConditionsProvider constructor. + * + * @param {any} props + */ + constructor(props) { + super(props); + this.state = { + ...this.state, + conditionsFetched: false, + conditions: {}, + updateConditionItemState: this.updateConditionItemState.bind(this), + removeConditionItemInState: this.removeConditionItemInState.bind(this), + createConditionItemInState: this.createConditionItemInState.bind(this), + findConditionItemInState: this.findConditionItemInState.bind(this), + saveConditions: this.saveConditions.bind(this) + }; + } + + /** + * Fetch the conditions config, then normalize the conditions and then setup titles for + * the subIds. + */ + componentDidMount() { + this.executeAction(ConditionsProvider.actions.FETCH_CONFIG, () => _conditionsConfig.default.create()).then(conditionsConfig => this.conditionsConfig = conditionsConfig).then(this.normalizeConditionsState.bind(this)).then(() => { + this.setSubIdTitles.bind(this); + this.setState({ + conditionsFetched: true + }); + }); + } + componentDidUpdate(prevProps, prevState) { + if (!prevState.conditionsFetched && this.state.conditionsFetched) { + this.setSubIdTitles(); + } + } + + /** + * Execute a request to save the template conditions. + * + * @return {any} Saved conditions + */ + saveConditions() { + const conditions = Object.values(this.state.conditions).map(condition => condition.forDb()); + return this.executeAction(ConditionsProvider.actions.SAVE, () => $e.data.update(_commands.TemplatesConditions.signature, { + conditions + }, { + id: this.props.currentTemplate.id + })).then(() => { + const contextConditions = Object.values(this.state.conditions).map(condition => condition.forContext()); + this.props.onConditionsSaved(this.props.currentTemplate.id, { + conditions: contextConditions, + instances: this.conditionsConfig.calculateInstances(Object.values(this.state.conditions)), + isActive: !!(Object.keys(this.state.conditions).length && 'publish' === this.props.currentTemplate.status) + }); + }); + } + + /** + * Check for conflicts in the server and mark the condition if there + * is a conflict. + * + * @param {any} condition + */ + checkConflicts(condition) { + return this.executeAction(ConditionsProvider.actions.CHECK_CONFLICTS, () => $e.data.get(_commands.TemplatesConditionsConflicts.signature, { + post_id: this.props.currentTemplate.id, + condition: condition.clone().toString() + })).then(response => this.updateConditionItemState(condition.id, { + conflictErrors: Object.values(response.data) + }, false)); + } + + /** + * Fetching subId titles. + * + * @param {any} condition + * @return {Promise} Titles + */ + fetchSubIdsTitles(condition) { + return new Promise(resolve => { + return elementorCommon.ajax.loadObjects({ + action: 'query_control_value_titles', + ids: _.isArray(condition.subId) ? condition.subId : [condition.subId], + data: { + get_titles: condition.subIdAutocomplete, + unique_id: elementorCommon.helpers.getUniqueId() + }, + success(response) { + resolve(response); + } + }); + }); + } + + /** + * Get the conditions from the template and normalize it to data structure + * that the components can work with. + */ + normalizeConditionsState() { + this.updateConditionsState(() => { + return this.props.currentTemplate.conditions.reduce((current, condition) => { + const conditionObj = new _condition.default({ + ...condition, + default: this.props.currentTemplate.defaultCondition, + options: this.conditionsConfig.getOptions(), + subOptions: this.conditionsConfig.getSubOptions(condition.name), + subIdAutocomplete: this.conditionsConfig.getSubIdAutocomplete(condition.sub), + subIdOptions: condition.subId ? [{ + value: condition.subId, + label: '' + }] : [] + }); + return { + ...current, + [conditionObj.id]: conditionObj + }; + }, {}); + }).then(() => { + Object.values(this.state.conditions).forEach(condition => this.checkConflicts(condition)); + }); + } + + /** + * Set titles to the subIds, + * for the first render of the component. + */ + setSubIdTitles() { + return Object.values(this.state.conditions).forEach(condition => { + if (!condition.subId) { + return; + } + return this.fetchSubIdsTitles(condition).then(response => this.updateConditionItemState(condition.id, { + subIdOptions: [{ + label: Object.values(response)[0], + value: condition.subId + }] + }, false)); + }); + } + + /** + * Update state of specific condition item. + * + * @param {any} id + * @param {any} args + * @param {boolean} shouldCheckConflicts + */ + updateConditionItemState(id, args, shouldCheckConflicts = true) { + if (args.name) { + args.subOptions = this.conditionsConfig.getSubOptions(args.name); + } + if (args.sub || args.name) { + args.subIdAutocomplete = this.conditionsConfig.getSubIdAutocomplete(args.sub); + + // In case that the condition has been changed, it will set the options of the subId + // to empty array to let select2 autocomplete handle the options. + args.subIdOptions = []; + } + this.updateConditionsState(prev => { + const condition = prev[id]; + return { + ...prev, + [id]: condition.clone().set(args) + }; + }).then(() => { + if (shouldCheckConflicts) { + this.checkConflicts(this.findConditionItemInState(id)); + } + }); + } + + /** + * Remove a condition item from the state. + * + * @param {any} id + */ + removeConditionItemInState(id) { + this.updateConditionsState(prev => { + const newConditions = { + ...prev + }; + delete newConditions[id]; + return newConditions; + }); + } + + /** + * Add a new condition item into the state. + * + * @param {boolean} shouldCheckConflicts + */ + createConditionItemInState(shouldCheckConflicts = true) { + const defaultCondition = this.props.currentTemplate.defaultCondition, + newCondition = new _condition.default({ + name: defaultCondition, + default: defaultCondition, + options: this.conditionsConfig.getOptions(), + subOptions: this.conditionsConfig.getSubOptions(defaultCondition), + subIdAutocomplete: this.conditionsConfig.getSubIdAutocomplete('') + }); + this.updateConditionsState(prev => ({ + ...prev, + [newCondition.id]: newCondition + })).then(() => { + if (shouldCheckConflicts) { + this.checkConflicts(newCondition); + } + }); + } + + /** + * Find a condition item from the conditions state. + * + * @param {any} id + * @return {Condition|null} Condition + */ + findConditionItemInState(id) { + return Object.values(this.state.conditions).find(c => c.id === id); + } + + /** + * Update the whole conditions state. + * + * @param {Function} callback + * @return {Promise} Conditions state + */ + updateConditionsState(callback) { + return new Promise(resolve => this.setState(prev => ({ + conditions: callback(prev.conditions) + }), resolve)); + } + + /** + * Renders the provider. + * + * @return {any} Element + */ + render() { + if (this.state.action.current === ConditionsProvider.actions.FETCH_CONFIG) { + if (this.state.error) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Error:', 'elementor-pro'), " ", this.state.error); + } + if (this.state.loading) { + return /*#__PURE__*/_react.default.createElement("h3", null, __('Loading', 'elementor-pro'), "..."); + } + } + return /*#__PURE__*/_react.default.createElement(Context.Provider, { + value: this.state + }, this.props.children); + } +} +exports.ConditionsProvider = ConditionsProvider; +var _default = exports["default"] = ConditionsProvider; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/models/condition.js": +/*!*****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/models/condition.js ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class Condition { + id = elementorCommon.helpers.getUniqueId(); + default = ''; + type = 'include'; + name = ''; + sub = ''; + subId = ''; + options = []; + subOptions = []; + subIdAutocomplete = []; + subIdOptions = []; + conflictErrors = []; + constructor(args) { + this.set(args); + } + set(args) { + Object.assign(this, args); + return this; + } + clone() { + return Object.assign(new Condition(), this); + } + remove(keys) { + if (!Array.isArray(keys)) { + keys = [keys]; + } + keys.forEach(key => { + delete this[key]; + }); + return this; + } + only(keys) { + if (!Array.isArray(keys)) { + keys = [keys]; + } + const keysToRemove = Object.keys(this).filter(conditionKey => !keys.includes(conditionKey)); + this.remove(keysToRemove); + return this; + } + toJson() { + return JSON.stringify(this); + } + toString() { + return this.forDb().filter(item => item).join('/'); + } + forDb() { + return [this.type, this.name, this.sub, this.subId]; + } + forContext() { + return { + type: this.type, + name: this.name, + sub: this.sub, + subId: this.subId + }; + } +} +exports["default"] = Condition; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/context/services/conditions-config.js": +/*!***************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/context/services/conditions-config.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ConditionsConfig = void 0; +var _commands = __webpack_require__(/*! ../../data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +class ConditionsConfig { + static instance; + config = null; + constructor(config) { + this.config = config; + } + + /** + * @return {Promise} Conditions config + */ + static create() { + if (ConditionsConfig.instance) { + return Promise.resolve(ConditionsConfig.instance); + } + return $e.data.get(_commands.ConditionsConfig.signature, {}, { + refresh: true + }).then(response => { + ConditionsConfig.instance = new ConditionsConfig(response.data); + return ConditionsConfig.instance; + }); + } + + /** + * Get main options for condition name. + * + * @return {Array} Condition options + */ + getOptions() { + return this.getSubOptions('general', true).map(({ + label, + value + }) => { + return { + label, + value + }; + }); + } + + /** + * Get the sub options for the select. + * + * @param {string} itemName + * @param {boolean} isSubItem + * @return {Array} Sub options + */ + getSubOptions(itemName, isSubItem = false) { + const config = this.config[itemName]; + if (!config) { + return []; + } + return [{ + label: config.all_label, + value: isSubItem ? itemName : '' + }, ...config.sub_conditions.map(subName => { + const subConfig = this.config[subName]; + return { + label: subConfig.label, + value: subName, + children: subConfig.sub_conditions.length ? this.getSubOptions(subName, true) : null + }; + })]; + } + + /** + * Get the autocomplete property from the conditions config + * + * @param {string} sub + * @return {{}|any} Conditions autocomplete + */ + getSubIdAutocomplete(sub) { + const config = this.config[sub]; + if (!config || !('object' === typeof config.controls)) { + return {}; + } + const controls = Object.values(config.controls); + if (!controls?.[0]?.autocomplete) { + return {}; + } + return controls[0].autocomplete; + } + + /** + * Calculate instances from the conditions. + * + * @param {Array} conditions + * @return {Object} Conditions Instances + */ + calculateInstances(conditions) { + let instances = conditions.reduce((current, condition) => { + if ('exclude' === condition.type) { + return current; + } + const key = condition.sub || condition.name, + config = this.config[key]; + if (!config) { + return current; + } + const instanceLabel = condition.subId ? `${config.label} #${condition.subId}` : config.all_label; + return { + ...current, + [key]: instanceLabel + }; + }, {}); + if (0 === Object.keys(instances).length) { + instances = [__('No instances', 'elementor-pro')]; + } + return instances; + } +} +exports.ConditionsConfig = ConditionsConfig; +var _default = exports["default"] = ConditionsConfig; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ConditionsConfig = void 0; +class ConditionsConfig extends $e.modules.CommandData { + static signature = 'site-editor/conditions-config'; + static getEndpointFormat() { + return 'site-editor/conditions-config/{id}'; + } +} +exports.ConditionsConfig = ConditionsConfig; +var _default = exports["default"] = ConditionsConfig; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/index.js": +/*!************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/index.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ConditionsConfig", ({ + enumerable: true, + get: function () { + return _conditionsConfig.ConditionsConfig; + } +})); +Object.defineProperty(exports, "Templates", ({ + enumerable: true, + get: function () { + return _templates.Templates; + } +})); +Object.defineProperty(exports, "TemplatesConditions", ({ + enumerable: true, + get: function () { + return _templatesConditions.TemplatesConditions; + } +})); +Object.defineProperty(exports, "TemplatesConditionsConflicts", ({ + enumerable: true, + get: function () { + return _templatesConditionsConflicts.TemplatesConditionsConflicts; + } +})); +var _templates = __webpack_require__(/*! ./templates */ "../core/app/modules/site-editor/assets/js/data/commands/templates.js"); +var _conditionsConfig = __webpack_require__(/*! ./conditions-config */ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js"); +var _templatesConditions = __webpack_require__(/*! ./templates-conditions */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js"); +var _templatesConditionsConflicts = __webpack_require__(/*! ./templates-conditions-conflicts */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js"); + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js": +/*!*************************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditionsConflicts = void 0; +class TemplatesConditionsConflicts extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions-conflicts'; + static getEndpointFormat() { + return `${TemplatesConditionsConflicts.signature}/{id}`; + } +} +exports.TemplatesConditionsConflicts = TemplatesConditionsConflicts; +var _default = exports["default"] = TemplatesConditionsConflicts; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js": +/*!***************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditions = void 0; +class TemplatesConditions extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions'; + static getEndpointFormat() { + return 'site-editor/templates-conditions/{id}'; + } +} +exports.TemplatesConditions = TemplatesConditions; +var _default = exports["default"] = TemplatesConditions; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates.js": +/*!****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Templates = void 0; +class Templates extends $e.modules.CommandData { + static signature = 'site-editor/templates'; + static getEndpointFormat() { + return 'site-editor/templates/{id}'; + } +} +exports.Templates = Templates; +var _default = exports["default"] = Templates; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/component.js": +/*!*******************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/component.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var dataCommands = _interopRequireWildcard(__webpack_require__(/*! ./commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + static namespace = 'site-editor'; + getNamespace() { + return this.constructor.namespace; + } + defaultData() { + return this.importCommands(dataCommands); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js": +/*!*********************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js ***! + \*********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _reactDom = __webpack_require__(/*! react-dom */ "react-dom"); +var _react = __webpack_require__(/*! react */ "react"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConditionButtonPortal = props => { + const [shouldCreatePortal, setShouldCreatePortal] = (0, _react.useState)(false), + portalRoot = document.getElementById('portal-root'); + (0, _react.useEffect)(() => { + setShouldCreatePortal(!!portalRoot); + }, [portalRoot]); + return shouldCreatePortal ? (0, _reactDom.createPortal)(props.children, portalRoot) : null; +}; +ConditionButtonPortal.propTypes = { + children: PropTypes.oneOfType([PropTypes.node, PropTypes.string]) +}; +var _default = exports["default"] = ConditionButtonPortal; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js": +/*!*****************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var sprintf = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["sprintf"]; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionConflicts; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionConflicts(props) { + if (!props.conflicts.length) { + return ''; + } + const conflictLinks = props.conflicts.map(conflict => { + return /*#__PURE__*/_react.default.createElement(_appUi.Button, { + key: conflict.template_id, + target: "_blank", + url: conflict.edit_url, + text: conflict.template_title + }); + }); + return /*#__PURE__*/_react.default.createElement(_appUi.Text, { + className: "e-site-editor-conditions__conflict", + variant: "sm" + }, sprintf(/* Translators: %s: a list of conflicted templates */ + __('We noticed that you already applied %s with the same condition.', 'elementor-pro'), conflictLinks), /*#__PURE__*/_react.default.createElement("br", null), __("To continue, set different conditions for each so they don't conflict.", 'elementor-pro')); +} +ConditionConflicts.propTypes = { + conflicts: PropTypes.array.isRequired +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionName; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionName(props) { + // Hide for template types that has another default, like single & archive. + if ('general' !== props.default) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + name: e.target.value, + sub: '', + subId: '' + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: props.options, + value: props.name, + onChange: onChange + })); +} +ConditionName.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + options: PropTypes.array.isRequired, + default: PropTypes.string.isRequired +}; +ConditionName.defaultProps = { + name: '' +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js": +/*!**************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionSubId; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +/** + * Main component. + * + * @param {any} props + * @return {any} Element + * @class + */ +function ConditionSubId(props) { + const settings = _react.default.useMemo(() => Object.keys(props.subIdAutocomplete).length ? getSettings(props.subIdAutocomplete) : null, [props.subIdAutocomplete]); + if (!props.sub || !settings) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + subId: e.target.value + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select2, { + onChange: onChange, + value: props.subId, + settings: settings, + options: props.subIdOptions + })); +} + +/** + * Get settings for the select2 base on the autocomplete settings, + * that passes as a prop + * + * @param {any} autocomplete + * @return {Object} Settings + */ +function getSettings(autocomplete) { + return { + allowClear: false, + placeholder: __('All', 'elementor-pro'), + dir: elementorCommon.config.isRTL ? 'rtl' : 'ltr', + ajax: { + transport(params, success, failure) { + return elementorCommon.ajax.addRequest('pro_panel_posts_control_filter_autocomplete', { + data: { + q: params.data.q, + autocomplete + }, + success, + error: failure + }); + }, + data(params) { + return { + q: params.term, + page: params.page + }; + }, + cache: true + }, + escapeMarkup(markup) { + return markup; + }, + minimumInputLength: 1 + }; +} +ConditionSubId.propTypes = { + subIdAutocomplete: PropTypes.object, + id: PropTypes.string.isRequired, + sub: PropTypes.string, + subId: PropTypes.string, + updateConditions: PropTypes.func, + subIdOptions: PropTypes.array +}; +ConditionSubId.defaultProps = { + subId: '', + subIdOptions: [] +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js": +/*!***********************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionSub; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionSub(props) { + if ('general' === props.name || !props.subOptions.length) { + return ''; + } + const onChange = e => props.updateConditions(props.id, { + sub: e.target.value, + subId: '' + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper" + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: props.subOptions, + value: props.sub, + onChange: onChange + })); +} +ConditionSub.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + sub: PropTypes.string.isRequired, + subOptions: PropTypes.array.isRequired +}; +ConditionSub.defaultProps = { + sub: '', + subOptions: {} +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionType; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +function ConditionType(props) { + const wrapperRef = _react.default.createRef(); + const options = [{ + label: __('Include', 'elementor-pro'), + value: 'include' + }, { + label: __('Exclude', 'elementor-pro'), + value: 'exclude' + }]; + const onChange = e => { + props.updateConditions(props.id, { + type: e.target.value + }); + }; + _react.default.useEffect(() => { + wrapperRef.current.setAttribute('data-elementor-condition-type', props.type); + }); + return /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__input-wrapper e-site-editor-conditions__input-wrapper--condition-type", + ref: wrapperRef + }, /*#__PURE__*/_react.default.createElement(_appUi.Select, { + options: options, + value: props.type, + onChange: onChange + })); +} +ConditionType.propTypes = { + updateConditions: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + type: PropTypes.string.isRequired +}; +ConditionType.defaultProps = { + type: '' +}; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js": +/*!*************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionsRows; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _conditions = __webpack_require__(/*! ../../context/conditions */ "../core/app/modules/site-editor/assets/js/context/conditions.js"); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _conditionType = _interopRequireDefault(__webpack_require__(/*! ./condition-type */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-type.js")); +var _conditionName = _interopRequireDefault(__webpack_require__(/*! ./condition-name */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-name.js")); +var _conditionSub = _interopRequireDefault(__webpack_require__(/*! ./condition-sub */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub.js")); +var _conditionSubId = _interopRequireDefault(__webpack_require__(/*! ./condition-sub-id */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-sub-id.js")); +var _conditionConflicts = _interopRequireDefault(__webpack_require__(/*! ./condition-conflicts */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-conflicts.js")); +var _conditionButtonPortal = _interopRequireDefault(__webpack_require__(/*! ./condition-button-portal */ "../core/app/modules/site-editor/assets/js/pages/conditions/condition-button-portal.js")); +function ConditionsRows(props) { + const { + conditions, + createConditionItemInState: create, + updateConditionItemState: update, + removeConditionItemInState: remove, + saveConditions: save, + action, + resetActionState + } = _react.default.useContext(_conditions.Context); + const rows = Object.values(conditions).map(condition => /*#__PURE__*/_react.default.createElement("div", { + key: condition.id + }, /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__row" + }, /*#__PURE__*/_react.default.createElement("div", { + className: `e-site-editor-conditions__row-controls ${condition.conflictErrors.length && 'e-site-editor-conditions__row-controls--error'}` + }, /*#__PURE__*/_react.default.createElement(_conditionType.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__row-controls-inner" + }, /*#__PURE__*/_react.default.createElement(_conditionName.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement(_conditionSub.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })), /*#__PURE__*/_react.default.createElement(_conditionSubId.default, (0, _extends2.default)({}, condition, { + updateConditions: update + })))), /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "e-site-editor-conditions__remove-condition", + text: __('Delete', 'elementor-pro'), + icon: "eicon-close", + hideText: true, + onClick: () => remove(condition.id) + })), /*#__PURE__*/_react.default.createElement(_conditionConflicts.default, { + conflicts: condition.conflictErrors + }))); + const SaveButton = () => { + return /*#__PURE__*/_react.default.createElement(_appUi.Button, { + variant: "contained", + color: "primary", + size: "lg", + hideText: isSaving, + icon: isSaving ? 'eicon-loading eicon-animation-spin' : '', + text: __('Save & Close', 'elementor-pro'), + onClick: () => save().then(props.onAfterSave) + }); + }; + const isSaving = action.current === _conditions.ConditionsProvider.actions.SAVE && action.loading; + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, action.error && /*#__PURE__*/_react.default.createElement(_appUi.Dialog, { + text: action.error, + dismissButtonText: __('Go Back', 'elementor-pro'), + dismissButtonOnClick: resetActionState, + approveButtonText: __('Learn More', 'elementor-pro'), + approveButtonColor: "link", + approveButtonUrl: "https://go.elementor.com/app-theme-builder-conditions-load-issue", + approveButtonTarget: "_target" + }), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__rows" + }, rows), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__add-button-container" + }, /*#__PURE__*/_react.default.createElement(_appUi.Button, { + className: "e-site-editor-conditions__add-button", + variant: "contained", + size: "lg", + text: __('Add Condition', 'elementor-pro'), + onClick: create + })), /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__footer" + }, props?.loadPortal ? /*#__PURE__*/_react.default.createElement(_conditionButtonPortal.default, null, /*#__PURE__*/_react.default.createElement(SaveButton, null)) : /*#__PURE__*/_react.default.createElement(SaveButton, null))); +} +ConditionsRows.propTypes = { + onAfterSave: PropTypes.func, + loadPortal: PropTypes.bool +}; + +/***/ }), + +/***/ "../modules/custom-code/assets/js/admin/publish-metabox/conditions-modal.js": +/*!**********************************************************************************!*\ + !*** ../modules/custom-code/assets/js/admin/publish-metabox/conditions-modal.js ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = ConditionsModal; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _conditions = _interopRequireDefault(__webpack_require__(/*! ./conditions */ "../modules/custom-code/assets/js/admin/publish-metabox/conditions.js")); +var _conditionsConfig = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app-modules/site-editor/assets/js/context/services/conditions-config */ "../core/app/modules/site-editor/assets/js/context/services/conditions-config.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +/** + * Publish metabox conditions ( 'Edit' modal ). + */ +function ConditionsModal() { + const [showModal, setShowModal] = (0, _react.useState)(false), + [data, setData] = (0, _react.useState)({ + conditions: null, + instances: null + }), + isSavedOnce = (0, _react.useRef)(false), + post = elementorProAdmin.customCode.post, + elements = (0, _react.useMemo)(() => { + return { + $form: jQuery('#post'), + $formConditions: jQuery(''), + $publishButton: jQuery('#publish'), + title: { + $label: jQuery('#title-prompt-text'), + $input: jQuery('#title') + } + }; + }, []), + onPostSubmit = () => { + const { + title + } = elements; + if (!title.$input.attr('value').length) { + title.$label.addClass('screen-reader-text'); + title.$input.attr('value', __('Elementor Custom-Code #', 'elementor-pro') + elementorProAdmin.customCode.post.ID); + } + }, + onPublishClick = e => { + if ('auto-draft' === post.post_status && !showModal && !isSavedOnce.current) { + e.preventDefault(); + + // Set default condition for new post. + const conditions = [{ + name: 'general', + sub: '', + subId: '', + type: 'include' + }]; + setData(prevState => ({ + ...prevState, + conditions + })); + setShowModal(true); + } + }, + onConditionsSaved = args => { + const conditions = args.conditions, + instances = Object.values(args.instances).join(','), + { + $form, + $formConditions, + $publishButton + } = elements; + isSavedOnce.current = true; + setData(prevState => ({ + ...prevState, + conditions, + instances + })); + + // Temporary workaround for applying conditions for draft custom code post. + if ('auto-draft' === post.post_status || 'draft' === post.post_status) { + $formConditions.attr('type', 'hidden').attr('name', '_conditions').attr('value', JSON.stringify(conditions)).appendTo($form); + } + $publishButton.trigger('click'); + setShowModal(false); + }, + initData = async () => { + const conditionsConfig = await _conditionsConfig.default.create(); + $e.data.get('site-editor/templates-conditions', { + id: post.ID + }, { + refresh: true + }).then(result => { + // Since the 'state' format is different from db one. + const conditions = Object.values(result.data).map(condition => ({ + type: condition.type, + name: condition.name, + sub: condition.sub_name, + subId: condition.sub_id + })), + instances = Object.values(conditionsConfig.calculateInstances(conditions)).join(','); + setData(prevState => ({ + ...prevState, + conditions, + instances + })); + }); + }, + bindEvents = () => { + elements.$publishButton.on('click', onPublishClick); + elements.$form.on('submit', onPostSubmit); + }; + (0, _react.useEffect)(() => { + initData(); + bindEvents(); + }, []); + if (!post || !data.conditions) { + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_appUi.Text, { + tag: "span" + }, __('Loading', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_appUi.Icon, { + className: "spinner" + })); + } + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_appUi.Text, { + tag: "span", + className: "post-conditions-display" + }, /*#__PURE__*/_react.default.createElement("b", null, data.instances + ' ')), /*#__PURE__*/_react.default.createElement(_appUi.Button, { + onClick: () => setShowModal(true), + text: __('Edit', 'elementor-pro'), + variant: "underlined" + }), /*#__PURE__*/_react.default.createElement(_appUi.ModalProvider, { + show: showModal, + setShow: setShowModal, + title: __('Publish Settings', 'elementor-pro'), + icon: "eps-app__logo eicon-elementor" + }, /*#__PURE__*/_react.default.createElement(_appUi.CssGrid, { + columns: 1, + spacing: 700 + }, /*#__PURE__*/_react.default.createElement("section", null, /*#__PURE__*/_react.default.createElement(_conditions.default, { + id: post.ID, + status: post.post_status, + conditions: data.conditions, + onConditionsSaved: onConditionsSaved, + onAfterSave: () => {} + }))))); +} +ConditionsModal.propTypes = { + children: PropTypes.object // Disable parent requirement. +}; + +/***/ }), + +/***/ "../modules/custom-code/assets/js/admin/publish-metabox/conditions.js": +/*!****************************************************************************!*\ + !*** ../modules/custom-code/assets/js/admin/publish-metabox/conditions.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = Conditions; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _appUi = __webpack_require__(/*! @elementor/app-ui */ "@elementor/app-ui"); +var _conditions = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app-modules/site-editor/assets/js/context/conditions */ "../core/app/modules/site-editor/assets/js/context/conditions.js")); +var _conditionsRows = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app-modules/site-editor/assets/js/pages/conditions/conditions-rows */ "../core/app/modules/site-editor/assets/js/pages/conditions/conditions-rows.js")); +function Conditions(props) { + const currentTemplateProps = { + ...props, + defaultCondition: 'general' + }, + onConditionsSaved = (id, args) => { + $e.data.setCache($e.components.get('site-editor'), 'site-editor/templates-conditions', { + id + }, args.conditions); + props.onConditionsSaved(args); + }; + return /*#__PURE__*/_react.default.createElement("section", { + className: "e-site-editor-conditions" + }, /*#__PURE__*/_react.default.createElement("div", { + className: "e-site-editor-conditions__header" + }, /*#__PURE__*/_react.default.createElement("img", { + className: "e-site-editor-conditions__header-image", + src: `${elementorAppProConfig.baseUrl}/modules/theme-builder/assets/images/conditions-tab.svg`, + alt: __('Conditions', 'elementor-pro') + }), /*#__PURE__*/_react.default.createElement(_appUi.Heading, { + variant: "h1", + tag: "h1" + }, __('Where Do You Want to Display Your Code?', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_appUi.Text, { + variant: "md" + }, __('Set the conditions that determine where your code snippet is used throughout your site.', 'elementor-pro'), /*#__PURE__*/_react.default.createElement("br", null), __('For example, choose \'Entire Site\' to display the code snippet across your site.', 'elementor-pro'))), /*#__PURE__*/_react.default.createElement(_conditions.default, { + validateConflicts: false, + currentTemplate: currentTemplateProps, + onConditionsSaved: onConditionsSaved + }, /*#__PURE__*/_react.default.createElement(_conditionsRows.default, { + onAfterSave: props.onAfterSave, + loadPortal: false + }))); +} +Conditions.propTypes = { + id: PropTypes.number, + status: PropTypes.string.isRequired, + conditions: PropTypes.array, + onConditionsSaved: PropTypes.func, + onAfterSave: PropTypes.func.isRequired +}; +Conditions.defaultProps = { + conditions: [], + onConditionsSaved: () => {} +}; + +/***/ }), + +/***/ "../node_modules/object-assign/index.js": +/*!**********************************************!*\ + !*** ../node_modules/object-assign/index.js ***! + \**********************************************/ +/***/ ((module) => { + +"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + + +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/checkPropTypes.js": +/*!****************************************************!*\ + !*** ../node_modules/prop-types/checkPropTypes.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var printWarning = function() {}; + +if (true) { + var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); + var loggedTypeFailures = {}; + var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); + + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) { /**/ } + }; +} + +/** + * Assert that the values match with the type specs. + * Error messages are memorized and will only be shown once. + * + * @param {object} typeSpecs Map of name to a ReactPropType + * @param {object} values Runtime values that need to be type-checked + * @param {string} location e.g. "prop", "context", "child context" + * @param {string} componentName Name of the component for error messages. + * @param {?Function} getStack Returns the component stack. + * @private + */ +function checkPropTypes(typeSpecs, values, location, componentName, getStack) { + if (true) { + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== 'function') { + var err = Error( + (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.' + ); + err.name = 'Invariant Violation'; + throw err; + } + error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); + } catch (ex) { + error = ex; + } + if (error && !(error instanceof Error)) { + printWarning( + (componentName || 'React class') + ': type specification of ' + + location + ' `' + typeSpecName + '` is invalid; the type checker ' + + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + + 'You may have forgotten to pass an argument to the type checker ' + + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + + 'shape all require an argument).' + ); + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var stack = getStack ? getStack() : ''; + + printWarning( + 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') + ); + } + } + } + } +} + +/** + * Resets warning cache when testing. + * + * @private + */ +checkPropTypes.resetWarningCache = function() { + if (true) { + loggedTypeFailures = {}; + } +} + +module.exports = checkPropTypes; + + +/***/ }), + +/***/ "../node_modules/prop-types/factoryWithTypeCheckers.js": +/*!*************************************************************!*\ + !*** ../node_modules/prop-types/factoryWithTypeCheckers.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); +var assign = __webpack_require__(/*! object-assign */ "../node_modules/object-assign/index.js"); + +var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); +var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); +var checkPropTypes = __webpack_require__(/*! ./checkPropTypes */ "../node_modules/prop-types/checkPropTypes.js"); + +var printWarning = function() {}; + +if (true) { + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; +} + +function emptyFunctionThatReturnsNull() { + return null; +} + +module.exports = function(isValidElement, throwOnDirectAccess) { + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + /** + * Collection of methods that allow declaration and validation of props that are + * supplied to React components. Example usage: + * + * var Props = require('ReactPropTypes'); + * var MyArticle = React.createClass({ + * propTypes: { + * // An optional string prop named "description". + * description: Props.string, + * + * // A required enum prop named "category". + * category: Props.oneOf(['News','Photos']).isRequired, + * + * // A prop named "dialog" that requires an instance of Dialog. + * dialog: Props.instanceOf(Dialog).isRequired + * }, + * render: function() { ... } + * }); + * + * A more formal specification of how these methods are used: + * + * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) + * decl := ReactPropTypes.{type}(.isRequired)? + * + * Each and every declaration produces a function with the same signature. This + * allows the creation of custom validation functions. For example: + * + * var MyLink = React.createClass({ + * propTypes: { + * // An optional string or URI prop named "href". + * href: function(props, propName, componentName) { + * var propValue = props[propName]; + * if (propValue != null && typeof propValue !== 'string' && + * !(propValue instanceof URI)) { + * return new Error( + * 'Expected a string or an URI for ' + propName + ' in ' + + * componentName + * ); + * } + * } + * }, + * render: function() {...} + * }); + * + * @internal + */ + + var ANONYMOUS = '<>'; + + // Important! + // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. + var ReactPropTypes = { + array: createPrimitiveTypeChecker('array'), + bigint: createPrimitiveTypeChecker('bigint'), + bool: createPrimitiveTypeChecker('boolean'), + func: createPrimitiveTypeChecker('function'), + number: createPrimitiveTypeChecker('number'), + object: createPrimitiveTypeChecker('object'), + string: createPrimitiveTypeChecker('string'), + symbol: createPrimitiveTypeChecker('symbol'), + + any: createAnyTypeChecker(), + arrayOf: createArrayOfTypeChecker, + element: createElementTypeChecker(), + elementType: createElementTypeTypeChecker(), + instanceOf: createInstanceTypeChecker, + node: createNodeChecker(), + objectOf: createObjectOfTypeChecker, + oneOf: createEnumTypeChecker, + oneOfType: createUnionTypeChecker, + shape: createShapeTypeChecker, + exact: createStrictShapeTypeChecker, + }; + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + /*eslint-disable no-self-compare*/ + function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return x !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } + } + /*eslint-enable no-self-compare*/ + + /** + * We use an Error-like object for backward compatibility as people may call + * PropTypes directly and inspect their output. However, we don't use real + * Errors anymore. We don't inspect their stack anyway, and creating them + * is prohibitively expensive if they are created too often, such as what + * happens in oneOfType() for any type before the one that matched. + */ + function PropTypeError(message, data) { + this.message = message; + this.data = data && typeof data === 'object' ? data: {}; + this.stack = ''; + } + // Make `instanceof Error` still work for returned errors. + PropTypeError.prototype = Error.prototype; + + function createChainableTypeChecker(validate) { + if (true) { + var manualPropTypeCallCache = {}; + var manualPropTypeWarningCount = 0; + } + function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { + componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; + + if (secret !== ReactPropTypesSecret) { + if (throwOnDirectAccess) { + // New behavior only for users of `prop-types` package + var err = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + + 'Use `PropTypes.checkPropTypes()` to call them. ' + + 'Read more at http://fb.me/use-check-prop-types' + ); + err.name = 'Invariant Violation'; + throw err; + } else if ( true && typeof console !== 'undefined') { + // Old behavior for people using React.PropTypes + var cacheKey = componentName + ':' + propName; + if ( + !manualPropTypeCallCache[cacheKey] && + // Avoid spamming the console because they are often not actionable except for lib authors + manualPropTypeWarningCount < 3 + ) { + printWarning( + 'You are manually calling a React.PropTypes validation ' + + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + + 'and will throw in the standalone `prop-types` package. ' + + 'You may be seeing this warning due to a third-party PropTypes ' + + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.' + ); + manualPropTypeCallCache[cacheKey] = true; + manualPropTypeWarningCount++; + } + } + } + if (props[propName] == null) { + if (isRequired) { + if (props[propName] === null) { + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); + } + return null; + } else { + return validate(props, propName, componentName, location, propFullName); + } + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; + } + + function createPrimitiveTypeChecker(expectedType) { + function validate(props, propName, componentName, location, propFullName, secret) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== expectedType) { + // `propValue` being instance of, say, date/regexp, pass the 'object' + // check, but we can offer a more precise error message here rather than + // 'of type `object`'. + var preciseType = getPreciseType(propValue); + + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'), + {expectedType: expectedType} + ); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createAnyTypeChecker() { + return createChainableTypeChecker(emptyFunctionThatReturnsNull); + } + + function createArrayOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); + } + var propValue = props[propName]; + if (!Array.isArray(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); + } + for (var i = 0; i < propValue.length; i++) { + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!isValidElement(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!ReactIs.isValidElementType(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createInstanceTypeChecker(expectedClass) { + function validate(props, propName, componentName, location, propFullName) { + if (!(props[propName] instanceof expectedClass)) { + var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createEnumTypeChecker(expectedValues) { + if (!Array.isArray(expectedValues)) { + if (true) { + if (arguments.length > 1) { + printWarning( + 'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' + + 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).' + ); + } else { + printWarning('Invalid argument supplied to oneOf, expected an array.'); + } + } + return emptyFunctionThatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + for (var i = 0; i < expectedValues.length; i++) { + if (is(propValue, expectedValues[i])) { + return null; + } + } + + var valuesString = JSON.stringify(expectedValues, function replacer(key, value) { + var type = getPreciseType(value); + if (type === 'symbol') { + return String(value); + } + return value; + }); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); + } + return createChainableTypeChecker(validate); + } + + function createObjectOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); + } + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); + } + for (var key in propValue) { + if (has(propValue, key)) { + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createUnionTypeChecker(arrayOfTypeCheckers) { + if (!Array.isArray(arrayOfTypeCheckers)) { + true ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : 0; + return emptyFunctionThatReturnsNull; + } + + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (typeof checker !== 'function') { + printWarning( + 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.' + ); + return emptyFunctionThatReturnsNull; + } + } + + function validate(props, propName, componentName, location, propFullName) { + var expectedTypes = []; + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret); + if (checkerResult == null) { + return null; + } + if (checkerResult.data && has(checkerResult.data, 'expectedType')) { + expectedTypes.push(checkerResult.data.expectedType); + } + } + var expectedTypesMessage = (expectedTypes.length > 0) ? ', expected one of type [' + expectedTypes.join(', ') + ']': ''; + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.')); + } + return createChainableTypeChecker(validate); + } + + function createNodeChecker() { + function validate(props, propName, componentName, location, propFullName) { + if (!isNode(props[propName])) { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function invalidValidatorError(componentName, location, propFullName, key, type) { + return new PropTypeError( + (componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + type + '`.' + ); + } + + function createShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + for (var key in shapeTypes) { + var checker = shapeTypes[key]; + if (typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createStrictShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + // We need to check all keys in case some are required but missing from props. + var allKeys = assign({}, props[propName], shapeTypes); + for (var key in allKeys) { + var checker = shapeTypes[key]; + if (has(shapeTypes, key) && typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + if (!checker) { + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') + ); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + + return createChainableTypeChecker(validate); + } + + function isNode(propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + case 'undefined': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (propValue === null || isValidElement(propValue)) { + return true; + } + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } + } + } else { + return false; + } + + return true; + default: + return false; + } + } + + function isSymbol(propType, propValue) { + // Native Symbol. + if (propType === 'symbol') { + return true; + } + + // falsy value can't be a Symbol + if (!propValue) { + return false; + } + + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' + if (propValue['@@toStringTag'] === 'Symbol') { + return true; + } + + // Fallback for non-spec compliant Symbols which are polyfilled. + if (typeof Symbol === 'function' && propValue instanceof Symbol) { + return true; + } + + return false; + } + + // Equivalent of `typeof` but with special handling for array and regexp. + function getPropType(propValue) { + var propType = typeof propValue; + if (Array.isArray(propValue)) { + return 'array'; + } + if (propValue instanceof RegExp) { + // Old webkits (at least until Android 4.0) return 'function' rather than + // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ + // passes PropTypes.object. + return 'object'; + } + if (isSymbol(propType, propValue)) { + return 'symbol'; + } + return propType; + } + + // This handles more types than `getPropType`. Only used for error messages. + // See `createPrimitiveTypeChecker`. + function getPreciseType(propValue) { + if (typeof propValue === 'undefined' || propValue === null) { + return '' + propValue; + } + var propType = getPropType(propValue); + if (propType === 'object') { + if (propValue instanceof Date) { + return 'date'; + } else if (propValue instanceof RegExp) { + return 'regexp'; + } + } + return propType; + } + + // Returns a string that is postfixed to a warning about an invalid type. + // For example, "undefined" or "of type array" + function getPostfixForTypeWarning(value) { + var type = getPreciseType(value); + switch (type) { + case 'array': + case 'object': + return 'an ' + type; + case 'boolean': + case 'date': + case 'regexp': + return 'a ' + type; + default: + return type; + } + } + + // Returns class name of the object, if any. + function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return ANONYMOUS; + } + return propValue.constructor.name; + } + + ReactPropTypes.checkPropTypes = checkPropTypes; + ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/index.js": +/*!*******************************************!*\ + !*** ../node_modules/prop-types/index.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +if (true) { + var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); + + // By explicitly using `prop-types` you are opting into new development behavior. + // http://fb.me/prop-types-in-prod + var throwOnDirectAccess = true; + module.exports = __webpack_require__(/*! ./factoryWithTypeCheckers */ "../node_modules/prop-types/factoryWithTypeCheckers.js")(ReactIs.isElement, throwOnDirectAccess); +} else {} + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/ReactPropTypesSecret.js": +/*!**************************************************************!*\ + !*** ../node_modules/prop-types/lib/ReactPropTypesSecret.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + +module.exports = ReactPropTypesSecret; + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/has.js": +/*!*********************************************!*\ + !*** ../node_modules/prop-types/lib/has.js ***! + \*********************************************/ +/***/ ((module) => { + +module.exports = Function.call.bind(Object.prototype.hasOwnProperty); + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js": +/*!************************************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** @license React v16.13.1 + * react-is.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + + + +if (true) { + (function() { +'use strict'; + +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + +var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; +var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; +var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8; +var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; +var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4; +var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7; + +function isValidElementType(type) { + return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill. + type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE); +} + +function typeOf(object) { + if (typeof object === 'object' && object !== null) { + var $$typeof = object.$$typeof; + + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + var type = object.type; + + switch (type) { + case REACT_ASYNC_MODE_TYPE: + case REACT_CONCURRENT_MODE_TYPE: + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + return type; + + default: + var $$typeofType = type && type.$$typeof; + + switch ($$typeofType) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + case REACT_PROVIDER_TYPE: + return $$typeofType; + + default: + return $$typeof; + } + + } + + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + + return undefined; +} // AsyncMode is deprecated along with isAsyncMode + +var AsyncMode = REACT_ASYNC_MODE_TYPE; +var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE; +var ContextConsumer = REACT_CONTEXT_TYPE; +var ContextProvider = REACT_PROVIDER_TYPE; +var Element = REACT_ELEMENT_TYPE; +var ForwardRef = REACT_FORWARD_REF_TYPE; +var Fragment = REACT_FRAGMENT_TYPE; +var Lazy = REACT_LAZY_TYPE; +var Memo = REACT_MEMO_TYPE; +var Portal = REACT_PORTAL_TYPE; +var Profiler = REACT_PROFILER_TYPE; +var StrictMode = REACT_STRICT_MODE_TYPE; +var Suspense = REACT_SUSPENSE_TYPE; +var hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated + +function isAsyncMode(object) { + { + if (!hasWarnedAboutDeprecatedIsAsyncMode) { + hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint + + console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.'); + } + } + + return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE; +} +function isConcurrentMode(object) { + return typeOf(object) === REACT_CONCURRENT_MODE_TYPE; +} +function isContextConsumer(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; +} +function isContextProvider(object) { + return typeOf(object) === REACT_PROVIDER_TYPE; +} +function isElement(object) { + return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; +} +function isForwardRef(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; +} +function isFragment(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; +} +function isLazy(object) { + return typeOf(object) === REACT_LAZY_TYPE; +} +function isMemo(object) { + return typeOf(object) === REACT_MEMO_TYPE; +} +function isPortal(object) { + return typeOf(object) === REACT_PORTAL_TYPE; +} +function isProfiler(object) { + return typeOf(object) === REACT_PROFILER_TYPE; +} +function isStrictMode(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; +} +function isSuspense(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; +} + +exports.AsyncMode = AsyncMode; +exports.ConcurrentMode = ConcurrentMode; +exports.ContextConsumer = ContextConsumer; +exports.ContextProvider = ContextProvider; +exports.Element = Element; +exports.ForwardRef = ForwardRef; +exports.Fragment = Fragment; +exports.Lazy = Lazy; +exports.Memo = Memo; +exports.Portal = Portal; +exports.Profiler = Profiler; +exports.StrictMode = StrictMode; +exports.Suspense = Suspense; +exports.isAsyncMode = isAsyncMode; +exports.isConcurrentMode = isConcurrentMode; +exports.isContextConsumer = isContextConsumer; +exports.isContextProvider = isContextProvider; +exports.isElement = isElement; +exports.isForwardRef = isForwardRef; +exports.isFragment = isFragment; +exports.isLazy = isLazy; +exports.isMemo = isMemo; +exports.isPortal = isPortal; +exports.isProfiler = isProfiler; +exports.isStrictMode = isStrictMode; +exports.isSuspense = isSuspense; +exports.isValidElementType = isValidElementType; +exports.typeOf = typeOf; + })(); +} + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/index.js": +/*!*****************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/index.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +if (false) {} else { + module.exports = __webpack_require__(/*! ./cjs/react-is.development.js */ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js"); +} + + +/***/ }), + +/***/ "react": +/*!************************!*\ + !*** external "React" ***! + \************************/ +/***/ ((module) => { + +"use strict"; +module.exports = React; + +/***/ }), + +/***/ "react-dom": +/*!***************************!*\ + !*** external "ReactDOM" ***! + \***************************/ +/***/ ((module) => { + +"use strict"; +module.exports = ReactDOM; + +/***/ }), + +/***/ "elementor-ai-admin": +/*!**********************************************!*\ + !*** external "__UNSTABLE__elementorAI.App" ***! + \**********************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = __UNSTABLE__elementorAI.App; + +/***/ }), + +/***/ "@elementor/app-ui": +/*!*********************************************!*\ + !*** external "elementorAppPackages.appUi" ***! + \*********************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorAppPackages.appUi; + +/***/ }), + +/***/ "@wordpress/i18n": +/*!**************************!*\ + !*** external "wp.i18n" ***! + \**************************/ +/***/ ((module) => { + +"use strict"; +module.exports = wp.i18n; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/extends.js": +/*!*********************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/extends.js ***! + \*********************************************************/ +/***/ ((module) => { + +function _extends() { + return module.exports = _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends.apply(null, arguments); +} +module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js": +/*!***********************************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! + \***********************************************************************/ +/***/ ((module) => { + +function _interopRequireDefault(e) { + return e && e.__esModule ? e : { + "default": e + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +var exports = __webpack_exports__; +/*!*******************************************************!*\ + !*** ../modules/custom-code/assets/js/admin/admin.js ***! + \*******************************************************/ +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _component = _interopRequireDefault(__webpack_require__(/*! elementor-pro-app-modules/site-editor/assets/js/data/component */ "../core/app/modules/site-editor/assets/js/data/component.js")); +var _conditionsModal = _interopRequireDefault(__webpack_require__(/*! ./publish-metabox/conditions-modal */ "../modules/custom-code/assets/js/admin/publish-metabox/conditions-modal.js")); +var _elementorAiAdmin = _interopRequireDefault(__webpack_require__(/*! elementor-ai-admin */ "elementor-ai-admin")); +class CustomCode extends elementorModules.Module { + constructor() { + super(); + jQuery(this.initialize.bind(this)); + } + initialize() { + $e.components.register(new _component.default()); + + // eslint-disable-next-line react/no-deprecated + ReactDOM.render(/*#__PURE__*/_react.default.createElement(_conditionsModal.default, null), document.querySelector('.post-conditions')); + this.addTipsyToFields(); + this.addDescription(); + this.addLocationChangeHandler(); + this.addOpenAIButton(); + this.setOptionsPlacementVisibility('elementor_body_end' === jQuery('#location').val()); + } + addTipsyToFields() { + jQuery('.elementor-field-label i[data-info]').tipsy({ + title() { + return this.getAttribute('data-info'); + }, + gravity: () => 's' + }); + } + addDescription() { + const description = '

    ' + __('Manage and create all of your custom code here.
    Organize all of your custom code and incorporate code snippets in your site. Add tracking codes, meta titles, and other scripts. Set display conditions, locations, and priority all from one place.', 'elementor-pro') + ' ' + __('Learn more', 'elementor-pro') + '' + '

    '; + jQuery(description).insertBefore('.wp-header-end'); + } + addLocationChangeHandler() { + jQuery('#location').on('change', e => { + this.setOptionsPlacementVisibility('elementor_body_end' === e.target.value); + }); + } + addOpenAIButton() { + const $buttonOpenAI = jQuery(``); + $buttonOpenAI.on('click', event => { + event.preventDefault(); + const isRTL = elementorCommon.config.isRTL; + const rootElement = document.createElement('div'); + document.body.append(rootElement); + + // eslint-disable-next-line react/no-deprecated + ReactDOM.render(/*#__PURE__*/_react.default.createElement(_elementorAiAdmin.default, { + type: 'code', + getControlValue: () => document.querySelector('.CodeMirror').CodeMirror.getValue(), + setControlValue: value => document.querySelector('.CodeMirror').CodeMirror.setValue(value), + additionalOptions: { + codeLanguage: 'html' + }, + onClose: () => { + ReactDOM.unmountComponentAtNode(rootElement); // eslint-disable-line react/no-deprecated + rootElement.parentNode.removeChild(rootElement); + }, + isRTL: isRTL + }), rootElement); + }); + jQuery('.elementor-field.location.elementor-field-select').after($buttonOpenAI); + } + setOptionsPlacementVisibility(state) { + const $optionsPlacement = jQuery('.elementor-custom-code-options-placement'); + $optionsPlacement.toggleClass('show', state); + } +} +exports["default"] = CustomCode; +elementorProAdmin.customCode = new CustomCode(); +})(); + +/******/ })() +; +//# sourceMappingURL=custom-code.js.map \ No newline at end of file diff --git a/assets/js/custom-code.min.js b/assets/js/custom-code.min.js new file mode 100644 index 00000000..8ad5e611 --- /dev/null +++ b/assets/js/custom-code.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +(()=>{var e={9804:(e,t,n)=>{"use strict";var o=n(1594);Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.BaseContext=void 0;class BaseContext extends o.Component{constructor(e){super(e),this.state={action:{current:null,loading:!1,error:null,errorMeta:{}},updateActionState:this.updateActionState.bind(this),resetActionState:this.resetActionState.bind(this)}}executeAction(e,t){return this.updateActionState({current:e,loading:!0,error:null,errorMeta:{}}),t().then((e=>(this.resetActionState(),Promise.resolve(e)))).catch((t=>(this.updateActionState({current:e,loading:!1,error:t.message,errorMeta:t}),Promise.reject(t))))}updateActionState(e){return this.setState((t=>({action:{...t.action,...e}})))}resetActionState(){this.updateActionState({current:null,loading:!1,error:null,errorMeta:{}})}}t.BaseContext=BaseContext;t.default=BaseContext},4737:(e,t,n)=>{"use strict";var o=n(2688),i=n(2470).__,s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Context=t.ConditionsProvider=void 0;var r=s(n(1594)),a=s(n(8067)),d=s(n(2075)),l=s(n(9804)),u=n(5559);const c=t.Context=r.default.createContext();class ConditionsProvider extends l.default{static propTypes={children:o.any.isRequired,currentTemplate:o.object.isRequired,onConditionsSaved:o.func.isRequired,validateConflicts:o.bool};static defaultProps={validateConflicts:!0};static actions={FETCH_CONFIG:"fetch-config",SAVE:"save",CHECK_CONFLICTS:"check-conflicts"};conditionsConfig=null;constructor(e){super(e),this.state={...this.state,conditionsFetched:!1,conditions:{},updateConditionItemState:this.updateConditionItemState.bind(this),removeConditionItemInState:this.removeConditionItemInState.bind(this),createConditionItemInState:this.createConditionItemInState.bind(this),findConditionItemInState:this.findConditionItemInState.bind(this),saveConditions:this.saveConditions.bind(this)}}componentDidMount(){this.executeAction(ConditionsProvider.actions.FETCH_CONFIG,(()=>d.default.create())).then((e=>this.conditionsConfig=e)).then(this.normalizeConditionsState.bind(this)).then((()=>{this.setSubIdTitles.bind(this),this.setState({conditionsFetched:!0})}))}componentDidUpdate(e,t){!t.conditionsFetched&&this.state.conditionsFetched&&this.setSubIdTitles()}saveConditions(){const e=Object.values(this.state.conditions).map((e=>e.forDb()));return this.executeAction(ConditionsProvider.actions.SAVE,(()=>$e.data.update(u.TemplatesConditions.signature,{conditions:e},{id:this.props.currentTemplate.id}))).then((()=>{const e=Object.values(this.state.conditions).map((e=>e.forContext()));this.props.onConditionsSaved(this.props.currentTemplate.id,{conditions:e,instances:this.conditionsConfig.calculateInstances(Object.values(this.state.conditions)),isActive:!(!Object.keys(this.state.conditions).length||"publish"!==this.props.currentTemplate.status)})}))}checkConflicts(e){return this.executeAction(ConditionsProvider.actions.CHECK_CONFLICTS,(()=>$e.data.get(u.TemplatesConditionsConflicts.signature,{post_id:this.props.currentTemplate.id,condition:e.clone().toString()}))).then((t=>this.updateConditionItemState(e.id,{conflictErrors:Object.values(t.data)},!1)))}fetchSubIdsTitles(e){return new Promise((t=>elementorCommon.ajax.loadObjects({action:"query_control_value_titles",ids:_.isArray(e.subId)?e.subId:[e.subId],data:{get_titles:e.subIdAutocomplete,unique_id:elementorCommon.helpers.getUniqueId()},success(e){t(e)}})))}normalizeConditionsState(){this.updateConditionsState((()=>this.props.currentTemplate.conditions.reduce(((e,t)=>{const n=new a.default({...t,default:this.props.currentTemplate.defaultCondition,options:this.conditionsConfig.getOptions(),subOptions:this.conditionsConfig.getSubOptions(t.name),subIdAutocomplete:this.conditionsConfig.getSubIdAutocomplete(t.sub),subIdOptions:t.subId?[{value:t.subId,label:""}]:[]});return{...e,[n.id]:n}}),{}))).then((()=>{Object.values(this.state.conditions).forEach((e=>this.checkConflicts(e)))}))}setSubIdTitles(){return Object.values(this.state.conditions).forEach((e=>{if(e.subId)return this.fetchSubIdsTitles(e).then((t=>this.updateConditionItemState(e.id,{subIdOptions:[{label:Object.values(t)[0],value:e.subId}]},!1)))}))}updateConditionItemState(e,t,n=!0){t.name&&(t.subOptions=this.conditionsConfig.getSubOptions(t.name)),(t.sub||t.name)&&(t.subIdAutocomplete=this.conditionsConfig.getSubIdAutocomplete(t.sub),t.subIdOptions=[]),this.updateConditionsState((n=>{const o=n[e];return{...n,[e]:o.clone().set(t)}})).then((()=>{n&&this.checkConflicts(this.findConditionItemInState(e))}))}removeConditionItemInState(e){this.updateConditionsState((t=>{const n={...t};return delete n[e],n}))}createConditionItemInState(e=!0){const t=this.props.currentTemplate.defaultCondition,n=new a.default({name:t,default:t,options:this.conditionsConfig.getOptions(),subOptions:this.conditionsConfig.getSubOptions(t),subIdAutocomplete:this.conditionsConfig.getSubIdAutocomplete("")});this.updateConditionsState((e=>({...e,[n.id]:n}))).then((()=>{e&&this.checkConflicts(n)}))}findConditionItemInState(e){return Object.values(this.state.conditions).find((t=>t.id===e))}updateConditionsState(e){return new Promise((t=>this.setState((t=>({conditions:e(t.conditions)})),t)))}render(){if(this.state.action.current===ConditionsProvider.actions.FETCH_CONFIG){if(this.state.error)return r.default.createElement("h3",null,i("Error:","elementor-pro")," ",this.state.error);if(this.state.loading)return r.default.createElement("h3",null,i("Loading","elementor-pro"),"...")}return r.default.createElement(c.Provider,{value:this.state},this.props.children)}}t.ConditionsProvider=ConditionsProvider;t.default=ConditionsProvider},8067:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class Condition{id=elementorCommon.helpers.getUniqueId();default="";type="include";name="";sub="";subId="";options=[];subOptions=[];subIdAutocomplete=[];subIdOptions=[];conflictErrors=[];constructor(e){this.set(e)}set(e){return Object.assign(this,e),this}clone(){return Object.assign(new Condition,this)}remove(e){return Array.isArray(e)||(e=[e]),e.forEach((e=>{delete this[e]})),this}only(e){Array.isArray(e)||(e=[e]);const t=Object.keys(this).filter((t=>!e.includes(t)));return this.remove(t),this}toJson(){return JSON.stringify(this)}toString(){return this.forDb().filter((e=>e)).join("/")}forDb(){return[this.type,this.name,this.sub,this.subId]}forContext(){return{type:this.type,name:this.name,sub:this.sub,subId:this.subId}}}t.default=Condition},2075:(e,t,n)=>{"use strict";var o=n(2470).__;Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.ConditionsConfig=void 0;var i=n(5559);class ConditionsConfig{static instance;config=null;constructor(e){this.config=e}static create(){return ConditionsConfig.instance?Promise.resolve(ConditionsConfig.instance):$e.data.get(i.ConditionsConfig.signature,{},{refresh:!0}).then((e=>(ConditionsConfig.instance=new ConditionsConfig(e.data),ConditionsConfig.instance)))}getOptions(){return this.getSubOptions("general",!0).map((({label:e,value:t})=>({label:e,value:t})))}getSubOptions(e,t=!1){const n=this.config[e];return n?[{label:n.all_label,value:t?e:""},...n.sub_conditions.map((e=>{const t=this.config[e];return{label:t.label,value:e,children:t.sub_conditions.length?this.getSubOptions(e,!0):null}}))]:[]}getSubIdAutocomplete(e){const t=this.config[e];if(!t||"object"!=typeof t.controls)return{};const n=Object.values(t.controls);return n?.[0]?.autocomplete?n[0].autocomplete:{}}calculateInstances(e){let t=e.reduce(((e,t)=>{if("exclude"===t.type)return e;const n=t.sub||t.name,o=this.config[n];if(!o)return e;const i=t.subId?`${o.label} #${t.subId}`:o.all_label;return{...e,[n]:i}}),{});return 0===Object.keys(t).length&&(t=[o("No instances","elementor-pro")]),t}}t.ConditionsConfig=ConditionsConfig;t.default=ConditionsConfig},7952:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.ConditionsConfig=void 0;class ConditionsConfig extends $e.modules.CommandData{static signature="site-editor/conditions-config";static getEndpointFormat(){return"site-editor/conditions-config/{id}"}}t.ConditionsConfig=ConditionsConfig;t.default=ConditionsConfig},5559:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ConditionsConfig",{enumerable:!0,get:function(){return i.ConditionsConfig}}),Object.defineProperty(t,"Templates",{enumerable:!0,get:function(){return o.Templates}}),Object.defineProperty(t,"TemplatesConditions",{enumerable:!0,get:function(){return s.TemplatesConditions}}),Object.defineProperty(t,"TemplatesConditionsConflicts",{enumerable:!0,get:function(){return r.TemplatesConditionsConflicts}});var o=n(7636),i=n(7952),s=n(9591),r=n(7821)},7821:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditionsConflicts=void 0;class TemplatesConditionsConflicts extends $e.modules.CommandData{static signature="site-editor/templates-conditions-conflicts";static getEndpointFormat(){return`${TemplatesConditionsConflicts.signature}/{id}`}}t.TemplatesConditionsConflicts=TemplatesConditionsConflicts;t.default=TemplatesConditionsConflicts},9591:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditions=void 0;class TemplatesConditions extends $e.modules.CommandData{static signature="site-editor/templates-conditions";static getEndpointFormat(){return"site-editor/templates-conditions/{id}"}}t.TemplatesConditions=TemplatesConditions;t.default=TemplatesConditions},7636:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Templates=void 0;class Templates extends $e.modules.CommandData{static signature="site-editor/templates";static getEndpointFormat(){return"site-editor/templates/{id}"}}t.Templates=Templates;t.default=Templates},2239:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&{}.hasOwnProperty.call(e,s)){var r=i?Object.getOwnPropertyDescriptor(e,s):null;r&&(r.get||r.set)?Object.defineProperty(o,s,r):o[s]=e[s]}return o.default=e,n&&n.set(e,o),o}(n(5559));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}class Component extends $e.modules.ComponentBase{static namespace="site-editor";getNamespace(){return this.constructor.namespace}defaultData(){return this.importCommands(o)}}t.default=Component},7010:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=n(5206),i=n(1594),s=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&{}.hasOwnProperty.call(e,s)){var r=i?Object.getOwnPropertyDescriptor(e,s):null;r&&(r.get||r.set)?Object.defineProperty(o,s,r):o[s]=e[s]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}const ConditionButtonPortal=e=>{const[t,n]=(0,i.useState)(!1),s=document.getElementById("portal-root");return(0,i.useEffect)((()=>{n(!!s)}),[s]),t?(0,o.createPortal)(e.children,s):null};ConditionButtonPortal.propTypes={children:s.oneOfType([s.node,s.string])};t.default=ConditionButtonPortal},7624:(e,t,n)=>{"use strict";var o=n(2470).sprintf,i=n(2470).__,s=n(2688),r=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionConflicts;var a=r(n(1594)),d=n(7401);function ConditionConflicts(e){if(!e.conflicts.length)return"";const t=e.conflicts.map((e=>a.default.createElement(d.Button,{key:e.template_id,target:"_blank",url:e.edit_url,text:e.template_title})));return a.default.createElement(d.Text,{className:"e-site-editor-conditions__conflict",variant:"sm"},o(i("We noticed that you already applied %s with the same condition.","elementor-pro"),t),a.default.createElement("br",null),i("To continue, set different conditions for each so they don't conflict.","elementor-pro"))}ConditionConflicts.propTypes={conflicts:s.array.isRequired}},1360:(e,t,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionName;var s=i(n(1594)),r=n(7401);function ConditionName(e){if("general"!==e.default)return"";return s.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},s.default.createElement(r.Select,{options:e.options,value:e.name,onChange:t=>e.updateConditions(e.id,{name:t.target.value,sub:"",subId:""})}))}ConditionName.propTypes={updateConditions:o.func.isRequired,id:o.string.isRequired,name:o.string.isRequired,options:o.array.isRequired,default:o.string.isRequired},ConditionName.defaultProps={name:""}},2943:(e,t,n)=>{"use strict";var o=n(2470).__,i=n(2688),s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionSubId;var r=s(n(1594)),a=n(7401);function ConditionSubId(e){const t=r.default.useMemo((()=>Object.keys(e.subIdAutocomplete).length?function getSettings(e){return{allowClear:!1,placeholder:o("All","elementor-pro"),dir:elementorCommon.config.isRTL?"rtl":"ltr",ajax:{transport:(t,n,o)=>elementorCommon.ajax.addRequest("pro_panel_posts_control_filter_autocomplete",{data:{q:t.data.q,autocomplete:e},success:n,error:o}),data:e=>({q:e.term,page:e.page}),cache:!0},escapeMarkup:e=>e,minimumInputLength:1}}(e.subIdAutocomplete):null),[e.subIdAutocomplete]);if(!e.sub||!t)return"";return r.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},r.default.createElement(a.Select2,{onChange:t=>e.updateConditions(e.id,{subId:t.target.value}),value:e.subId,settings:t,options:e.subIdOptions}))}ConditionSubId.propTypes={subIdAutocomplete:i.object,id:i.string.isRequired,sub:i.string,subId:i.string,updateConditions:i.func,subIdOptions:i.array},ConditionSubId.defaultProps={subId:"",subIdOptions:[]}},2437:(e,t,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionSub;var s=i(n(1594)),r=n(7401);function ConditionSub(e){if("general"===e.name||!e.subOptions.length)return"";return s.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper"},s.default.createElement(r.Select,{options:e.subOptions,value:e.sub,onChange:t=>e.updateConditions(e.id,{sub:t.target.value,subId:""})}))}ConditionSub.propTypes={updateConditions:o.func.isRequired,id:o.string.isRequired,name:o.string.isRequired,sub:o.string.isRequired,subOptions:o.array.isRequired},ConditionSub.defaultProps={sub:"",subOptions:{}}},1303:(e,t,n)=>{"use strict";var o=n(2470).__,i=n(2688),s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionType;var r=s(n(1594)),a=n(7401);function ConditionType(e){const t=r.default.createRef(),n=[{label:o("Include","elementor-pro"),value:"include"},{label:o("Exclude","elementor-pro"),value:"exclude"}];return r.default.useEffect((()=>{t.current.setAttribute("data-elementor-condition-type",e.type)})),r.default.createElement("div",{className:"e-site-editor-conditions__input-wrapper e-site-editor-conditions__input-wrapper--condition-type",ref:t},r.default.createElement(a.Select,{options:n,value:e.type,onChange:t=>{e.updateConditions(e.id,{type:t.target.value})}}))}ConditionType.propTypes={updateConditions:i.func.isRequired,id:i.string.isRequired,type:i.string.isRequired},ConditionType.defaultProps={type:""}},8927:(e,t,n)=>{"use strict";var o=n(2470).__,i=n(2688),s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionsRows;var r=s(n(1594)),a=s(n(8304)),d=n(4737),l=n(7401),u=s(n(1303)),c=s(n(1360)),p=s(n(2437)),f=s(n(2943)),m=s(n(7624)),C=s(n(7010));function ConditionsRows(e){const{conditions:t,createConditionItemInState:n,updateConditionItemState:i,removeConditionItemInState:s,saveConditions:h,action:b,resetActionState:_}=r.default.useContext(d.Context),g=Object.values(t).map((e=>r.default.createElement("div",{key:e.id},r.default.createElement("div",{className:"e-site-editor-conditions__row"},r.default.createElement("div",{className:`e-site-editor-conditions__row-controls ${e.conflictErrors.length&&"e-site-editor-conditions__row-controls--error"}`},r.default.createElement(u.default,(0,a.default)({},e,{updateConditions:i})),r.default.createElement("div",{className:"e-site-editor-conditions__row-controls-inner"},r.default.createElement(c.default,(0,a.default)({},e,{updateConditions:i})),r.default.createElement(p.default,(0,a.default)({},e,{updateConditions:i})),r.default.createElement(f.default,(0,a.default)({},e,{updateConditions:i})))),r.default.createElement(l.Button,{className:"e-site-editor-conditions__remove-condition",text:o("Delete","elementor-pro"),icon:"eicon-close",hideText:!0,onClick:()=>s(e.id)})),r.default.createElement(m.default,{conflicts:e.conflictErrors})))),SaveButton=()=>r.default.createElement(l.Button,{variant:"contained",color:"primary",size:"lg",hideText:v,icon:v?"eicon-loading eicon-animation-spin":"",text:o("Save & Close","elementor-pro"),onClick:()=>h().then(e.onAfterSave)}),v=b.current===d.ConditionsProvider.actions.SAVE&&b.loading;return r.default.createElement(r.default.Fragment,null,b.error&&r.default.createElement(l.Dialog,{text:b.error,dismissButtonText:o("Go Back","elementor-pro"),dismissButtonOnClick:_,approveButtonText:o("Learn More","elementor-pro"),approveButtonColor:"link",approveButtonUrl:"https://go.elementor.com/app-theme-builder-conditions-load-issue",approveButtonTarget:"_target"}),r.default.createElement("div",{className:"e-site-editor-conditions__rows"},g),r.default.createElement("div",{className:"e-site-editor-conditions__add-button-container"},r.default.createElement(l.Button,{className:"e-site-editor-conditions__add-button",variant:"contained",size:"lg",text:o("Add Condition","elementor-pro"),onClick:n})),r.default.createElement("div",{className:"e-site-editor-conditions__footer"},e?.loadPortal?r.default.createElement(C.default,null,r.default.createElement(SaveButton,null)):r.default.createElement(SaveButton,null)))}ConditionsRows.propTypes={onAfterSave:i.func,loadPortal:i.bool}},9212:(e,t,n)=>{"use strict";var o=n(2470).__,i=n(2688),s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=ConditionsModal;var r=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(t);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&{}.hasOwnProperty.call(e,s)){var r=i?Object.getOwnPropertyDescriptor(e,s):null;r&&(r.get||r.set)?Object.defineProperty(o,s,r):o[s]=e[s]}return o.default=e,n&&n.set(e,o),o}(n(1594)),a=n(7401),d=s(n(12)),l=s(n(2075));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function ConditionsModal(){const[e,t]=(0,r.useState)(!1),[n,i]=(0,r.useState)({conditions:null,instances:null}),s=(0,r.useRef)(!1),u=elementorProAdmin.customCode.post,c=(0,r.useMemo)((()=>({$form:jQuery("#post"),$formConditions:jQuery(""),$publishButton:jQuery("#publish"),title:{$label:jQuery("#title-prompt-text"),$input:jQuery("#title")}})),[]),onPostSubmit=()=>{const{title:e}=c;e.$input.attr("value").length||(e.$label.addClass("screen-reader-text"),e.$input.attr("value",o("Elementor Custom-Code #","elementor-pro")+elementorProAdmin.customCode.post.ID))},onPublishClick=n=>{if("auto-draft"===u.post_status&&!e&&!s.current){n.preventDefault();const e=[{name:"general",sub:"",subId:"",type:"include"}];i((t=>({...t,conditions:e}))),t(!0)}};return(0,r.useEffect)((()=>{(async()=>{const e=await l.default.create();$e.data.get("site-editor/templates-conditions",{id:u.ID},{refresh:!0}).then((t=>{const n=Object.values(t.data).map((e=>({type:e.type,name:e.name,sub:e.sub_name,subId:e.sub_id}))),o=Object.values(e.calculateInstances(n)).join(",");i((e=>({...e,conditions:n,instances:o})))}))})(),c.$publishButton.on("click",onPublishClick),c.$form.on("submit",onPostSubmit)}),[]),u&&n.conditions?r.default.createElement(r.default.Fragment,null,r.default.createElement(a.Text,{tag:"span",className:"post-conditions-display"},r.default.createElement("b",null,n.instances+" ")),r.default.createElement(a.Button,{onClick:()=>t(!0),text:o("Edit","elementor-pro"),variant:"underlined"}),r.default.createElement(a.ModalProvider,{show:e,setShow:t,title:o("Publish Settings","elementor-pro"),icon:"eps-app__logo eicon-elementor"},r.default.createElement(a.CssGrid,{columns:1,spacing:700},r.default.createElement("section",null,r.default.createElement(d.default,{id:u.ID,status:u.post_status,conditions:n.conditions,onConditionsSaved:e=>{const n=e.conditions,o=Object.values(e.instances).join(","),{$form:r,$formConditions:a,$publishButton:d}=c;s.current=!0,i((e=>({...e,conditions:n,instances:o}))),"auto-draft"!==u.post_status&&"draft"!==u.post_status||a.attr("type","hidden").attr("name","_conditions").attr("value",JSON.stringify(n)).appendTo(r),d.trigger("click"),t(!1)},onAfterSave:()=>{}}))))):r.default.createElement(r.default.Fragment,null,r.default.createElement(a.Text,{tag:"span"},o("Loading","elementor-pro")),r.default.createElement(a.Icon,{className:"spinner"}))}ConditionsModal.propTypes={children:i.object}},12:(e,t,n)=>{"use strict";var o=n(2470).__,i=n(2688),s=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=Conditions;var r=s(n(1594)),a=n(7401),d=s(n(4737)),l=s(n(8927));function Conditions(e){const t={...e,defaultCondition:"general"};return r.default.createElement("section",{className:"e-site-editor-conditions"},r.default.createElement("div",{className:"e-site-editor-conditions__header"},r.default.createElement("img",{className:"e-site-editor-conditions__header-image",src:`${elementorAppProConfig.baseUrl}/modules/theme-builder/assets/images/conditions-tab.svg`,alt:o("Conditions","elementor-pro")}),r.default.createElement(a.Heading,{variant:"h1",tag:"h1"},o("Where Do You Want to Display Your Code?","elementor-pro")),r.default.createElement(a.Text,{variant:"md"},o("Set the conditions that determine where your code snippet is used throughout your site.","elementor-pro"),r.default.createElement("br",null),o("For example, choose 'Entire Site' to display the code snippet across your site.","elementor-pro"))),r.default.createElement(d.default,{validateConflicts:!1,currentTemplate:t,onConditionsSaved:(t,n)=>{$e.data.setCache($e.components.get("site-editor"),"site-editor/templates-conditions",{id:t},n.conditions),e.onConditionsSaved(n)}},r.default.createElement(l.default,{onAfterSave:e.onAfterSave,loadPortal:!1})))}Conditions.propTypes={id:i.number,status:i.string.isRequired,conditions:i.array,onConditionsSaved:i.func,onAfterSave:i.func.isRequired},Conditions.defaultProps={conditions:[],onConditionsSaved:()=>{}}},362:(e,t,n)=>{"use strict";var o=n(6441);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,e.exports=function(){function shim(e,t,n,i,s,r){if(r!==o){var a=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw a.name="Invariant Violation",a}}function getShim(){return shim}shim.isRequired=shim;var e={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return e.PropTypes=e,e}},2688:(e,t,n)=>{e.exports=n(362)()},6441:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},1594:e=>{"use strict";e.exports=React},5206:e=>{"use strict";e.exports=ReactDOM},1755:e=>{"use strict";e.exports=__UNSTABLE__elementorAI.App},7401:e=>{"use strict";e.exports=elementorAppPackages.appUi},2470:e=>{"use strict";e.exports=wp.i18n},8304:e=>{function _extends(){return e.exports=_extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t{e.exports=function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports}},t={};function __webpack_require__(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,__webpack_require__),i.exports}(()=>{"use strict";var e=__webpack_require__(2470).__,t=__webpack_require__(6784);var n=t(__webpack_require__(1594)),o=t(__webpack_require__(2239)),i=t(__webpack_require__(9212)),s=t(__webpack_require__(1755));class CustomCode extends elementorModules.Module{constructor(){super(),jQuery(this.initialize.bind(this))}initialize(){$e.components.register(new o.default),ReactDOM.render(n.default.createElement(i.default,null),document.querySelector(".post-conditions")),this.addTipsyToFields(),this.addDescription(),this.addLocationChangeHandler(),this.addOpenAIButton(),this.setOptionsPlacementVisibility("elementor_body_end"===jQuery("#location").val())}addTipsyToFields(){jQuery(".elementor-field-label i[data-info]").tipsy({title(){return this.getAttribute("data-info")},gravity:()=>"s"})}addDescription(){const t="

    "+e("Manage and create all of your custom code here.
    Organize all of your custom code and incorporate code snippets in your site. Add tracking codes, meta titles, and other scripts. Set display conditions, locations, and priority all from one place.","elementor-pro")+' '+e("Learn more","elementor-pro")+"

    ";jQuery(t).insertBefore(".wp-header-end")}addLocationChangeHandler(){jQuery("#location").on("change",(e=>{this.setOptionsPlacementVisibility("elementor_body_end"===e.target.value)}))}addOpenAIButton(){const t=jQuery(``);t.on("click",(e=>{e.preventDefault();const t=elementorCommon.config.isRTL,o=document.createElement("div");document.body.append(o),ReactDOM.render(n.default.createElement(s.default,{type:"code",getControlValue:()=>document.querySelector(".CodeMirror").CodeMirror.getValue(),setControlValue:e=>document.querySelector(".CodeMirror").CodeMirror.setValue(e),additionalOptions:{codeLanguage:"html"},onClose:()=>{ReactDOM.unmountComponentAtNode(o),o.parentNode.removeChild(o)},isRTL:t}),o)})),jQuery(".elementor-field.location.elementor-field-select").after(t)}setOptionsPlacementVisibility(e){jQuery(".elementor-custom-code-options-placement").toggleClass("show",e)}}elementorProAdmin.customCode=new CustomCode})()})(); \ No newline at end of file diff --git a/assets/js/d241154d3774d66da9eb.bundle.min.js b/assets/js/d241154d3774d66da9eb.bundle.min.js new file mode 100644 index 00000000..38604468 --- /dev/null +++ b/assets/js/d241154d3774d66da9eb.bundle.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict";(self.webpackChunkelementor_pro=self.webpackChunkelementor_pro||[]).push([[93],{3093:(e,t,n)=>{var o=n(2470).__,a=n(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=a(n(8300));class TemplateQueryControl extends i.default{ui(){return{...super.ui(),newButton:'button[data-action="new"]',editButton:'button[data-action="edit"]'}}events(){return{...super.events(),"click @ui.newButton":"onNewButtonClicked","click @ui.editButton":"onEditButtonClicked"}}onRender(...e){super.onRender(...e),this.toggleButtons(this.getControlValue())}onBaseInputChange(...e){super.onBaseInputChange(...e),this.toggleButtons(this.getInputValue(e[0].currentTarget))}toggleButtons(e){e?this.showEditTemplateButton():this.showNewTemplateButton()}showNewTemplateButton(){const e=this.ui?.newButton?.get(0),t=this.ui?.editButton?.get(0);e&&(e.style.display="block"),t&&(t.style.display="none")}showEditTemplateButton(){const e=this.ui.newButton.get(0),t=this.ui.editButton.get(0);e&&(e.style.display="none"),t&&(t.style.display="block")}async onNewButtonClicked(){this.createTemplate()}createTemplate(){this.confirmSaveBeforeTemplateCreateDialog||(this.confirmSaveBeforeTemplateCreateDialog=elementorCommon.dialogsManager.createWidget("confirm",{id:"e-confirm-save-before-template-create",headerMessage:o("Save Changes","elementor-pro"),message:o("Would you like to save the changes you've made?","elementor-pro"),position:{my:"center center",at:"center center"},strings:{confirm:o("Save","elementor-pro"),cancel:o("Discard","elementor-pro")},onConfirm:async()=>{await this.onConfirmCreateTemplate()}})),this.confirmSaveBeforeTemplateCreateDialog.show()}async onConfirmCreateTemplate(){$e.internal("panel/state-loading");const e=await this.createAndSetTemplate();this.afterAction("new",e),$e.internal("panel/state-ready")}async createAndSetTemplate(){const e=this.model.get("name"),t=this.options.container.controls[e].actions.new.document_config.type,n=this.getTemplateSourceTypeValue(),o=await $e.data.create("library/templates",{type:t,page_settings:{source:n}}),a=parseInt(o.data.template_id);return this.setValue(a),a}getTemplateSourceTypeValue(){return"repeater"===this.options?.container?.args?.type?this.options.container.renderer.args.settings.attributes._skin||void 0:this.options.container.controls._skin?this.options.container.panel.getControlView("_skin").getControlValue():void 0}async switchDocument(e){await $e.run("editor/documents/switch",{id:parseInt(e),mode:"save"});const t=elementor.documents.getCurrent();t.config.container_attributes&&t.config.container_attributes.class&&t.$element.addClass(t.config.container_attributes.class)}async onEditButtonClicked(){this.afterAction("edit",this.getControlValue())}getSelect2Placeholder(){return{id:"",text:o("Start typing its name","elementor-pro")}}async afterAction(e,t){"switch_document"===("new"===e?this.ui.newButton[0].getAttribute("data-after-action"):this.ui.editButton[0].getAttribute("data-after-action"))?await this.switchDocument(t):window.open(this.getThemeBuilderURL(t),"_blank")}getThemeBuilderURL(e){return`${elementor.config.admin_url}post.php?post=${e}&action=elementor`}}t.default=TemplateQueryControl}}]); \ No newline at end of file diff --git a/assets/js/display-conditions.js b/assets/js/display-conditions.js new file mode 100644 index 00000000..d4185bd3 --- /dev/null +++ b/assets/js/display-conditions.js @@ -0,0 +1,5598 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../core/app/assets/js/utils.js": +/*!**************************************!*\ + !*** ../core/app/assets/js/utils.js ***! + \**************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.replaceUtmPlaceholders = exports.htmlDecodeTextContent = exports.arrayToClassName = void 0; +// Copied from Core. +const arrayToClassName = (array, action) => { + return array.filter(item => 'object' === typeof item ? Object.entries(item)[0][1] : item).map(item => { + const value = 'object' === typeof item ? Object.entries(item)[0][0] : item; + return action ? action(value) : value; + }).join(' '); +}; +exports.arrayToClassName = arrayToClassName; +const htmlDecodeTextContent = input => { + const doc = new DOMParser().parseFromString(input, 'text/html'); + return doc.documentElement.textContent; +}; +exports.htmlDecodeTextContent = htmlDecodeTextContent; +const replaceUtmPlaceholders = (link = '', utms = {}) => { + if (!link || !utms) { + return link; + } + Object.keys(utms).forEach(key => { + const match = new RegExp(`%%${key}%%`, 'g'); + link = link.replace(match, utms[key]); + }); + return link; +}; +exports.replaceUtmPlaceholders = replaceUtmPlaceholders; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/app.js": +/*!*************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/app.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _content = _interopRequireDefault(__webpack_require__(/*! ./components/content */ "../modules/display-conditions/assets/js/editor/components/content.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const App = props => { + const [dialogOpen, setDialogOpen] = (0, _react.useState)(true), + fadeDuration = 500; + (0, _react.useEffect)(() => { + if (!dialogOpen) { + const timeoutId = setTimeout(() => { + props.onClose(); + }, fadeDuration); + return () => clearTimeout(timeoutId); + } + }, [dialogOpen]); + const handleCloseDialog = () => { + setDialogOpen(false); + }; + return /*#__PURE__*/_react.default.createElement(_ui.DirectionProvider, { + rtl: props.isRTL + }, /*#__PURE__*/_react.default.createElement(_ui.LocalizationProvider, null, /*#__PURE__*/_react.default.createElement(_ui.ThemeProvider, { + colorScheme: props.colorScheme + }, /*#__PURE__*/_react.default.createElement(_ui.Dialog, { + open: dialogOpen, + fullWidth: true, + maxWidth: "lg", + TransitionComponent: _ui.Fade, + transitionDuration: { + enter: fadeDuration, + exit: fadeDuration + }, + sx: { + '& .MuiDialog-paper': { + height: 'calc(100vh - 4rem)', + maxHeight: 775 + } + } + }, /*#__PURE__*/_react.default.createElement(_content.default, { + getControlValue: props.getControlValue, + setControlValue: props.setControlValue, + fetchData: props.fetchData, + onClose: handleCloseDialog, + conditionsConfig: props.conditionsConfig, + setCacheNoticeStatus: props.setCacheNoticeStatus + }))))); +}; +App.propTypes = { + colorScheme: PropTypes.oneOf(['auto', 'light', 'dark']), + isRTL: PropTypes.bool, + getControlValue: PropTypes.func.isRequired, + setControlValue: PropTypes.func.isRequired, + fetchData: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + conditionsConfig: PropTypes.object.isRequired, + setCacheNoticeStatus: PropTypes.func.isRequired +}; +var _default = exports["default"] = App; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/behavior.js": +/*!******************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/behavior.js ***! + \******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _app = _interopRequireDefault(__webpack_require__(/*! ./app */ "../modules/display-conditions/assets/js/editor/app.js")); +class DisplayConditionsBehavior extends Marionette.Behavior { + ui() { + const iconClass = '.eicon-flow.e-control-display-conditions'; + return { + displayConditionsButton: iconClass, + displayConditionsPromoButton: `${iconClass}-promo` + }; + } + events() { + return { + 'click @ui.displayConditionsButton': 'onClickControlButtonDisplayConditions', + 'mouseenter @ui.displayConditionsPromoButton': 'onHoverControlButtonDisplayConditions' + }; + } + onClickControlButtonDisplayConditions(event) { + event.stopPropagation(); + this.mount(); + } + onHoverControlButtonDisplayConditions(event) { + event.stopPropagation(); + elementor.promotion.showDialog({ + title: __('Display Conditions', 'elementor-pro'), + content: __('', 'elementor-pro'), + targetElement: this.el, + actionButton: { + url: 'https://go.elementor.com/go-pro-advanced-display-conditions/', + text: __('Upgrade Now', 'elementor-pro'), + classes: ['elementor-button', 'go-pro'] + } + }); + } + getRootElement() { + let rootElement = window.parent.document.getElementById('elementor-conditions__modal'); + if (!!rootElement) { + return rootElement; + } + rootElement = document.createElement('div'); + rootElement.setAttribute('id', 'elementor-conditions__modal'); + return rootElement; + } + mount() { + const colorScheme = elementor?.getPreferences?.('ui_theme') || 'auto', + isRTL = elementorCommon.config.isRTL, + rootElement = this.getRootElement(); + window.parent.document.body.appendChild(rootElement); + ReactDOM.render(/*#__PURE__*/_react.default.createElement(_app.default // eslint-disable-line react/no-deprecated + , { + colorScheme: colorScheme, + isRTL: isRTL, + getControlValue: this.getOption('getControlValue'), + setControlValue: this.getOption('setControlValue'), + fetchData: this.getOption('fetchData'), + onClose: () => this.unmount(rootElement), + conditionsConfig: this.getOption('conditionsConfig'), + setCacheNoticeStatus: this.getOption('setCacheNoticeStatus') + }), rootElement); + } + unmount(rootElement) { + // eslint-disable-next-line react/no-deprecated + ReactDOM.unmountComponentAtNode(rootElement); + rootElement.remove(); + } +} +exports["default"] = DisplayConditionsBehavior; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/cache-notice.js": +/*!*********************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/cache-notice.js ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const CacheNotice = ({ + setCacheNoticeStatus +}) => { + const [open, setOpen] = (0, _react.useState)(true); + const handleClose = async () => { + const response = await setCacheNoticeStatus(); + if (response) { + setOpen(false); + } + }; + return /*#__PURE__*/_react.default.createElement(_ui.Box, null, /*#__PURE__*/_react.default.createElement(_ui.Collapse, { + in: open, + sx: { + px: 3 + } + }, /*#__PURE__*/_react.default.createElement(_ui.Alert, { + color: "info", + severity: "error", + variant: "standard", + onClose: handleClose, + sx: { + mt: 3 + } + }, (0, _i18n.__)('Keep in mind: Certain cache plugins can conflict with your display conditions. ', 'elementor-pro'), /*#__PURE__*/_react.default.createElement(_ui.Link, { + href: "https://go.elementor.com/app-display-conditions-cache-notice/", + underline: "hover", + color: "info.main", + target: "_blank", + sx: { + '&:hover': { + color: theme => theme.palette.info.main + } + } + }, (0, _i18n.__)('Learn more', 'elementor-pro'))))); +}; +CacheNotice.propTypes = { + setCacheNoticeStatus: PropTypes.func.isRequired +}; +var _default = exports["default"] = CacheNotice; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/conditions-repeater-row.js": +/*!********************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/conditions-repeater-row.js ***! + \********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _useConditions = _interopRequireDefault(__webpack_require__(/*! ../hooks/use-conditions */ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _controlRenderer = _interopRequireDefault(__webpack_require__(/*! ./control-renderer */ "../modules/display-conditions/assets/js/editor/components/control-renderer.js")); +var _conditionSelectControl = _interopRequireDefault(__webpack_require__(/*! ./controls/ui/condition-select-control */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-control.js")); +var _conditionSelectOption = _interopRequireDefault(__webpack_require__(/*! ./controls/ui/condition-select-option */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js")); +var _rowControls = _interopRequireDefault(__webpack_require__(/*! ./ui/row-controls */ "../modules/display-conditions/assets/js/editor/components/ui/row-controls.js")); +var _utils = __webpack_require__(/*! ../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var _constants = __webpack_require__(/*! ../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConditionsRepeaterRow = ({ + andConditionIndex, + orConditionIndex +}) => { + const { + selectedConditions, + conditionsConfig, + dispatch + } = (0, _useConditions.default)(), + { + conditions: availableConditions, + flattenedConditionOptions + } = conditionsConfig, + orCondition = selectedConditions[orConditionIndex]; + const andCondition = orCondition[andConditionIndex], + selectedConditionKey = andCondition?.condition; + const conditionControls = availableConditions[selectedConditionKey]?.controls || {}, + controlCount = Object.keys(conditionControls).length; + const handleChangeCondition = event => { + const conditionKey = event.target.value, + conditionToChange = { + condition: conditionKey, + ...(0, _utils.getConditionInitialState)(availableConditions, conditionKey) + }; + dispatch({ + type: _constants.ACTION_TYPES.CHANGE_CONDITION_TYPE, + orConditionIndex, + andConditionIndex, + conditionToChange + }); + }; + return /*#__PURE__*/React.createElement(_ui.Container, { + maxWidth: "md", + sx: { + display: 'flex', + gap: 0.5, + mb: 1, + position: 'relative' + }, + className: `and-condition-repeater-row and-condition-${andConditionIndex}` + }, /*#__PURE__*/React.createElement(_conditionSelectControl.default, { + id: "condition-select", + value: andCondition.condition || '', + onChange: event => handleChangeCondition(event, andConditionIndex), + controlCount: controlCount + }, flattenedConditionOptions.map(({ + key, + label, + isGroup + }) => isGroup ? /*#__PURE__*/React.createElement(_ui.ListSubheader, { + key: key + }, /*#__PURE__*/React.createElement(_conditionSelectOption.default, { + variant: "caption", + controlCount: controlCount + }, label)) : /*#__PURE__*/React.createElement(_ui.MenuItem, { + key: key, + value: key + }, /*#__PURE__*/React.createElement(_conditionSelectOption.default, { + controlCount: controlCount + }, label)))), Object.keys(conditionControls).map(controlKey => /*#__PURE__*/React.createElement(_controlRenderer.default, { + key: controlKey, + controlKey: controlKey, + andConditionIndex: andConditionIndex, + orConditionIndex: orConditionIndex, + controlCount: controlCount + })), /*#__PURE__*/React.createElement(_rowControls.default, { + orConditionIndex: orConditionIndex, + andConditionIndex: andConditionIndex + })); +}; +ConditionsRepeaterRow.propTypes = { + andConditionIndex: PropTypes.number.isRequired, + orConditionIndex: PropTypes.number.isRequired +}; +var _default = exports["default"] = ConditionsRepeaterRow; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/conditions-selectors.js": +/*!*****************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/conditions-selectors.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _useConditions = _interopRequireDefault(__webpack_require__(/*! ../hooks/use-conditions */ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _conditionsRepeaterRow = _interopRequireDefault(__webpack_require__(/*! ./conditions-repeater-row */ "../modules/display-conditions/assets/js/editor/components/conditions-repeater-row.js")); +const ConditionsSelectors = ({ + orConditionIndex +}) => { + const { + selectedConditions + } = (0, _useConditions.default)(), + orCondition = selectedConditions[orConditionIndex]; + return /*#__PURE__*/_react.default.createElement(_ui.Box, { + sx: { + my: 2, + gap: 1 + }, + className: `or-condition-repeater or-condition-${orConditionIndex}` + }, orCondition.map((andCondition, andConditionIndex) => /*#__PURE__*/_react.default.createElement(_conditionsRepeaterRow.default, { + key: 'or-condition-row-' + andConditionIndex, + andConditionIndex: andConditionIndex, + orConditionIndex: orConditionIndex + }))); +}; +ConditionsSelectors.propTypes = { + orConditionIndex: PropTypes.number.isRequired +}; +var _default = exports["default"] = ConditionsSelectors; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/conditions.js": +/*!*******************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/conditions.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _hierarchyIcon = _interopRequireDefault(__webpack_require__(/*! ./icons/hierarchy-icon */ "../modules/display-conditions/assets/js/editor/components/icons/hierarchy-icon.js")); +var _orRowGroup = _interopRequireDefault(__webpack_require__(/*! ./or-row-group */ "../modules/display-conditions/assets/js/editor/components/or-row-group.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const Conditions = props => { + return /*#__PURE__*/React.createElement(_ui.Box, { + display: "flex", + justifyContent: "center", + alignItems: "flex-start", + sx: { + flex: 1, + overflow: 'auto' + } + }, /*#__PURE__*/React.createElement(_ui.Stack, { + maxWidth: "md", + width: "100%", + justifyContent: "center", + textAlign: "center", + sx: { + pt: 5, + pb: 10, + px: 6 + } + }, /*#__PURE__*/React.createElement(_hierarchyIcon.default, { + fontSize: "large", + sx: { + mb: 1, + mx: 'auto' + } + }), /*#__PURE__*/React.createElement(_ui.Typography, { + component: "h6", + variant: "h6", + color: "text.primary" + }, __('Set one or more conditions for this element', 'elementor-pro')), /*#__PURE__*/React.createElement(_ui.Typography, { + variant: "body2", + color: "text.tertiary", + sx: { + mb: 4 + } + }, __('It will only appear on your website when all the conditions are met.', 'elementor-pro'), ' ', /*#__PURE__*/React.createElement(_ui.Link, { + href: "https://go.elementor.com/app-display-conditions/", + target: "_blank", + rel: "noreferrer", + color: "info.main", + underline: "hover", + sx: { + '&:hover': { + color: theme => theme.palette.info.main + } + } + }, __('Learn more', 'elementor-pro'))), /*#__PURE__*/React.createElement(_orRowGroup.default, props))); +}; +var _default = exports["default"] = Conditions; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/content.js": +/*!****************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/content.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _conditionsReducer = __webpack_require__(/*! ../reducers/conditions-reducer */ "../modules/display-conditions/assets/js/editor/reducers/conditions-reducer.js"); +var _conditionsContext = __webpack_require__(/*! ../contexts/conditions-context */ "../modules/display-conditions/assets/js/editor/contexts/conditions-context.js"); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _utils = __webpack_require__(/*! ../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var _header = _interopRequireDefault(__webpack_require__(/*! ./header */ "../modules/display-conditions/assets/js/editor/components/header.js")); +var _footer = _interopRequireDefault(__webpack_require__(/*! ./footer */ "../modules/display-conditions/assets/js/editor/components/footer.js")); +var _conditions = _interopRequireDefault(__webpack_require__(/*! ./conditions */ "../modules/display-conditions/assets/js/editor/components/conditions.js")); +var _cacheNotice = _interopRequireDefault(__webpack_require__(/*! ./cache-notice */ "../modules/display-conditions/assets/js/editor/components/cache-notice.js")); +var _constants = __webpack_require__(/*! ../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const Content = ({ + getControlValue, + setControlValue, + conditionsConfig, + onClose, + fetchData, + setCacheNoticeStatus +}) => { + const inputValue = getControlValue(), + controlValue = inputValue || [], + initialState = { + conditionsConfig, + selectedConditions: controlValue, + fetchData + }; + const [showConditions, setShowConditions] = _react.default.useState(true), + [conditionsStore, dispatch] = (0, _react.useReducer)(_conditionsReducer.conditionsReducer, initialState), + [saveButtonDisplay, setSaveButtonDisplay] = (0, _react.useState)(false), + { + selectedConditions + } = conditionsStore; + (0, _react.useEffect)(() => { + if (!saveButtonDisplay) { + setSaveButtonDisplay(true); + } + }, [selectedConditions]); + (0, _react.useEffect)(() => { + setSaveButtonDisplay(false); + }, []); + const handleEmptyFieldsAndGetFirstInvalidIndex = () => { + let hasFoundInvalidCondition = false, + invalidOrConditionIndex = null, + invalidAndConditionIndex = null; + selectedConditions.forEach((orCondition, orConditionIndex) => { + const { + hasFoundInvalidConditionInConditionSet, + invalidAndConditionIndex: andConditionIndex + } = handleEmptyFieldsPerConditionSet(orCondition, orConditionIndex); + if (hasFoundInvalidConditionInConditionSet && !hasFoundInvalidCondition) { + hasFoundInvalidCondition = true; + invalidAndConditionIndex = andConditionIndex; + invalidOrConditionIndex = orConditionIndex; + } + }); + return { + hasFoundInvalidCondition, + invalidOrConditionIndex, + invalidAndConditionIndex + }; + }; + const handleEmptyFieldsPerConditionSet = (orCondition, orConditionIndex) => { + let hasFoundInvalidConditionInConditionSet = false, + invalidAndConditionIndex = null; + orCondition.forEach((andCondition, andConditionIndex) => { + const { + condition: conditionKey + } = andCondition, + requiredKeys = getRequiredControlKeys(conditionKey); + const isCurrentConditionInvalid = handleInvalidRequiredKeysPerCondition({ + requiredKeys, + andCondition, + orConditionIndex, + andConditionIndex + }); + if (isCurrentConditionInvalid && !hasFoundInvalidConditionInConditionSet) { + invalidAndConditionIndex = andConditionIndex; + hasFoundInvalidConditionInConditionSet = true; + } + }); + return { + hasFoundInvalidConditionInConditionSet, + invalidAndConditionIndex + }; + }; + const handleInvalidRequiredKeysPerCondition = ({ + requiredKeys, + andCondition, + orConditionIndex, + andConditionIndex + }) => { + const { + condition: conditionKey + } = andCondition; + let hasFoundInvalidCondition = false; + requiredKeys.forEach(controlKey => { + const value = andCondition[controlKey], + { + type, + variant = null + } = conditionsConfig.conditions[conditionKey].controls[controlKey]; + if (value?.length || (0, _utils.shouldEmptyValuePassValidation)(andCondition.condition, andCondition.comparator)) { + return; + } + if (!hasFoundInvalidCondition) { + hasFoundInvalidCondition = true; + } + dispatch({ + type: _constants.ACTION_TYPES.SET_ERRORS, + andConditionIndex, + orConditionIndex, + errors: { + [controlKey]: (0, _utils.getInvalidInputFeedback)(type, variant, value, true) + } + }); + }); + return hasFoundInvalidCondition; + }; + const handleSave = () => { + const { + hasFoundInvalidCondition, + invalidOrConditionIndex, + invalidAndConditionIndex + } = handleEmptyFieldsAndGetFirstInvalidIndex(); + if (hasFoundInvalidCondition) { + const className = `.or-condition-repeater.or-condition-${invalidOrConditionIndex} .and-condition-repeater-row.and-condition-${invalidAndConditionIndex}`, + conditionRepeaterRows = document.querySelector(className); + setTimeout(() => conditionRepeaterRows?.scrollIntoView({ + behavior: 'smooth' + }), 100); + return; + } + setControlValue([JSON.stringify(getSanitizedConditions())]); + onClose(); + }; + const getRequiredControlKeys = condition => { + const { + controls + } = conditionsConfig.conditions[condition]; + return Object.keys(controls).filter(key => controls[key].required); + }; + const getSanitizedConditions = () => { + return selectedConditions.map(orCondition => { + return orCondition.map(andCondition => { + const formattedCondition = { + ...andCondition + }; + delete formattedCondition.errors; + return formattedCondition; + }); + }); + }; + return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_header.default, { + onClose: onClose + }), /*#__PURE__*/_react.default.createElement(_ui.Divider, { + orientation: "horizontal" + }), conditionsConfig.show_cache_notice && /*#__PURE__*/_react.default.createElement(_cacheNotice.default, { + setCacheNoticeStatus: setCacheNoticeStatus + }), /*#__PURE__*/_react.default.createElement(_conditionsContext.ConditionsContext.Provider, { + value: { + dispatch, + ...conditionsStore + } + }, /*#__PURE__*/_react.default.createElement(_conditions.default, { + showConditions: showConditions, + setShowConditions: setShowConditions + })), /*#__PURE__*/_react.default.createElement(_ui.Divider, { + orientation: "horizontal" + }), /*#__PURE__*/_react.default.createElement(_footer.default, { + onClickSaveButton: () => handleSave(), + showConditions: showConditions, + setShowConditions: setShowConditions, + isButtonDisabled: saveButtonDisplay + })); +}; +Content.propTypes = { + getControlValue: PropTypes.func.isRequired, + setControlValue: PropTypes.func.isRequired, + fetchData: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + conditionsConfig: PropTypes.object.isRequired, + setCacheNoticeStatus: PropTypes.func.isRequired +}; +var _default = exports["default"] = Content; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/control-renderer.js": +/*!*************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/control-renderer.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _useConditions = _interopRequireDefault(__webpack_require__(/*! ../hooks/use-conditions */ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js")); +var _selectControl = _interopRequireDefault(__webpack_require__(/*! ./controls/select-control */ "../modules/display-conditions/assets/js/editor/components/controls/select-control.js")); +var _autocompleteControl = _interopRequireDefault(__webpack_require__(/*! ./controls/autocomplete-control */ "../modules/display-conditions/assets/js/editor/components/controls/autocomplete-control.js")); +var _queryControl = _interopRequireDefault(__webpack_require__(/*! ./controls/query-control */ "../modules/display-conditions/assets/js/editor/components/controls/query-control.js")); +var _textFieldControl = _interopRequireDefault(__webpack_require__(/*! ./controls/text-field-control */ "../modules/display-conditions/assets/js/editor/components/controls/text-field-control.js")); +var _datePickerControl = _interopRequireDefault(__webpack_require__(/*! ./controls/date-picker-control */ "../modules/display-conditions/assets/js/editor/components/controls/date-picker-control.js")); +var _timePickerControl = _interopRequireDefault(__webpack_require__(/*! ./controls/time-picker-control */ "../modules/display-conditions/assets/js/editor/components/controls/time-picker-control.js")); +var _constants = __webpack_require__(/*! ../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +var _utils = __webpack_require__(/*! ../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ControlRenderer = ({ + controlKey, + andConditionIndex, + orConditionIndex, + controlCount +}) => { + const { + conditionsConfig, + selectedConditions, + dispatch + } = (0, _useConditions.default)(), + { + conditions: availableConditions + } = conditionsConfig, + orCondition = selectedConditions[orConditionIndex], + andCondition = orCondition[andConditionIndex]; + const selectedConditionKey = andCondition.condition, + { + controls = {} + } = availableConditions[selectedConditionKey], + control = {} = controls[controlKey], + { + options = {} + } = control; + if ('__settings' === controlKey) { + return null; + } + const extractControlPropsFromGlobals = defaultAltValue => { + const valueProps = getControlValueRelatedProps(defaultAltValue), + invalidInputProps = getControlInvalidInputRelatedProps(), + controlProps = { + controlKey, + control, + conditionIndex: andConditionIndex, + condition: andCondition, + conditions: availableConditions, + options, + onChangeOption: handleChangeOption, + controlCount + }; + if ((0, _utils.shouldDisableControl)(controlKey, controlProps.condition.comparator)) { + controlProps.disabled = true; + } + return { + ...valueProps, + ...invalidInputProps, + ...controlProps + }; + }; + const getControlValueRelatedProps = defaultAltValue => { + defaultAltValue = (0, _utils.getControlValue)(defaultAltValue, _constants.DEFAULT_CONTROL_VALUES[control.type]); + const defaultValue = (0, _utils.getControlValue)(control?.default, Object.keys(options)[0] || defaultAltValue), + value = (0, _utils.getControlValue)(andCondition[controlKey], defaultValue); + const placeholder = control?.placeholder || '', + isMultiple = control?.multiple || false; + return { + defaultValue, + value, + placeholder, + isMultiple + }; + }; + const getControlInvalidInputRelatedProps = () => { + const conditionErrors = andCondition.errors || {}, + controlErrors = conditionErrors[controlKey] || {}, + errorMessage = controlErrors.shouldShow && controlErrors.message || '', + shouldShowError = Boolean(errorMessage); + return { + errorMessage, + shouldShowError + }; + }; + const handleChangeOption = value => { + const { + type, + variant + } = controls[controlKey], + error = (0, _utils.getInvalidInputFeedback)(type, variant, value); + dispatch({ + type: _constants.ACTION_TYPES.CHANGE_CONTROL_VALUE, + orConditionIndex, + andConditionIndex, + controlKey, + value + }); + dispatch({ + type: _constants.ACTION_TYPES.SET_ERRORS, + andConditionIndex, + orConditionIndex, + errors: { + [controlKey]: error + } + }); + }; + const getDateAndTimeBasedControl = variant => { + switch (variant) { + case 'date': + return /*#__PURE__*/React.createElement(_datePickerControl.default, extractControlPropsFromGlobals()); + case 'time': + return /*#__PURE__*/React.createElement(_timePickerControl.default, extractControlPropsFromGlobals()); + } + }; + switch (control.type) { + case _constants.CONTROL_TYPES.SELECT: + return /*#__PURE__*/React.createElement(_selectControl.default, extractControlPropsFromGlobals()); + case _constants.CONTROL_TYPES.MULTIPLE_SELECT: + return /*#__PURE__*/React.createElement(_autocompleteControl.default, extractControlPropsFromGlobals()); + case _constants.CONTROL_TYPES.DATE_TIME: + return getDateAndTimeBasedControl(control?.variant); + case _constants.CONTROL_TYPES.QUERY: + return /*#__PURE__*/React.createElement(_queryControl.default, extractControlPropsFromGlobals()); + } + return /*#__PURE__*/React.createElement(_textFieldControl.default, extractControlPropsFromGlobals()); +}; +ControlRenderer.propTypes = { + controlKey: PropTypes.string.isRequired, + andConditionIndex: PropTypes.number.isRequired, + orConditionIndex: PropTypes.number.isRequired, + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = ControlRenderer; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/autocomplete-control.js": +/*!**************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/autocomplete-control.js ***! + \**************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _conditionSelectOption = _interopRequireDefault(__webpack_require__(/*! ./ui/condition-select-option */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const formatValue = valueToFormat => { + return Array.isArray(valueToFormat) ? valueToFormat : [valueToFormat]; +}; +const AutocompleteControl = ({ + conditions, + condition, + controlKey, + onChangeOption, + options, + value, + shouldShowError, + errorMessage, + isMultiple, + controlCount +}) => { + const [controlValue, setControlValue] = (0, _react.useState)(formatValue(value)), + label = controlValue?.length ? '' : conditions[condition.condition].label || ''; + (0, _react.useEffect)(() => { + setControlValue(formatValue(value)); + }, [condition]); + const handleChangeOption = newValue => { + onChangeOption(newValue); + setControlValue(newValue); + }; + return /*#__PURE__*/React.createElement(_ui.Autocomplete, { + multiple: isMultiple, + id: `select-${controlKey}`, + value: controlValue, + options: Object.keys(options), + getOptionLabel: optionKey => options[optionKey], + sx: { + flex: 1 + }, + ChipProps: { + sx: { + '&.MuiAutocomplete-tag': { + maxWidth: '100px' + } + } + }, + renderInput: params => /*#__PURE__*/React.createElement(_ui.TextField, (0, _extends2.default)({ + error: shouldShowError, + helperText: errorMessage + }, params, { + placeholder: label, + color: "secondary" + })), + ListboxProps: { + sx: { + maxHeight: 280 + } + }, + size: "small", + onChange: (_event, newValues) => handleChangeOption(formatValue(newValues)), + renderOption: (optionProps, option) => /*#__PURE__*/React.createElement(_ui.Typography, (0, _extends2.default)({ + component: "li" + }, optionProps), /*#__PURE__*/React.createElement(_conditionSelectOption.default, { + component: "span", + variant: "inherit", + noWrap: true, + controlCount: controlCount + }, options[option])), + forcePopupIcon: !Object.keys(options).length <= 1 + }); +}; +AutocompleteControl.propTypes = { + conditions: PropTypes.object.isRequired, + condition: PropTypes.object.isRequired, + controlKey: PropTypes.string.isRequired, + onChangeOption: PropTypes.func.isRequired, + value: PropTypes.array.isRequired, + options: PropTypes.object.isRequired, + errorMessage: PropTypes.string.isRequired, + shouldShowError: PropTypes.bool.isRequired, + isMultiple: PropTypes.bool.isRequired, + optionsStyles: PropTypes.object.isRequired, + menuStyles: PropTypes.object.isRequired, + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = AutocompleteControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/date-picker-control.js": +/*!*************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/date-picker-control.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _dayjs = _interopRequireDefault(__webpack_require__(/*! dayjs */ "../node_modules/dayjs/dayjs.min.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const dateFormat = 'MM-DD-YYYY'; +const formattedValue = dateString => { + return (0, _dayjs.default)(dateString, dateFormat, true).isValid() ? (0, _dayjs.default)(dateString, dateFormat) : null; +}; +const DatePickerControl = ({ + condition, + onChangeOption, + controlKey, + value, + shouldShowError, + errorMessage +}) => { + const [controlValue, setControlValue] = (0, _react.useState)(formattedValue(value)); + (0, _react.useEffect)(() => { + setControlValue(formattedValue(value)); + }, [condition]); + const handleChangeOption = newValue => { + if ((0, _dayjs.default)(newValue, dateFormat, true).isValid()) { + onChangeOption(newValue.format(dateFormat)); + setControlValue(formattedValue(newValue)); + } else { + onChangeOption(''); + } + }; + return /*#__PURE__*/React.createElement(_ui.DatePicker, { + value: controlValue, + sx: { + flex: 1 + }, + id: `select-${controlKey}`, + slotProps: { + openPickerButton: { + size: 'small' + }, + textField: { + size: 'small', + color: 'secondary', + error: shouldShowError, + helperText: errorMessage + } + }, + onChange: newValue => handleChangeOption(newValue) + }); +}; +DatePickerControl.propTypes = { + condition: PropTypes.object.isRequired, + controlKey: PropTypes.string.isRequired, + onChangeOption: PropTypes.func.isRequired, + value: PropTypes.string, + errorMessage: PropTypes.string.isRequired, + shouldShowError: PropTypes.bool.isRequired +}; +var _default = exports["default"] = DatePickerControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/query-control.js": +/*!*******************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/query-control.js ***! + \*******************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _conditionsContext = __webpack_require__(/*! ../../contexts/conditions-context */ "../modules/display-conditions/assets/js/editor/contexts/conditions-context.js"); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _utils = __webpack_require__(/*! elementor-pro-app/utils */ "../core/app/assets/js/utils.js"); +var _conditionSelectOption = _interopRequireDefault(__webpack_require__(/*! ./ui/condition-select-option */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const formatValue = valueToFormat => { + return Array.isArray(valueToFormat) ? valueToFormat : [valueToFormat]; +}; +const QueryControl = ({ + conditions, + condition, + control, + controlKey, + onChangeOption, + value, + shouldShowError, + errorMessage, + isMultiple, + controlCount +}) => { + const { + fetchData + } = (0, _react.useContext)(_conditionsContext.ConditionsContext), + [controlValue, setControlValue] = (0, _react.useState)(formatValue(value)), + [options, setOptions] = (0, _react.useState)([]), + [loading, setLoading] = (0, _react.useState)(false), + label = controlValue?.length ? '' : conditions[condition.condition].label || ''; + (0, _react.useEffect)(() => { + setControlValue(formatValue(value)); + }, [condition]); + const handleSearchInputChange = async (event, newInputValue, selectedValues) => { + if ('' === newInputValue) { + setOptions([]); + return; + } + setLoading(true); + const results = await fetchData(newInputValue, control); + + // Filter out options that are already selected + const filteredResults = results.filter(option => { + option.text = (0, _utils.htmlDecodeTextContent)(option.text); + return !selectedValues.some(selectedOption => selectedOption?.id === option?.id); + }); + setOptions(filteredResults); + setLoading(false); + }; + const handleChangeOption = newValue => { + onChangeOption(newValue); + setControlValue(newValue); + }; + return /*#__PURE__*/_react.default.createElement(_ui.Autocomplete, { + multiple: isMultiple, + id: `select-${controlKey}`, + value: controlValue, + options: options, + getOptionLabel: option => option ? option.text : '', + isOptionEqualToValue: (option, optionToCompare) => option.id === optionToCompare.id, + filterOptions: x => x, + noOptionsText: (0, _i18n.__)('No results', 'elementor-pro'), + loading: loading, + loadingText: (0, _i18n.__)('Searching...', 'elementor-pro'), + size: "small", + sx: { + flex: 1 + }, + ChipProps: { + sx: { + '&.MuiAutocomplete-tag': { + maxWidth: '100px' + } + } + }, + renderInput: params => /*#__PURE__*/_react.default.createElement(_ui.TextField, (0, _extends2.default)({}, params, { + placeholder: label, + color: "secondary", + error: shouldShowError, + helperText: errorMessage, + InputProps: { + ...params.InputProps, + endAdornment: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, loading ? /*#__PURE__*/_react.default.createElement(_ui.CircularProgress, { + color: "inherit", + size: 20 + }) : null, params.InputProps.endAdornment) + } + })), + ListboxProps: { + sx: { + maxHeight: 280 + } + }, + onChange: (_event, newValues) => handleChangeOption(newValues), + onInputChange: (event, newInputValue) => handleSearchInputChange(event, newInputValue, controlValue), + renderOption: (optionProps, option) => /*#__PURE__*/_react.default.createElement(_ui.Typography, (0, _extends2.default)({ + component: "li" + }, optionProps), /*#__PURE__*/_react.default.createElement(_conditionSelectOption.default, { + component: "span", + variant: "inherit", + noWrap: true, + controlCount: controlCount + }, option.text)) + }); +}; +QueryControl.propTypes = { + conditions: PropTypes.object.isRequired, + condition: PropTypes.object.isRequired, + onChangeOption: PropTypes.func.isRequired, + controlKey: PropTypes.string.isRequired, + control: PropTypes.object.isRequired, + value: PropTypes.array.isRequired, + errorMessage: PropTypes.string.isRequired, + shouldShowError: PropTypes.bool.isRequired, + isMultiple: PropTypes.bool.isRequired, + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = QueryControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/select-control.js": +/*!********************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/select-control.js ***! + \********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _conditionSelectControl = _interopRequireDefault(__webpack_require__(/*! ./ui/condition-select-control */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-control.js")); +var _conditionSelectOption = _interopRequireDefault(__webpack_require__(/*! ./ui/condition-select-option */ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const SelectControl = ({ + condition, + control, + controlKey, + onChangeOption, + options, + value, + controlCount +}) => { + const [controlValue, setControlValue] = (0, _react.useState)(value); + (0, _react.useEffect)(() => { + setControlValue(value); + }, [condition]); + const handleChangeOption = newValue => { + onChangeOption(newValue); + setControlValue(newValue); + }; + const getOptions = () => { + return Object.entries(options).map(([optionKey, optionValue]) => { + if (!optionValue) { + return null; + } + if ('group' === optionValue.type) { + return /*#__PURE__*/React.createElement(_ui.ListSubheader, { + key: optionKey + }, /*#__PURE__*/React.createElement(_conditionSelectOption.default, { + controlCount: controlCount + }, optionValue.label)); + } + const isDisabled = control?.disabled_options?.includes(optionKey); + return /*#__PURE__*/React.createElement(_ui.MenuItem, { + key: optionKey, + value: optionKey, + disabled: isDisabled, + className: isDisabled && 'hidden' === control?.disabled_type ? 'elementor-hidden' : '' + }, /*#__PURE__*/React.createElement(_conditionSelectOption.default, { + controlCount: controlCount + }, optionValue)); + }); + }; + return /*#__PURE__*/React.createElement(_conditionSelectControl.default, { + id: `select-${controlKey}`, + value: controlValue, + onChange: event => handleChangeOption(event.target.value), + disabled: Object.keys(options).length <= 1, + controlCount: controlCount + }, getOptions()); +}; +SelectControl.propTypes = { + condition: PropTypes.object.isRequired, + control: PropTypes.object.isRequired, + controlKey: PropTypes.string.isRequired, + onChangeOption: PropTypes.func.isRequired, + options: PropTypes.object.isRequired, + value: PropTypes.string.isRequired, + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = SelectControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/text-field-control.js": +/*!************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/text-field-control.js ***! + \************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _utils = __webpack_require__(/*! ../../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const TextFieldControl = ({ + condition, + controlKey, + control, + onChangeOption, + value, + errorMessage, + shouldShowError, + placeholder, + disabled +}) => { + const [controlValue, setControlValue] = (0, _react.useState)(value), + { + step = 1, + min = 0, + variant = null + } = control; + const numericProps = 'number' === variant ? { + type: 'number', + inputProps: { + step, + min + } + } : {}; + (0, _react.useEffect)(() => { + setControlValue(value); + }, [condition]); + const handleChangeOption = (newValue, controlVariant) => { + let integerValue = null; + if ('number' === controlVariant && (0, _utils.hasDecimalSeparator)(newValue)) { + integerValue = Math.floor(parseFloat(newValue)); + } + onChangeOption(integerValue ?? newValue.trim()); + setControlValue(integerValue ?? newValue); + }; + return /*#__PURE__*/React.createElement(_ui.TextField, (0, _extends2.default)({}, numericProps, { + sx: { + flex: 1 + }, + error: shouldShowError, + helperText: errorMessage, + value: controlValue, + id: `text-${controlKey}`, + variant: "outlined", + onChange: event => handleChangeOption(event.target.value, variant), + size: "small", + color: "secondary", + placeholder: placeholder, + disabled: disabled ?? false + })); +}; +TextFieldControl.propTypes = { + condition: PropTypes.object.isRequired, + controlKey: PropTypes.string.isRequired, + control: PropTypes.object.isRequired, + onChangeOption: PropTypes.func.isRequired, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + errorMessage: PropTypes.string.isRequired, + shouldShowError: PropTypes.bool.isRequired, + placeholder: PropTypes.string.isRequired, + disabled: PropTypes.bool +}; +var _default = exports["default"] = TextFieldControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/time-picker-control.js": +/*!*************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/time-picker-control.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var React = _react; +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _dayjs = _interopRequireDefault(__webpack_require__(/*! dayjs */ "../node_modules/dayjs/dayjs.min.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const timeFormat = 'HH:mm', + dateFormat = 'MM-DD-YYYY ' + timeFormat; +const formattedValue = dateString => { + return (0, _dayjs.default)(dateString, timeFormat, true).isValid() ? (0, _dayjs.default)(dateString, timeFormat) : null; +}; +const TimePickerControl = ({ + condition, + controlKey, + onChangeOption, + value, + shouldShowError, + errorMessage +}) => { + const lastInputValue = (0, _react.useRef)(formattedValue(value)), + [controlValue, setControlValue] = (0, _react.useState)(lastInputValue.current); + (0, _react.useEffect)(() => { + setControlValue(lastInputValue.current); + }, [condition]); + const handleChangeOption = newValue => { + const dateString = (0, _dayjs.default)(newValue, dateFormat, true).isValid() ? newValue.format(dateFormat) : ''; + onChangeOption(dateString); + lastInputValue.current = newValue; + setControlValue(newValue); + }; + return /*#__PURE__*/React.createElement(_ui.TimePicker, { + sx: { + flex: 1 + }, + id: `select-${controlKey}`, + value: controlValue, + slotProps: { + textField: { + size: 'small', + error: shouldShowError, + helperText: errorMessage + } + }, + onChange: newValue => handleChangeOption(newValue) + }); +}; +TimePickerControl.propTypes = { + condition: PropTypes.object.isRequired, + control: PropTypes.object.isRequired, + controlKey: PropTypes.string.isRequired, + onChangeOption: PropTypes.func.isRequired, + value: PropTypes.string, + errorMessage: PropTypes.string.isRequired, + shouldShowError: PropTypes.bool.isRequired +}; +var _default = exports["default"] = TimePickerControl; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-control.js": +/*!*********************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-control.js ***! + \*********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _utils = __webpack_require__(/*! ../../../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConditionSelect = ({ + controlCount, + ...props +}) => /*#__PURE__*/_react.default.createElement(_ui.Select, (0, _extends2.default)({}, props, { + size: "small", + sx: { + flex: 1, + textAlign: 'start', + alignSelf: 'flex-start', + '.MuiSelect-select .MuiTypography-root': { + maxWidth: (0, _utils.getControlValueMaxWidth)(controlCount) + } + }, + color: "secondary", + MenuProps: { + PaperProps: { + sx: { + maxHeight: 280, + '& .MuiListSubheader-root': { + position: 'initial' + } + } + }, + classes: { + paper: 'e-conditions-select-menu' + } + } +})); +ConditionSelect.propTypes = { + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = ConditionSelect; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js": +/*!********************************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/controls/ui/condition-select-option.js ***! + \********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _utils = __webpack_require__(/*! ../../../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ConditionSelectOption = ({ + controlCount, + sx = {}, + ...props +}) => /*#__PURE__*/_react.default.createElement(_ui.Typography, (0, _extends2.default)({ + noWrap: true +}, props, { + variant: props.variant || 'inherit', + sx: { + maxWidth: (0, _utils.getSelectOptionMaxWidth)(controlCount), + ...sx + } +})); +ConditionSelectOption.propTypes = { + sx: PropTypes.object, + isDropdownItem: PropTypes.bool, + variant: PropTypes.string, + controlCount: PropTypes.number.isRequired +}; +var _default = exports["default"] = ConditionSelectOption; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/footer.js": +/*!***************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/footer.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const Footer = ({ + onClickSaveButton, + isButtonDisabled +}) => { + return /*#__PURE__*/React.createElement(_ui.Stack, { + direction: "row", + justifyContent: "flex-end", + sx: { + py: 1, + px: 3 + } + }, /*#__PURE__*/React.createElement(_ui.Button, { + variant: "contained", + className: "save-and-close-button", + disabled: !isButtonDisabled, + onClick: onClickSaveButton + }, __('Save & Close', 'elementor-pro'))); +}; +Footer.propTypes = { + onClickSaveButton: PropTypes.func, + isButtonDisabled: PropTypes.bool.isRequired +}; +var _default = exports["default"] = Footer; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/header.js": +/*!***************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/header.js ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var PropTypes = _interopRequireWildcard(__webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js")); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _elementorLogo = _interopRequireDefault(__webpack_require__(/*! ./icons/elementor-logo */ "../modules/display-conditions/assets/js/editor/components/icons/elementor-logo.js")); +var _icons = __webpack_require__(/*! @elementor/icons */ "@elementor/icons"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const Header = ({ + onClose +}) => { + return /*#__PURE__*/_react.default.createElement(_ui.AppBar, { + sx: { + fontWeight: 'normal' + }, + color: "transparent", + position: "relative" + }, /*#__PURE__*/_react.default.createElement(_ui.Toolbar, { + variant: "dense" + }, /*#__PURE__*/_react.default.createElement(_elementorLogo.default, { + sx: { + mr: 1 + } + }), /*#__PURE__*/_react.default.createElement(_ui.Typography, { + component: "span", + variant: "subtitle2", + sx: { + fontWeight: 'bold', + textTransform: 'uppercase' + } + }, (0, _i18n.__)('Display Conditions', 'elementor-pro')), /*#__PURE__*/_react.default.createElement(_ui.Stack, { + direction: "row", + spacing: 1, + alignItems: "center", + sx: { + ml: 'auto' + } + }, /*#__PURE__*/_react.default.createElement(_ui.IconButton, { + size: "small", + "aria-label": (0, _i18n.__)('Close', 'elementor-pro'), + onClick: onClose, + sx: { + '&.MuiButtonBase-root': { + mr: -1 + } + } + }, /*#__PURE__*/_react.default.createElement(_icons.XIcon, null))))); +}; +Header.propTypes = { + onClose: PropTypes.func.isRequired +}; +var _default = exports["default"] = Header; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/icons/elementor-logo.js": +/*!*****************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/icons/elementor-logo.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const ElementorLogo = props => { + return /*#__PURE__*/React.createElement(_ui.SvgIcon, (0, _extends2.default)({ + viewBox: "0 0 32 32" + }, props), /*#__PURE__*/React.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M2.69648 24.8891C0.938383 22.2579 0 19.1645 0 16C0 11.7566 1.68571 7.68687 4.68629 4.68629C7.68687 1.68571 11.7566 0 16 0C19.1645 0 22.2579 0.938383 24.8891 2.69648C27.5203 4.45459 29.5711 6.95344 30.7821 9.87706C31.9931 12.8007 32.3099 16.0177 31.6926 19.1214C31.0752 22.2251 29.5514 25.0761 27.3137 27.3137C25.0761 29.5514 22.2251 31.0752 19.1214 31.6926C16.0177 32.3099 12.8007 31.9931 9.87706 30.7821C6.95344 29.5711 4.45459 27.5203 2.69648 24.8891ZM12.0006 9.33281H9.33437V22.6665H12.0006V9.33281ZM22.6657 9.33281H14.6669V11.9991H22.6657V9.33281ZM22.6657 14.6654H14.6669V17.3316H22.6657V14.6654ZM22.6657 20.0003H14.6669V22.6665H22.6657V20.0003Z" + })); +}; +var _default = exports["default"] = ElementorLogo; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/icons/hierarchy-icon.js": +/*!*****************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/icons/hierarchy-icon.js ***! + \*****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/extends */ "../node_modules/@babel/runtime/helpers/extends.js")); +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const UnstyledHierarchyIcon = React.forwardRef((props, ref) => { + return /*#__PURE__*/React.createElement(_ui.SvgIcon, (0, _extends2.default)({ + viewBox: "0 0 24 24" + }, props, { + ref: ref + }), /*#__PURE__*/React.createElement("path", { + fillRule: "evenodd", + clipRule: "evenodd", + d: "M11 3.75C10.3096 3.75 9.75 4.30964 9.75 5V7C9.75 7.69036 10.3096 8.25 11 8.25H13C13.6904 8.25 14.25 7.69036 14.25 7V5C14.25 4.30964 13.6904 3.75 13 3.75H11ZM12.75 9.75H13C14.5188 9.75 15.75 8.51878 15.75 7V5C15.75 3.48122 14.5188 2.25 13 2.25H11C9.48122 2.25 8.25 3.48122 8.25 5V7C8.25 8.51878 9.48122 9.75 11 9.75H11.25V11.25H8C7.27065 11.25 6.57118 11.5397 6.05546 12.0555C5.53973 12.5712 5.25 13.2707 5.25 14V14.25H5C3.48122 14.25 2.25 15.4812 2.25 17V19C2.25 20.5188 3.48122 21.75 5 21.75H7C8.51878 21.75 9.75 20.5188 9.75 19V17C9.75 15.4812 8.51878 14.25 7 14.25H6.75V14C6.75 13.6685 6.8817 13.3505 7.11612 13.1161C7.35054 12.8817 7.66848 12.75 8 12.75H16C16.3315 12.75 16.6495 12.8817 16.8839 13.1161C17.1183 13.3505 17.25 13.6685 17.25 14V14.25H17C15.4812 14.25 14.25 15.4812 14.25 17V19C14.25 20.5188 15.4812 21.75 17 21.75H19C20.5188 21.75 21.75 20.5188 21.75 19V17C21.75 15.4812 20.5188 14.25 19 14.25H18.75V14C18.75 13.2707 18.4603 12.5712 17.9445 12.0555C17.4288 11.5397 16.7293 11.25 16 11.25H12.75V9.75ZM17 15.75C16.3096 15.75 15.75 16.3096 15.75 17V19C15.75 19.6904 16.3096 20.25 17 20.25H19C19.6904 20.25 20.25 19.6904 20.25 19V17C20.25 16.3096 19.6904 15.75 19 15.75H17ZM5 15.75C4.30964 15.75 3.75 16.3096 3.75 17V19C3.75 19.6904 4.30964 20.25 5 20.25H7C7.69036 20.25 8.25 19.6904 8.25 19V17C8.25 16.3096 7.69036 15.75 7 15.75H5Z" + })); +}); +const HierarchyIcon = (0, _ui.styled)(UnstyledHierarchyIcon)(({ + theme +}) => ({ + '& path': { + fill: theme.palette.text.primary + } +})); +var _default = exports["default"] = HierarchyIcon; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/or-row-group.js": +/*!*********************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/or-row-group.js ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _icons = __webpack_require__(/*! @elementor/icons */ "@elementor/icons"); +var _conditionsSelectors = _interopRequireDefault(__webpack_require__(/*! ./conditions-selectors */ "../modules/display-conditions/assets/js/editor/components/conditions-selectors.js")); +var _useConditions = _interopRequireDefault(__webpack_require__(/*! ../hooks/use-conditions */ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js")); +var _utils = __webpack_require__(/*! ../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var _conditionsOrDivider = _interopRequireDefault(__webpack_require__(/*! ./ui/conditions-or-divider */ "../modules/display-conditions/assets/js/editor/components/ui/conditions-or-divider.js")); +var _constants = __webpack_require__(/*! ../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const OrRowGroup = ({ + showConditions, + setShowConditions +}) => { + const { + selectedConditions, + conditionsConfig, + dispatch + } = (0, _useConditions.default)(), + { + conditions: availableConditions, + conditionsByGroup + } = conditionsConfig, + addButtonText = selectedConditions.length ? __('Add condition group', 'elementor-pro') : __('Add Condition', 'elementor-pro'); + const addOrCondition = () => { + const conditionKey = (0, _utils.getDefaultActiveCondition)(conditionsByGroup), + defaultValues = (0, _utils.getConditionInitialState)(availableConditions, conditionKey), + andCondition = { + condition: conditionKey, + ...defaultValues + }; + dispatch({ + type: _constants.ACTION_TYPES.ADD_OR_CONDITION, + andCondition + }); + setShowConditions(true); + }; + return /*#__PURE__*/_react.default.createElement(_ui.Box, null, showConditions && selectedConditions.map((orCondition, orConditionIndex) => /*#__PURE__*/_react.default.createElement(_react.Fragment, { + key: orConditionIndex + }, orConditionIndex > 0 && /*#__PURE__*/_react.default.createElement(_conditionsOrDivider.default, null), /*#__PURE__*/_react.default.createElement(_conditionsSelectors.default, { + orConditionIndex: orConditionIndex + }))), /*#__PURE__*/_react.default.createElement(_ui.Button, { + variant: "contained", + className: "add-or-condition-button", + color: "secondary", + startIcon: /*#__PURE__*/_react.default.createElement(_icons.PlusIcon, null), + sx: { + mt: 1, + mb: 5 + }, + onClick: () => addOrCondition() + }, addButtonText)); +}; +OrRowGroup.propTypes = { + showConditions: PropTypes.bool.isRequired, + setShowConditions: PropTypes.func.isRequired +}; +var _default = exports["default"] = OrRowGroup; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/ui/conditions-or-divider.js": +/*!*********************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/ui/conditions-or-divider.js ***! + \*********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = _interopRequireDefault(__webpack_require__(/*! react */ "react")); +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +const OrDivider = () => { + return /*#__PURE__*/_react.default.createElement(_ui.Divider, { + sx: { + px: 3 + } + }, __('OR', 'elementor-pro')); +}; +var _default = exports["default"] = OrDivider; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/components/ui/row-controls.js": +/*!************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/components/ui/row-controls.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var PropTypes = __webpack_require__(/*! prop-types */ "../node_modules/prop-types/index.js"); + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _ui = __webpack_require__(/*! @elementor/ui */ "@elementor/ui"); +var _i18n = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +var _icons = __webpack_require__(/*! @elementor/icons */ "@elementor/icons"); +var React = _interopRequireWildcard(__webpack_require__(/*! react */ "react")); +var _utils = __webpack_require__(/*! ../../utils/utils */ "../modules/display-conditions/assets/js/editor/utils/utils.js"); +var _useConditions = _interopRequireDefault(__webpack_require__(/*! ../../hooks/use-conditions */ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js")); +var _constants = __webpack_require__(/*! ../../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const RowControls = ({ + orConditionIndex, + andConditionIndex +}) => { + const { + conditionsConfig, + dispatch + } = (0, _useConditions.default)(), + { + conditions: availableConditions, + conditionsByGroup + } = conditionsConfig; + const addRepeaterRow = () => { + const conditionKey = (0, _utils.getDefaultActiveCondition)(conditionsByGroup), + defaultValues = (0, _utils.getConditionInitialState)(availableConditions, conditionKey), + andCondition = { + condition: conditionKey, + ...defaultValues + }; + dispatch({ + type: _constants.ACTION_TYPES.ADD_AND_CONDITION, + andCondition, + andConditionIndex, + orConditionIndex + }); + }; + const removeRepeaterRow = () => { + dispatch({ + type: _constants.ACTION_TYPES.REMOVE_AND_CONDITION, + andConditionIndex, + orConditionIndex + }); + }; + return /*#__PURE__*/React.createElement(_ui.Stack, { + direction: "row", + alignItems: "center", + sx: { + left: '100%', + gap: .5, + ml: -1, + mt: '2.5px', + position: 'absolute' + } + }, /*#__PURE__*/React.createElement(_ui.Button, { + color: "secondary", + variant: "outlined", + sx: { + px: 1, + minWidth: 'unset' + }, + className: "add-single-condition-button", + onClick: addRepeaterRow + }, (0, _i18n.__)('AND', 'elementor-pro')), /*#__PURE__*/React.createElement(_ui.IconButton, { + color: "secondary", + "aria-label": (0, _i18n.__)('Delete', 'elementor-pro'), + className: "remove-single-condition-button", + onClick: removeRepeaterRow + }, /*#__PURE__*/React.createElement(_icons.XIcon, { + fontSize: "small" + }))); +}; +RowControls.propTypes = { + andConditionIndex: PropTypes.number.isRequired, + orConditionIndex: PropTypes.number.isRequired +}; +var _default = exports["default"] = RowControls; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/contexts/conditions-context.js": +/*!*************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/contexts/conditions-context.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var React = __webpack_require__(/*! react */ "react"); + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ConditionsContext = void 0; +const ConditionsContext = exports.ConditionsContext = React.createContext(); + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/hooks/use-conditions.js": +/*!******************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/hooks/use-conditions.js ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _react = __webpack_require__(/*! react */ "react"); +var _conditionsContext = __webpack_require__(/*! ../contexts/conditions-context */ "../modules/display-conditions/assets/js/editor/contexts/conditions-context.js"); +function useConditions() { + return (0, _react.useContext)(_conditionsContext.ConditionsContext); +} +var _default = exports["default"] = useConditions; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/module.js": +/*!****************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/module.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var _behavior = _interopRequireDefault(__webpack_require__(/*! ./behavior */ "../modules/display-conditions/assets/js/editor/behavior.js")); +class Module extends elementorModules.editor.utils.Module { + pasteAction = 'paste'; + clearAction = 'clear'; + getDefaultSettings() { + return { + selectors: { + icon: '.eicon-flow.e-control-display-conditions' + }, + controls: { + displayConditions: 'e_display_conditions', + trigger: 'e_display_conditions_trigger' + } + }; + } + onElementorInit() { + elementor.hooks.addFilter('controls/base/behaviors', this.registerControlBehavior); + elementor.channels.editor.on('section:activated', this.highlightIconIfFilled); + elementor.on('navigator:init', this.onNavigatorInit.bind(this)); + const elTypes = ['widget', 'section', 'column', 'container']; + elTypes.forEach(type => { + elementor.hooks.addFilter(`elements/${type}/contextMenuGroups`, this.registerContextMenuGroups.bind(this)); + }); + } + onElementorInitComponents() { + $e.commands.register('document/elements', 'paste-display-conditions', args => { + this.tryContextMenuActions(args, this.pasteAction); + }); + $e.commands.register('document/elements', 'clear-display-conditions', args => { + this.tryContextMenuActions(args, this.clearAction); + }); + } + registerContextMenuGroups(groups, currentElement) { + const clipboardGroup = groups.find(group => 'clipboard' === group.name); + if (!clipboardGroup) { + return groups; + } + + // Add after pasteStyle + const pasteStyleIndex = clipboardGroup.actions.findIndex(action => 'pasteStyle' === action.name); + if (-1 !== pasteStyleIndex) { + clipboardGroup.actions.splice(pasteStyleIndex + 1, 0, { + name: 'pasteDisplayConditions', + isEnabled: () => this.isPasteDisplayConditionsEnabled(currentElement), + isVisible: () => this.isPasteDisplayConditionsEnabled(currentElement), + // Need both for Core/Pro dependancy. + title: __('Paste display conditions', 'elementor-pro'), + callback: () => $e.run('document/elements/paste-display-conditions', elementor.selection.getElements(currentElement.getContainer())) + }); + } + clipboardGroup.actions.push({ + name: 'clearDisplayConditions', + isEnabled: () => this.isClearDisplayConditionsEnabled(currentElement), + isVisible: () => this.isClearDisplayConditionsEnabled(currentElement), + // Need both for Core/Pro dependancy. + title: __('Clear display conditions', 'elementor-pro'), + callback: () => $e.run('document/elements/clear-display-conditions', elementor.selection.getElements(currentElement.getContainer())) + }); + return groups; + } + isPasteDisplayConditionsEnabled(selectedElement) { + const displayConditions = this.getSelectedElementDisplayCondition(selectedElement), + doesClipboardHaveConditions = !!JSON.parse(this.getDisplayConditionsFromClipboard()).length; + return !displayConditions.length && !elementor.selection.isMultiple() && doesClipboardHaveConditions; + } + isClearDisplayConditionsEnabled(selectedElement) { + const displayConditions = this.getSelectedElementDisplayCondition(selectedElement); + return displayConditions.length && !elementor.selection.isMultiple(); + } + getSelectedElementDisplayCondition(selectedElement) { + return JSON.parse(selectedElement?.model?.getSetting(this.getSettings('controls').displayConditions) || '[]'); + } + getDisplayConditionsFromClipboard() { + const clipboard = elementorCommon.storage.get('clipboard'), + elements = clipboard?.elements || []; + if (1 !== elements.length) { + return '[]'; + } + return elements[0]?.settings?.e_display_conditions || '[]'; + } + + /** + * Paste or clear display conditions to/of the selected element. + * + * @param {Array} containers + * @param {'paste' | 'clear'} action + */ + tryContextMenuActions(containers, action) { + const container = containers?.[0] || null, + displayConditions = this.pasteAction === action ? this.getDisplayConditionsFromClipboard() : ''; + if (!container) { + return; + } + $e.run('document/elements/settings', { + container, + settings: { + e_display_conditions: displayConditions + } + }); + container.panel.refresh(); + try { + const controlView = container.panel.getControlView(this.getSettings('controls').displayConditions), + icon = this.getEditorControlView(this.getSettings('controls').trigger).$el.find(this.getSettings('selectors').icon); + this.highlightIcon(icon, controlView); + } catch (error) { + return false; + } + } + registerControlBehavior = (behaviors, view) => { + if (this.getSettings('controls').trigger !== view.options.model.get('name')) { + return behaviors; + } + if (!behaviors) { + behaviors = {}; + } + const conditionsByGroup = this._getGroupedConditionKeys(elementor.config.displayConditions || {}); + const flattenedConditionOptions = this._getFlattenedConditionOptions(conditionsByGroup); + behaviors.displayConditions = { + behaviorClass: _behavior.default, + getControlValue: () => { + const controlView = this.getEditorControlView(this.getSettings('controls').displayConditions); + if (!controlView) { + return []; + } + return this._getStructuredConditions(JSON.parse(controlView.getControlValue() || '[]')); + }, + setControlValue: value => { + const displayConditionsInput = this.getEditorControlView(this.getSettings('controls').displayConditions), + displayConditionsTemplate = this.getEditorControlView(this.getSettings('controls').trigger); + if (displayConditionsInput) { + value = !value?.length || '[]' === value[0] ? '' : value; + displayConditionsInput.setValue(value); + displayConditionsInput.applySavedValue(); + } + if (displayConditionsTemplate.$el) { + const icon = displayConditionsTemplate.$el.find(this.getSettings('selectors').icon); + this.highlightIcon(icon, displayConditionsInput); + } + }, + fetchData: async (value, control) => { + const response = await this.doAjaxRequest('pro_panel_posts_control_filter_autocomplete', { + autocomplete: control.autocomplete, + q: value + }); + return response?.results ?? []; + }, + setCacheNoticeStatus: async () => { + const response = await this.doAjaxRequest('display_conditions_set_cache_notice_status'); + if (response) { + elementor.config.displayConditions.show_cache_notice = false; + } + return response; + }, + conditionsConfig: { + ...elementor.config.displayConditions, + conditionsByGroup, + flattenedConditionOptions + } + }; + return behaviors; + }; + highlightIconIfFilled = (sectionName, editor) => { + const advancedSections = ['section_advanced', + // Sections / Columns + '_section_style', + // Widgets + 'section_layout' // Containers + ]; + if (!advancedSections.includes(sectionName)) { + return; + } + const controlView = this.getEditorControlView(this.getSettings('controls').displayConditions); + if (!controlView) { + return; + } + const icon = editor.$childViewContainer.find(this.getSettings('selectors').icon); + this.highlightIcon(icon, controlView); + }; + onNavigatorInit() { + elementor.navigator.indicators.displayConditions = { + icon: 'flow', + title: __('Display Conditions', 'elementor-pro'), + settingKeys: ['e_display_conditions'], + section: 'e_display_conditions_trigger' + }; + } + highlightIcon = (icon, controlView) => { + if (!icon[0]) { + return; + } + const conditionValue = controlView.getControlValue() || '[]', + conditionArray = '[]' !== conditionValue ? this._getStructuredConditions(JSON.parse(conditionValue)) : []; + if (!conditionArray.length) { + icon[0]?.classList?.remove('filled'); + } else { + icon[0]?.classList?.add('filled'); + } + }; + doAjaxRequest = (action, data) => { + try { + return new Promise((resolve, reject) => { + elementorCommon.ajax.addRequest(action, { + data, + error: () => reject(), + success: res => { + resolve(res); + } + }); + }); + } catch (error) { + return false; + } + }; + _getStructuredConditions = conditions => { + return this._shouldConvertConditionsStructure(conditions) ? [conditions] : conditions; + }; + _shouldConvertConditionsStructure = conditions => { + return conditions.length && !Array.isArray(conditions[0]); + }; + _getGroupedConditionKeys = conditionsConfig => { + return Object.keys(conditionsConfig?.groups || {}).reduce((group, groupName) => { + const conditions = this._getConditionKeyByGroup(conditionsConfig.conditions, groupName); + if (conditions.length) { + group[groupName] = conditions; + } + return group; + }, {}); + }; + _getConditionKeyByGroup = (conditions, groupName) => { + return Object.keys(conditions).filter(conditionKey => groupName === conditions[conditionKey].group); + }; + _getFlattenedConditionOptions = conditionsByGroup => { + const { + conditions = {}, + groups = {} + } = elementor.config.displayConditions || {}; + return Object.entries(conditionsByGroup).reduce((optionList, [groupName, conditionKeys]) => { + const relevantConditions = conditionKeys.map(key => ({ + key, + label: conditions[key].label, + isGroup: false + })); + optionList.push({ + key: groupName, + label: groups[groupName].label, + isGroup: true + }, ...relevantConditions); + return optionList; + }, []); + }; +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/reducers/conditions-reducer.js": +/*!*************************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/reducers/conditions-reducer.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.conditionsReducer = void 0; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var _constants = __webpack_require__(/*! ../utils/constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +const conditionsReducer = (state, action) => { + switch (action.type) { + case _constants.ACTION_TYPES.CHANGE_CONDITION_TYPE: + return { + ...state, + selectedConditions: _changeConditionType({ + ...state, + ...action + }) + }; + case _constants.ACTION_TYPES.CHANGE_CONTROL_VALUE: + return { + ...state, + selectedConditions: _changeControlValue({ + ...state, + ...action + }) + }; + case _constants.ACTION_TYPES.ADD_AND_CONDITION: + return { + ...state, + selectedConditions: _addAndCondition({ + ...state, + ...action + }) + }; + case _constants.ACTION_TYPES.ADD_OR_CONDITION: + return { + ...state, + selectedConditions: [...state.selectedConditions, [action.andCondition]] + }; + case _constants.ACTION_TYPES.REMOVE_AND_CONDITION: + return { + ...state, + selectedConditions: _removeAndCondition({ + ...state, + ...action + }) + }; + case _constants.ACTION_TYPES.REMOVE_OR_CONDITION: + return { + ...state, + selectedConditions: state.selectedConditions.filter((_, index) => index !== action.orConditionIndex) + }; + case _constants.ACTION_TYPES.SET_ERRORS: + return { + ...state, + selectedConditions: _setErrors({ + ...state, + ...action + }) + }; + default: + return state; + } +}; +exports.conditionsReducer = conditionsReducer; +const _changeConditionType = ({ + selectedConditions, + conditionToChange, + orConditionIndex, + andConditionIndex +}) => { + const newOrCondition = selectedConditions[orConditionIndex].map((andCondition, index) => index === andConditionIndex ? conditionToChange : { + ...andCondition + }); + return selectedConditions.map((orCondition, index) => index === orConditionIndex ? newOrCondition : [...orCondition]); +}; +const _changeControlValue = ({ + selectedConditions, + orConditionIndex, + andConditionIndex, + controlKey, + value +}) => { + const existingOrCondition = [...selectedConditions[orConditionIndex]], + existingAndCondition = { + ...existingOrCondition[andConditionIndex] + }; + const newAndCondition = { + ...existingAndCondition, + [controlKey]: value + }, + newOrCondition = existingOrCondition.map((andCondition, index) => index === andConditionIndex ? newAndCondition : { + ...andCondition + }); + return selectedConditions.map((orCondition, index) => index === orConditionIndex ? newOrCondition : [...orCondition]); +}; +const _addAndCondition = ({ + selectedConditions, + orConditionIndex, + andConditionIndex, + andCondition +}) => { + const existingOrCondition = selectedConditions[orConditionIndex], + newOrCondition = existingOrCondition.reduce((newAndConditions, condition, index) => { + newAndConditions.push({ + ...condition + }); + if (index === andConditionIndex || existingOrCondition.length === andConditionIndex && existingOrCondition.length - 1 === index) { + newAndConditions.push(andCondition); + } + return newAndConditions; + }, []); + return selectedConditions.map((orCondition, index) => index === orConditionIndex ? newOrCondition : [...orCondition]); +}; +const _removeAndCondition = ({ + selectedConditions, + orConditionIndex, + andConditionIndex +}) => { + const newOrCondition = selectedConditions[orConditionIndex].reduce((newAndConditions, condition, index) => { + if (index !== andConditionIndex) { + newAndConditions.push({ + ...condition + }); + } + return newAndConditions; + }, []); + return selectedConditions.reduce((newOrConditions, orCondition, index) => { + if (index === orConditionIndex && newOrCondition.length) { + newOrConditions.push(newOrCondition); + } + if (index !== orConditionIndex) { + newOrConditions.push([...orCondition]); + } + return newOrConditions; + }, []); +}; +const _setErrors = ({ + selectedConditions, + orConditionIndex, + andConditionIndex, + errors +}) => { + const newOrCondition = [...selectedConditions[orConditionIndex]], + newAndCondition = { + ...newOrCondition[andConditionIndex] + }; + newAndCondition.errors = { + ...newAndCondition.errors, + ...errors + }; + newOrCondition[andConditionIndex] = newAndCondition; + return selectedConditions.map((orCondition, index) => index === orConditionIndex ? [...newOrCondition] : [...orCondition]); +}; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/utils/constants.js": +/*!*************************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/utils/constants.js ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DISABLED_CONTROL_CONFIG = exports.DEFAULT_CONTROL_VALUES = exports.CONTROL_TYPES = exports.ACTION_TYPES = void 0; +// These values will match the Controls_Manager +const CONTROL_TYPES = exports.CONTROL_TYPES = { + MULTIPLE_SELECT: 'select2', + SELECT: 'select', + QUERY: 'query', + DATE_TIME: 'date_time', + TEXT_FIELD: 'text' +}; +const DEFAULT_CONTROL_VALUES = exports.DEFAULT_CONTROL_VALUES = { + select2: [], + query: [], + select: '', + text: '', + date_time: null +}; +const ACTION_TYPES = exports.ACTION_TYPES = { + CHANGE_CONTROL_VALUE: 'CHANGE_CONTROL_VALUE', + SET_ERRORS: 'SET_ERRORS', + ADD_OR_CONDITION: 'ADD_OR_CONDITION', + CHANGE_CONDITION_TYPE: 'CHANGE_CONDITION_TYPE', + ADD_AND_CONDITION: 'ADD_AND_CONDITION', + REMOVE_AND_CONDITION: 'REMOVE_AND_CONDITION', + REMOVE_OR_CONDITION: 'REMOVE_OR_CONDITION' +}; +const DISABLED_CONTROL_CONFIG = exports.DISABLED_CONTROL_CONFIG = { + CONDITION_NAME: 'dynamic_tags', + CONTROL_NAME: 'dynamic_tag_value', + COMPARATORS: ['is_empty', 'is_not_empty'] +}; + +/***/ }), + +/***/ "../modules/display-conditions/assets/js/editor/utils/utils.js": +/*!*********************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/utils/utils.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getControlDefaults = exports.getConditionInitialState = void 0; +exports.getControlValue = getControlValue; +exports.getControlValueMaxWidth = getControlValueMaxWidth; +exports.getDefaultActiveCondition = getDefaultActiveCondition; +exports.getInvalidInputFeedback = getInvalidInputFeedback; +exports.getSelectOptionMaxWidth = getSelectOptionMaxWidth; +exports.hasDecimalSeparator = hasDecimalSeparator; +exports.shouldCastToArray = shouldCastToArray; +exports.shouldDisableControl = shouldDisableControl; +exports.shouldEmptyValuePassValidation = shouldEmptyValuePassValidation; +var _constants = __webpack_require__(/*! ./constants */ "../modules/display-conditions/assets/js/editor/utils/constants.js"); +function shouldCastToArray(controlType) { + return _constants.CONTROL_TYPES.MULTIPLE_SELECT === controlType || _constants.CONTROL_TYPES.QUERY === controlType; +} +function getDefaultActiveCondition(conditionsByGroup) { + return Object.values(conditionsByGroup)[0][0]; +} +function getInvalidInputFeedback(type, variant, value, shouldShow = false) { + return !value?.length ? { + message: _getErrorMessage(type, variant), + shouldShow + } : {}; +} +const getControlDefaults = (controlKey, control) => { + const { + type, + variant = null, + options + } = control, + defaultValue = control?.default || (options && _constants.CONTROL_TYPES.MULTIPLE_SELECT !== type ? Object.keys(options)[0] : _constants.DEFAULT_CONTROL_VALUES[type]), + formattedDefaultValue = shouldCastToArray(type) && !Array.isArray(defaultValue) ? [defaultValue] : defaultValue, + error = getInvalidInputFeedback(type, variant, formattedDefaultValue); + return { + defaultValue: formattedDefaultValue, + error + }; +}; +exports.getControlDefaults = getControlDefaults; +const getConditionInitialState = (conditions, conditionKey) => { + const { + controls = {} + } = conditions?.[conditionKey] || {}; + return Object.keys(controls).reduce((defaults, controlKey) => { + if ('__settings' === controlKey) { + return defaults; + } + const { + defaultValue, + error + } = getControlDefaults(controlKey, controls[controlKey]); + defaults[controlKey] = defaultValue; + defaults.errors[controlKey] = error; + return defaults; + }, { + errors: {} + }); +}; +exports.getConditionInitialState = getConditionInitialState; +function hasDecimalSeparator(newValue) { + if (isNaN(parseFloat(newValue))) { + return false; + } + if (newValue.toString().indexOf('.') !== -1) { + return true; + } + if (newValue.toString().indexOf(',') !== -1) { + return true; + } +} +function getSelectOptionMaxWidth(controlCount) { + return 3 === controlCount ? 200 : 150; +} +function getControlValueMaxWidth(controlCount) { + return 3 === controlCount ? 190 : 135; +} +function getControlValue(value, altValue) { + return 'undefined' !== typeof value ? value : altValue; +} +function _getErrorMessage(controlType, variant = null) { + if (shouldCastToArray(controlType)) { + return __('Select an option', 'elementor-pro'); + } + if (_constants.CONTROL_TYPES.DATE_TIME === controlType) { + return 'time' === variant ? __('Select a time', 'elementor-pro') : __('Select a date', 'elementor-pro'); + } + return __('Enter a value', 'elementor-pro'); +} +function shouldDisableControl(control, comparator) { + return _constants.DISABLED_CONTROL_CONFIG.CONTROL_NAME === control && _constants.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(comparator); +} +function shouldEmptyValuePassValidation(condition, comparator) { + return _constants.DISABLED_CONTROL_CONFIG.CONDITION_NAME === condition && _constants.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(comparator); +} + +/***/ }), + +/***/ "../node_modules/dayjs/dayjs.min.js": +/*!******************************************!*\ + !*** ../node_modules/dayjs/dayjs.min.js ***! + \******************************************/ +/***/ (function(module) { + +!function(t,e){ true?module.exports=e():0}(this,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return b},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t) { + +"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + + +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/checkPropTypes.js": +/*!****************************************************!*\ + !*** ../node_modules/prop-types/checkPropTypes.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var printWarning = function() {}; + +if (true) { + var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); + var loggedTypeFailures = {}; + var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); + + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) { /**/ } + }; +} + +/** + * Assert that the values match with the type specs. + * Error messages are memorized and will only be shown once. + * + * @param {object} typeSpecs Map of name to a ReactPropType + * @param {object} values Runtime values that need to be type-checked + * @param {string} location e.g. "prop", "context", "child context" + * @param {string} componentName Name of the component for error messages. + * @param {?Function} getStack Returns the component stack. + * @private + */ +function checkPropTypes(typeSpecs, values, location, componentName, getStack) { + if (true) { + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== 'function') { + var err = Error( + (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.' + ); + err.name = 'Invariant Violation'; + throw err; + } + error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); + } catch (ex) { + error = ex; + } + if (error && !(error instanceof Error)) { + printWarning( + (componentName || 'React class') + ': type specification of ' + + location + ' `' + typeSpecName + '` is invalid; the type checker ' + + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + + 'You may have forgotten to pass an argument to the type checker ' + + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + + 'shape all require an argument).' + ); + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var stack = getStack ? getStack() : ''; + + printWarning( + 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') + ); + } + } + } + } +} + +/** + * Resets warning cache when testing. + * + * @private + */ +checkPropTypes.resetWarningCache = function() { + if (true) { + loggedTypeFailures = {}; + } +} + +module.exports = checkPropTypes; + + +/***/ }), + +/***/ "../node_modules/prop-types/factoryWithTypeCheckers.js": +/*!*************************************************************!*\ + !*** ../node_modules/prop-types/factoryWithTypeCheckers.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); +var assign = __webpack_require__(/*! object-assign */ "../node_modules/object-assign/index.js"); + +var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ "../node_modules/prop-types/lib/ReactPropTypesSecret.js"); +var has = __webpack_require__(/*! ./lib/has */ "../node_modules/prop-types/lib/has.js"); +var checkPropTypes = __webpack_require__(/*! ./checkPropTypes */ "../node_modules/prop-types/checkPropTypes.js"); + +var printWarning = function() {}; + +if (true) { + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; +} + +function emptyFunctionThatReturnsNull() { + return null; +} + +module.exports = function(isValidElement, throwOnDirectAccess) { + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + /** + * Collection of methods that allow declaration and validation of props that are + * supplied to React components. Example usage: + * + * var Props = require('ReactPropTypes'); + * var MyArticle = React.createClass({ + * propTypes: { + * // An optional string prop named "description". + * description: Props.string, + * + * // A required enum prop named "category". + * category: Props.oneOf(['News','Photos']).isRequired, + * + * // A prop named "dialog" that requires an instance of Dialog. + * dialog: Props.instanceOf(Dialog).isRequired + * }, + * render: function() { ... } + * }); + * + * A more formal specification of how these methods are used: + * + * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) + * decl := ReactPropTypes.{type}(.isRequired)? + * + * Each and every declaration produces a function with the same signature. This + * allows the creation of custom validation functions. For example: + * + * var MyLink = React.createClass({ + * propTypes: { + * // An optional string or URI prop named "href". + * href: function(props, propName, componentName) { + * var propValue = props[propName]; + * if (propValue != null && typeof propValue !== 'string' && + * !(propValue instanceof URI)) { + * return new Error( + * 'Expected a string or an URI for ' + propName + ' in ' + + * componentName + * ); + * } + * } + * }, + * render: function() {...} + * }); + * + * @internal + */ + + var ANONYMOUS = '<>'; + + // Important! + // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. + var ReactPropTypes = { + array: createPrimitiveTypeChecker('array'), + bigint: createPrimitiveTypeChecker('bigint'), + bool: createPrimitiveTypeChecker('boolean'), + func: createPrimitiveTypeChecker('function'), + number: createPrimitiveTypeChecker('number'), + object: createPrimitiveTypeChecker('object'), + string: createPrimitiveTypeChecker('string'), + symbol: createPrimitiveTypeChecker('symbol'), + + any: createAnyTypeChecker(), + arrayOf: createArrayOfTypeChecker, + element: createElementTypeChecker(), + elementType: createElementTypeTypeChecker(), + instanceOf: createInstanceTypeChecker, + node: createNodeChecker(), + objectOf: createObjectOfTypeChecker, + oneOf: createEnumTypeChecker, + oneOfType: createUnionTypeChecker, + shape: createShapeTypeChecker, + exact: createStrictShapeTypeChecker, + }; + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + /*eslint-disable no-self-compare*/ + function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return x !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } + } + /*eslint-enable no-self-compare*/ + + /** + * We use an Error-like object for backward compatibility as people may call + * PropTypes directly and inspect their output. However, we don't use real + * Errors anymore. We don't inspect their stack anyway, and creating them + * is prohibitively expensive if they are created too often, such as what + * happens in oneOfType() for any type before the one that matched. + */ + function PropTypeError(message, data) { + this.message = message; + this.data = data && typeof data === 'object' ? data: {}; + this.stack = ''; + } + // Make `instanceof Error` still work for returned errors. + PropTypeError.prototype = Error.prototype; + + function createChainableTypeChecker(validate) { + if (true) { + var manualPropTypeCallCache = {}; + var manualPropTypeWarningCount = 0; + } + function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { + componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; + + if (secret !== ReactPropTypesSecret) { + if (throwOnDirectAccess) { + // New behavior only for users of `prop-types` package + var err = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + + 'Use `PropTypes.checkPropTypes()` to call them. ' + + 'Read more at http://fb.me/use-check-prop-types' + ); + err.name = 'Invariant Violation'; + throw err; + } else if ( true && typeof console !== 'undefined') { + // Old behavior for people using React.PropTypes + var cacheKey = componentName + ':' + propName; + if ( + !manualPropTypeCallCache[cacheKey] && + // Avoid spamming the console because they are often not actionable except for lib authors + manualPropTypeWarningCount < 3 + ) { + printWarning( + 'You are manually calling a React.PropTypes validation ' + + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + + 'and will throw in the standalone `prop-types` package. ' + + 'You may be seeing this warning due to a third-party PropTypes ' + + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.' + ); + manualPropTypeCallCache[cacheKey] = true; + manualPropTypeWarningCount++; + } + } + } + if (props[propName] == null) { + if (isRequired) { + if (props[propName] === null) { + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); + } + return null; + } else { + return validate(props, propName, componentName, location, propFullName); + } + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; + } + + function createPrimitiveTypeChecker(expectedType) { + function validate(props, propName, componentName, location, propFullName, secret) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== expectedType) { + // `propValue` being instance of, say, date/regexp, pass the 'object' + // check, but we can offer a more precise error message here rather than + // 'of type `object`'. + var preciseType = getPreciseType(propValue); + + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'), + {expectedType: expectedType} + ); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createAnyTypeChecker() { + return createChainableTypeChecker(emptyFunctionThatReturnsNull); + } + + function createArrayOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); + } + var propValue = props[propName]; + if (!Array.isArray(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); + } + for (var i = 0; i < propValue.length; i++) { + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!isValidElement(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!ReactIs.isValidElementType(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createInstanceTypeChecker(expectedClass) { + function validate(props, propName, componentName, location, propFullName) { + if (!(props[propName] instanceof expectedClass)) { + var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createEnumTypeChecker(expectedValues) { + if (!Array.isArray(expectedValues)) { + if (true) { + if (arguments.length > 1) { + printWarning( + 'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' + + 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).' + ); + } else { + printWarning('Invalid argument supplied to oneOf, expected an array.'); + } + } + return emptyFunctionThatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + for (var i = 0; i < expectedValues.length; i++) { + if (is(propValue, expectedValues[i])) { + return null; + } + } + + var valuesString = JSON.stringify(expectedValues, function replacer(key, value) { + var type = getPreciseType(value); + if (type === 'symbol') { + return String(value); + } + return value; + }); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); + } + return createChainableTypeChecker(validate); + } + + function createObjectOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); + } + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); + } + for (var key in propValue) { + if (has(propValue, key)) { + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createUnionTypeChecker(arrayOfTypeCheckers) { + if (!Array.isArray(arrayOfTypeCheckers)) { + true ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : 0; + return emptyFunctionThatReturnsNull; + } + + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (typeof checker !== 'function') { + printWarning( + 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.' + ); + return emptyFunctionThatReturnsNull; + } + } + + function validate(props, propName, componentName, location, propFullName) { + var expectedTypes = []; + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret); + if (checkerResult == null) { + return null; + } + if (checkerResult.data && has(checkerResult.data, 'expectedType')) { + expectedTypes.push(checkerResult.data.expectedType); + } + } + var expectedTypesMessage = (expectedTypes.length > 0) ? ', expected one of type [' + expectedTypes.join(', ') + ']': ''; + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.')); + } + return createChainableTypeChecker(validate); + } + + function createNodeChecker() { + function validate(props, propName, componentName, location, propFullName) { + if (!isNode(props[propName])) { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function invalidValidatorError(componentName, location, propFullName, key, type) { + return new PropTypeError( + (componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + type + '`.' + ); + } + + function createShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + for (var key in shapeTypes) { + var checker = shapeTypes[key]; + if (typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createStrictShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + // We need to check all keys in case some are required but missing from props. + var allKeys = assign({}, props[propName], shapeTypes); + for (var key in allKeys) { + var checker = shapeTypes[key]; + if (has(shapeTypes, key) && typeof checker !== 'function') { + return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker)); + } + if (!checker) { + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') + ); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + + return createChainableTypeChecker(validate); + } + + function isNode(propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + case 'undefined': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (propValue === null || isValidElement(propValue)) { + return true; + } + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } + } + } else { + return false; + } + + return true; + default: + return false; + } + } + + function isSymbol(propType, propValue) { + // Native Symbol. + if (propType === 'symbol') { + return true; + } + + // falsy value can't be a Symbol + if (!propValue) { + return false; + } + + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' + if (propValue['@@toStringTag'] === 'Symbol') { + return true; + } + + // Fallback for non-spec compliant Symbols which are polyfilled. + if (typeof Symbol === 'function' && propValue instanceof Symbol) { + return true; + } + + return false; + } + + // Equivalent of `typeof` but with special handling for array and regexp. + function getPropType(propValue) { + var propType = typeof propValue; + if (Array.isArray(propValue)) { + return 'array'; + } + if (propValue instanceof RegExp) { + // Old webkits (at least until Android 4.0) return 'function' rather than + // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ + // passes PropTypes.object. + return 'object'; + } + if (isSymbol(propType, propValue)) { + return 'symbol'; + } + return propType; + } + + // This handles more types than `getPropType`. Only used for error messages. + // See `createPrimitiveTypeChecker`. + function getPreciseType(propValue) { + if (typeof propValue === 'undefined' || propValue === null) { + return '' + propValue; + } + var propType = getPropType(propValue); + if (propType === 'object') { + if (propValue instanceof Date) { + return 'date'; + } else if (propValue instanceof RegExp) { + return 'regexp'; + } + } + return propType; + } + + // Returns a string that is postfixed to a warning about an invalid type. + // For example, "undefined" or "of type array" + function getPostfixForTypeWarning(value) { + var type = getPreciseType(value); + switch (type) { + case 'array': + case 'object': + return 'an ' + type; + case 'boolean': + case 'date': + case 'regexp': + return 'a ' + type; + default: + return type; + } + } + + // Returns class name of the object, if any. + function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return ANONYMOUS; + } + return propValue.constructor.name; + } + + ReactPropTypes.checkPropTypes = checkPropTypes; + ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; +}; + + +/***/ }), + +/***/ "../node_modules/prop-types/index.js": +/*!*******************************************!*\ + !*** ../node_modules/prop-types/index.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +if (true) { + var ReactIs = __webpack_require__(/*! react-is */ "../node_modules/prop-types/node_modules/react-is/index.js"); + + // By explicitly using `prop-types` you are opting into new development behavior. + // http://fb.me/prop-types-in-prod + var throwOnDirectAccess = true; + module.exports = __webpack_require__(/*! ./factoryWithTypeCheckers */ "../node_modules/prop-types/factoryWithTypeCheckers.js")(ReactIs.isElement, throwOnDirectAccess); +} else {} + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/ReactPropTypesSecret.js": +/*!**************************************************************!*\ + !*** ../node_modules/prop-types/lib/ReactPropTypesSecret.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + +module.exports = ReactPropTypesSecret; + + +/***/ }), + +/***/ "../node_modules/prop-types/lib/has.js": +/*!*********************************************!*\ + !*** ../node_modules/prop-types/lib/has.js ***! + \*********************************************/ +/***/ ((module) => { + +module.exports = Function.call.bind(Object.prototype.hasOwnProperty); + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js": +/*!************************************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** @license React v16.13.1 + * react-is.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + + + +if (true) { + (function() { +'use strict'; + +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === 'function' && Symbol.for; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + +var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; +var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; +var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8; +var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; +var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4; +var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7; + +function isValidElementType(type) { + return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill. + type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE); +} + +function typeOf(object) { + if (typeof object === 'object' && object !== null) { + var $$typeof = object.$$typeof; + + switch ($$typeof) { + case REACT_ELEMENT_TYPE: + var type = object.type; + + switch (type) { + case REACT_ASYNC_MODE_TYPE: + case REACT_CONCURRENT_MODE_TYPE: + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: + return type; + + default: + var $$typeofType = type && type.$$typeof; + + switch ($$typeofType) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_LAZY_TYPE: + case REACT_MEMO_TYPE: + case REACT_PROVIDER_TYPE: + return $$typeofType; + + default: + return $$typeof; + } + + } + + case REACT_PORTAL_TYPE: + return $$typeof; + } + } + + return undefined; +} // AsyncMode is deprecated along with isAsyncMode + +var AsyncMode = REACT_ASYNC_MODE_TYPE; +var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE; +var ContextConsumer = REACT_CONTEXT_TYPE; +var ContextProvider = REACT_PROVIDER_TYPE; +var Element = REACT_ELEMENT_TYPE; +var ForwardRef = REACT_FORWARD_REF_TYPE; +var Fragment = REACT_FRAGMENT_TYPE; +var Lazy = REACT_LAZY_TYPE; +var Memo = REACT_MEMO_TYPE; +var Portal = REACT_PORTAL_TYPE; +var Profiler = REACT_PROFILER_TYPE; +var StrictMode = REACT_STRICT_MODE_TYPE; +var Suspense = REACT_SUSPENSE_TYPE; +var hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated + +function isAsyncMode(object) { + { + if (!hasWarnedAboutDeprecatedIsAsyncMode) { + hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint + + console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.'); + } + } + + return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE; +} +function isConcurrentMode(object) { + return typeOf(object) === REACT_CONCURRENT_MODE_TYPE; +} +function isContextConsumer(object) { + return typeOf(object) === REACT_CONTEXT_TYPE; +} +function isContextProvider(object) { + return typeOf(object) === REACT_PROVIDER_TYPE; +} +function isElement(object) { + return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; +} +function isForwardRef(object) { + return typeOf(object) === REACT_FORWARD_REF_TYPE; +} +function isFragment(object) { + return typeOf(object) === REACT_FRAGMENT_TYPE; +} +function isLazy(object) { + return typeOf(object) === REACT_LAZY_TYPE; +} +function isMemo(object) { + return typeOf(object) === REACT_MEMO_TYPE; +} +function isPortal(object) { + return typeOf(object) === REACT_PORTAL_TYPE; +} +function isProfiler(object) { + return typeOf(object) === REACT_PROFILER_TYPE; +} +function isStrictMode(object) { + return typeOf(object) === REACT_STRICT_MODE_TYPE; +} +function isSuspense(object) { + return typeOf(object) === REACT_SUSPENSE_TYPE; +} + +exports.AsyncMode = AsyncMode; +exports.ConcurrentMode = ConcurrentMode; +exports.ContextConsumer = ContextConsumer; +exports.ContextProvider = ContextProvider; +exports.Element = Element; +exports.ForwardRef = ForwardRef; +exports.Fragment = Fragment; +exports.Lazy = Lazy; +exports.Memo = Memo; +exports.Portal = Portal; +exports.Profiler = Profiler; +exports.StrictMode = StrictMode; +exports.Suspense = Suspense; +exports.isAsyncMode = isAsyncMode; +exports.isConcurrentMode = isConcurrentMode; +exports.isContextConsumer = isContextConsumer; +exports.isContextProvider = isContextProvider; +exports.isElement = isElement; +exports.isForwardRef = isForwardRef; +exports.isFragment = isFragment; +exports.isLazy = isLazy; +exports.isMemo = isMemo; +exports.isPortal = isPortal; +exports.isProfiler = isProfiler; +exports.isStrictMode = isStrictMode; +exports.isSuspense = isSuspense; +exports.isValidElementType = isValidElementType; +exports.typeOf = typeOf; + })(); +} + + +/***/ }), + +/***/ "../node_modules/prop-types/node_modules/react-is/index.js": +/*!*****************************************************************!*\ + !*** ../node_modules/prop-types/node_modules/react-is/index.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +if (false) {} else { + module.exports = __webpack_require__(/*! ./cjs/react-is.development.js */ "../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js"); +} + + +/***/ }), + +/***/ "react": +/*!************************!*\ + !*** external "React" ***! + \************************/ +/***/ ((module) => { + +"use strict"; +module.exports = React; + +/***/ }), + +/***/ "@elementor/icons": +/*!************************************!*\ + !*** external "elementorV2.icons" ***! + \************************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorV2.icons; + +/***/ }), + +/***/ "@elementor/ui": +/*!*********************************!*\ + !*** external "elementorV2.ui" ***! + \*********************************/ +/***/ ((module) => { + +"use strict"; +module.exports = elementorV2.ui; + +/***/ }), + +/***/ "@wordpress/i18n": +/*!**************************!*\ + !*** external "wp.i18n" ***! + \**************************/ +/***/ ((module) => { + +"use strict"; +module.exports = wp.i18n; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/extends.js": +/*!*********************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/extends.js ***! + \*********************************************************/ +/***/ ((module) => { + +function _extends() { + return module.exports = _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends.apply(null, arguments); +} +module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js": +/*!***********************************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! + \***********************************************************************/ +/***/ ((module) => { + +function _interopRequireDefault(e) { + return e && e.__esModule ? e : { + "default": e + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/core-js/internals/a-callable.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/a-callable.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var tryToString = __webpack_require__(/*! ../internals/try-to-string */ "../node_modules/core-js/internals/try-to-string.js"); + +var $TypeError = TypeError; + +// `Assert: IsCallable(argument) is true` +module.exports = function (argument) { + if (isCallable(argument)) return argument; + throw new $TypeError(tryToString(argument) + ' is not a function'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/an-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/an-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $String = String; +var $TypeError = TypeError; + +// `Assert: Type(argument) is Object` +module.exports = function (argument) { + if (isObject(argument)) return argument; + throw new $TypeError($String(argument) + ' is not an object'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-includes.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/array-includes.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ "../node_modules/core-js/internals/to-absolute-index.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); + +// `Array.prototype.{ indexOf, includes }` methods implementation +var createMethod = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = lengthOfArrayLike(O); + if (length === 0) return !IS_INCLUDES && -1; + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare -- NaN check + if (IS_INCLUDES && el !== el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare -- NaN check + if (value !== value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) { + if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +module.exports = { + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod(false) +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-set-length.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/array-set-length.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var isArray = __webpack_require__(/*! ../internals/is-array */ "../node_modules/core-js/internals/is-array.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Safari < 13 does not throw an error in this case +var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () { + // makes no sense without proper strict mode support + if (this !== undefined) return true; + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).length = 1; + } catch (error) { + return error instanceof TypeError; + } +}(); + +module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { + if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) { + throw new $TypeError('Cannot set read only .length'); + } return O.length = length; +} : function (O, length) { + return O.length = length; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/classof-raw.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/classof-raw.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var toString = uncurryThis({}.toString); +var stringSlice = uncurryThis(''.slice); + +module.exports = function (it) { + return stringSlice(toString(it), 8, -1); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/copy-constructor-properties.js": +/*!************************************************************************!*\ + !*** ../node_modules/core-js/internals/copy-constructor-properties.js ***! + \************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var ownKeys = __webpack_require__(/*! ../internals/own-keys */ "../node_modules/core-js/internals/own-keys.js"); +var getOwnPropertyDescriptorModule = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); + +module.exports = function (target, source, exceptions) { + var keys = ownKeys(source); + var defineProperty = definePropertyModule.f; + var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) { + defineProperty(target, key, getOwnPropertyDescriptor(source, key)); + } + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-non-enumerable-property.js": +/*!***************************************************************************!*\ + !*** ../node_modules/core-js/internals/create-non-enumerable-property.js ***! + \***************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); + +module.exports = DESCRIPTORS ? function (object, key, value) { + return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-property-descriptor.js": +/*!***********************************************************************!*\ + !*** ../node_modules/core-js/internals/create-property-descriptor.js ***! + \***********************************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-built-in.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/define-built-in.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var makeBuiltIn = __webpack_require__(/*! ../internals/make-built-in */ "../node_modules/core-js/internals/make-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +module.exports = function (O, key, value, options) { + if (!options) options = {}; + var simple = options.enumerable; + var name = options.name !== undefined ? options.name : key; + if (isCallable(value)) makeBuiltIn(value, name, options); + if (options.global) { + if (simple) O[key] = value; + else defineGlobalProperty(key, value); + } else { + try { + if (!options.unsafe) delete O[key]; + else if (O[key]) simple = true; + } catch (error) { /* empty */ } + if (simple) O[key] = value; + else definePropertyModule.f(O, key, { + value: value, + enumerable: false, + configurable: !options.nonConfigurable, + writable: !options.nonWritable + }); + } return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-global-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/define-global-property.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; + +module.exports = function (key, value) { + try { + defineProperty(globalThis, key, { value: value, configurable: true, writable: true }); + } catch (error) { + globalThis[key] = value; + } return value; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/descriptors.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/descriptors.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// Detect IE8's incomplete defineProperty implementation +module.exports = !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/document-create-element.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/document-create-element.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var document = globalThis.document; +// typeof document.createElement is 'object' in old IE +var EXISTS = isObject(document) && isObject(document.createElement); + +module.exports = function (it) { + return EXISTS ? document.createElement(it) : {}; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/does-not-exceed-safe-integer.js ***! + \*************************************************************************/ +/***/ ((module) => { + +"use strict"; + +var $TypeError = TypeError; +var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 + +module.exports = function (it) { + if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded'); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/enum-bug-keys.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/enum-bug-keys.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +// IE8- don't enum bug keys +module.exports = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' +]; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-user-agent.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-user-agent.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var navigator = globalThis.navigator; +var userAgent = navigator && navigator.userAgent; + +module.exports = userAgent ? String(userAgent) : ''; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-v8-version.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-v8-version.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var userAgent = __webpack_require__(/*! ../internals/environment-user-agent */ "../node_modules/core-js/internals/environment-user-agent.js"); + +var process = globalThis.process; +var Deno = globalThis.Deno; +var versions = process && process.versions || Deno && Deno.version; +var v8 = versions && versions.v8; +var match, version; + +if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} + +// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` +// so check `userAgent` even if `.v8` exists, but 0 +if (!version && userAgent) { + match = userAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent.match(/Chrome\/(\d+)/); + if (match) version = +match[1]; + } +} + +module.exports = version; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/export.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/export.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var getOwnPropertyDescriptor = (__webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js").f); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var defineBuiltIn = __webpack_require__(/*! ../internals/define-built-in */ "../node_modules/core-js/internals/define-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); +var copyConstructorProperties = __webpack_require__(/*! ../internals/copy-constructor-properties */ "../node_modules/core-js/internals/copy-constructor-properties.js"); +var isForced = __webpack_require__(/*! ../internals/is-forced */ "../node_modules/core-js/internals/is-forced.js"); + +/* + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.dontCallGetSet - prevent calling a getter on target + options.name - the .name of the function if it does not match the key +*/ +module.exports = function (options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED, target, key, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = globalThis; + } else if (STATIC) { + target = globalThis[TARGET] || defineGlobalProperty(TARGET, {}); + } else { + target = globalThis[TARGET] && globalThis[TARGET].prototype; + } + if (target) for (key in source) { + sourceProperty = source[key]; + if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; + FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); + // contained in target + if (!FORCED && targetProperty !== undefined) { + if (typeof sourceProperty == typeof targetProperty) continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + // add a flag to not completely full polyfills + if (options.sham || (targetProperty && targetProperty.sham)) { + createNonEnumerableProperty(sourceProperty, 'sham', true); + } + defineBuiltIn(target, key, sourceProperty, options); + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/fails.js": +/*!**************************************************!*\ + !*** ../node_modules/core-js/internals/fails.js ***! + \**************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (exec) { + try { + return !!exec(); + } catch (error) { + return true; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-bind-native.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/function-bind-native.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +module.exports = !fails(function () { + // eslint-disable-next-line es/no-function-prototype-bind -- safe + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test != 'function' || test.hasOwnProperty('prototype'); +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-call.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-call.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var call = Function.prototype.call; + +module.exports = NATIVE_BIND ? call.bind(call) : function () { + return call.apply(call, arguments); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-name.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-name.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); + +var FunctionPrototype = Function.prototype; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor; + +var EXISTS = hasOwn(FunctionPrototype, 'name'); +// additional protection from minified / mangled / dropped function names +var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; +var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable)); + +module.exports = { + EXISTS: EXISTS, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-uncurry-this.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/function-uncurry-this.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var FunctionPrototype = Function.prototype; +var call = FunctionPrototype.call; +var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call); + +module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) { + return function () { + return call.apply(fn, arguments); + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-built-in.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/get-built-in.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var aFunction = function (argument) { + return isCallable(argument) ? argument : undefined; +}; + +module.exports = function (namespace, method) { + return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-method.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/get-method.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var aCallable = __webpack_require__(/*! ../internals/a-callable */ "../node_modules/core-js/internals/a-callable.js"); +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +// `GetMethod` abstract operation +// https://tc39.es/ecma262/#sec-getmethod +module.exports = function (V, P) { + var func = V[P]; + return isNullOrUndefined(func) ? undefined : aCallable(func); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/global-this.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/global-this.js ***! + \********************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + +var check = function (it) { + return it && it.Math === Math && it; +}; + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +module.exports = + // eslint-disable-next-line es/no-global-this -- safe + check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == 'object' && self) || + check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) || + check(typeof this == 'object' && this) || + // eslint-disable-next-line no-new-func -- fallback + (function () { return this; })() || Function('return this')(); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/has-own-property.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/has-own-property.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); + +var hasOwnProperty = uncurryThis({}.hasOwnProperty); + +// `HasOwnProperty` abstract operation +// https://tc39.es/ecma262/#sec-hasownproperty +// eslint-disable-next-line es/no-object-hasown -- safe +module.exports = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty(toObject(it), key); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/hidden-keys.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/hidden-keys.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = {}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ie8-dom-define.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/ie8-dom-define.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var createElement = __webpack_require__(/*! ../internals/document-create-element */ "../node_modules/core-js/internals/document-create-element.js"); + +// Thanks to IE8 for its funny defineProperty +module.exports = !DESCRIPTORS && !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(createElement('div'), 'a', { + get: function () { return 7; } + }).a !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/indexed-object.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/indexed-object.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +var $Object = Object; +var split = uncurryThis(''.split); + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +module.exports = fails(function () { + // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 + // eslint-disable-next-line no-prototype-builtins -- safe + return !$Object('z').propertyIsEnumerable(0); +}) ? function (it) { + return classof(it) === 'String' ? split(it, '') : $Object(it); +} : $Object; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/inspect-source.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/inspect-source.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +var functionToString = uncurryThis(Function.toString); + +// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper +if (!isCallable(store.inspectSource)) { + store.inspectSource = function (it) { + return functionToString(it); + }; +} + +module.exports = store.inspectSource; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/internal-state.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/internal-state.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/weak-map-basic-detection */ "../node_modules/core-js/internals/weak-map-basic-detection.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var shared = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); +var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "../node_modules/core-js/internals/shared-key.js"); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; +var TypeError = globalThis.TypeError; +var WeakMap = globalThis.WeakMap; +var set, get, has; + +var enforce = function (it) { + return has(it) ? get(it) : set(it, {}); +}; + +var getterFor = function (TYPE) { + return function (it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw new TypeError('Incompatible receiver, ' + TYPE + ' required'); + } return state; + }; +}; + +if (NATIVE_WEAK_MAP || shared.state) { + var store = shared.state || (shared.state = new WeakMap()); + /* eslint-disable no-self-assign -- prototype methods protection */ + store.get = store.get; + store.has = store.has; + store.set = store.set; + /* eslint-enable no-self-assign -- prototype methods protection */ + set = function (it, metadata) { + if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + store.set(it, metadata); + return metadata; + }; + get = function (it) { + return store.get(it) || {}; + }; + has = function (it) { + return store.has(it); + }; +} else { + var STATE = sharedKey('state'); + hiddenKeys[STATE] = true; + set = function (it, metadata) { + if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty(it, STATE, metadata); + return metadata; + }; + get = function (it) { + return hasOwn(it, STATE) ? it[STATE] : {}; + }; + has = function (it) { + return hasOwn(it, STATE); + }; +} + +module.exports = { + set: set, + get: get, + has: has, + enforce: enforce, + getterFor: getterFor +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-array.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/is-array.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +// `IsArray` abstract operation +// https://tc39.es/ecma262/#sec-isarray +// eslint-disable-next-line es/no-array-isarray -- safe +module.exports = Array.isArray || function isArray(argument) { + return classof(argument) === 'Array'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-callable.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/is-callable.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot +var documentAll = typeof document == 'object' && document.all; + +// `IsCallable` abstract operation +// https://tc39.es/ecma262/#sec-iscallable +// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing +module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) { + return typeof argument == 'function' || argument === documentAll; +} : function (argument) { + return typeof argument == 'function'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-forced.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-forced.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var replacement = /#|\.prototype\./; + +var isForced = function (feature, detection) { + var value = data[normalize(feature)]; + return value === POLYFILL ? true + : value === NATIVE ? false + : isCallable(detection) ? fails(detection) + : !!detection; +}; + +var normalize = isForced.normalize = function (string) { + return String(string).replace(replacement, '.').toLowerCase(); +}; + +var data = isForced.data = {}; +var NATIVE = isForced.NATIVE = 'N'; +var POLYFILL = isForced.POLYFILL = 'P'; + +module.exports = isForced; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-null-or-undefined.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/is-null-or-undefined.js ***! + \*****************************************************************/ +/***/ ((module) => { + +"use strict"; + +// we can't use just `it == null` since of `document.all` special case +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec +module.exports = function (it) { + return it === null || it === undefined; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +module.exports = function (it) { + return typeof it == 'object' ? it !== null : isCallable(it); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-pure.js": +/*!****************************************************!*\ + !*** ../node_modules/core-js/internals/is-pure.js ***! + \****************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = false; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-symbol.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-symbol.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isPrototypeOf = __webpack_require__(/*! ../internals/object-is-prototype-of */ "../node_modules/core-js/internals/object-is-prototype-of.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var $Object = Object; + +module.exports = USE_SYMBOL_AS_UID ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + var $Symbol = getBuiltIn('Symbol'); + return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/length-of-array-like.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/length-of-array-like.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toLength = __webpack_require__(/*! ../internals/to-length */ "../node_modules/core-js/internals/to-length.js"); + +// `LengthOfArrayLike` abstract operation +// https://tc39.es/ecma262/#sec-lengthofarraylike +module.exports = function (obj) { + return toLength(obj.length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/make-built-in.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/make-built-in.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(/*! ../internals/function-name */ "../node_modules/core-js/internals/function-name.js").CONFIGURABLE); +var inspectSource = __webpack_require__(/*! ../internals/inspect-source */ "../node_modules/core-js/internals/inspect-source.js"); +var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "../node_modules/core-js/internals/internal-state.js"); + +var enforceInternalState = InternalStateModule.enforce; +var getInternalState = InternalStateModule.get; +var $String = String; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; +var stringSlice = uncurryThis(''.slice); +var replace = uncurryThis(''.replace); +var join = uncurryThis([].join); + +var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () { + return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; +}); + +var TEMPLATE = String(String).split('String'); + +var makeBuiltIn = module.exports = function (value, name, options) { + if (stringSlice($String(name), 0, 7) === 'Symbol(') { + name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']'; + } + if (options && options.getter) name = 'get ' + name; + if (options && options.setter) name = 'set ' + name; + if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) { + if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true }); + else value.name = name; + } + if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { + defineProperty(value, 'length', { value: options.arity }); + } + try { + if (options && hasOwn(options, 'constructor') && options.constructor) { + if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false }); + // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable + } else if (value.prototype) value.prototype = undefined; + } catch (error) { /* empty */ } + var state = enforceInternalState(value); + if (!hasOwn(state, 'source')) { + state.source = join(TEMPLATE, typeof name == 'string' ? name : ''); + } return value; +}; + +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +// eslint-disable-next-line no-extend-native -- required +Function.prototype.toString = makeBuiltIn(function toString() { + return isCallable(this) && getInternalState(this).source || inspectSource(this); +}, 'toString'); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/math-trunc.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/math-trunc.js ***! + \*******************************************************/ +/***/ ((module) => { + +"use strict"; + +var ceil = Math.ceil; +var floor = Math.floor; + +// `Math.trunc` method +// https://tc39.es/ecma262/#sec-math.trunc +// eslint-disable-next-line es/no-math-trunc -- safe +module.exports = Math.trunc || function trunc(x) { + var n = +x; + return (n > 0 ? floor : ceil)(n); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-define-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-define-property.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); +var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(/*! ../internals/v8-prototype-define-bug */ "../node_modules/core-js/internals/v8-prototype-define-bug.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var $defineProperty = Object.defineProperty; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var ENUMERABLE = 'enumerable'; +var CONFIGURABLE = 'configurable'; +var WRITABLE = 'writable'; + +// `Object.defineProperty` method +// https://tc39.es/ecma262/#sec-object.defineproperty +exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor(O, P); + if (current && current[WRITABLE]) { + O[P] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } return $defineProperty(O, P, Attributes); +} : $defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return $defineProperty(O, P, Attributes); + } catch (error) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-descriptor.js": +/*!*******************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-descriptor.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ "../node_modules/core-js/internals/object-property-is-enumerable.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// `Object.getOwnPropertyDescriptor` method +// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor +exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject(O); + P = toPropertyKey(P); + if (IE8_DOM_DEFINE) try { + return $getOwnPropertyDescriptor(O, P); + } catch (error) { /* empty */ } + if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-names.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-names.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ "../node_modules/core-js/internals/object-keys-internal.js"); +var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "../node_modules/core-js/internals/enum-bug-keys.js"); + +var hiddenKeys = enumBugKeys.concat('length', 'prototype'); + +// `Object.getOwnPropertyNames` method +// https://tc39.es/ecma262/#sec-object.getownpropertynames +// eslint-disable-next-line es/no-object-getownpropertynames -- safe +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return internalObjectKeys(O, hiddenKeys); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-symbols.js": +/*!****************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-symbols.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe +exports.f = Object.getOwnPropertySymbols; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-is-prototype-of.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-is-prototype-of.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +module.exports = uncurryThis({}.isPrototypeOf); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-keys-internal.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/object-keys-internal.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var indexOf = (__webpack_require__(/*! ../internals/array-includes */ "../node_modules/core-js/internals/array-includes.js").indexOf); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var push = uncurryThis([].push); + +module.exports = function (object, names) { + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key; + for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key); + // Don't enum bug & hidden keys + while (names.length > i) if (hasOwn(O, key = names[i++])) { + ~indexOf(result, key) || push(result, key); + } + return result; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-property-is-enumerable.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-property-is-enumerable.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +var $propertyIsEnumerable = {}.propertyIsEnumerable; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Nashorn ~ JDK8 bug +var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1); + +// `Object.prototype.propertyIsEnumerable` method implementation +// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable +exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) { + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; +} : $propertyIsEnumerable; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ordinary-to-primitive.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/ordinary-to-primitive.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $TypeError = TypeError; + +// `OrdinaryToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-ordinarytoprimitive +module.exports = function (input, pref) { + var fn, val; + if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val; + if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + throw new $TypeError("Can't convert object to primitive value"); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/own-keys.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/own-keys.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var getOwnPropertyNamesModule = __webpack_require__(/*! ../internals/object-get-own-property-names */ "../node_modules/core-js/internals/object-get-own-property-names.js"); +var getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ "../node_modules/core-js/internals/object-get-own-property-symbols.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); + +var concat = uncurryThis([].concat); + +// all object keys, includes non-enumerable and symbols +module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { + var keys = getOwnPropertyNamesModule.f(anObject(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/require-object-coercible.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/require-object-coercible.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +var $TypeError = TypeError; + +// `RequireObjectCoercible` abstract operation +// https://tc39.es/ecma262/#sec-requireobjectcoercible +module.exports = function (it) { + if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-key.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/shared-key.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); + +var keys = shared('keys'); + +module.exports = function (key) { + return keys[key] || (keys[key] = uid(key)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-store.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/shared-store.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "../node_modules/core-js/internals/is-pure.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +var SHARED = '__core-js_shared__'; +var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {}); + +(store.versions || (store.versions = [])).push({ + version: '3.38.1', + mode: IS_PURE ? 'pure' : 'global', + copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)', + license: 'https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE', + source: 'https://github.com/zloirock/core-js' +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/shared.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +module.exports = function (key, value) { + return store[key] || (store[key] = value || {}); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/symbol-constructor-detection.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/symbol-constructor-detection.js ***! + \*************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var V8_VERSION = __webpack_require__(/*! ../internals/environment-v8-version */ "../node_modules/core-js/internals/environment-v8-version.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var $String = globalThis.String; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing +module.exports = !!Object.getOwnPropertySymbols && !fails(function () { + var symbol = Symbol('symbol detection'); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will, + // of course, fail. + return !$String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION && V8_VERSION < 41; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-absolute-index.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-absolute-index.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var max = Math.max; +var min = Math.min; + +// Helper for a popular repeating case of the spec: +// Let integer be ? ToInteger(index). +// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). +module.exports = function (index, length) { + var integer = toIntegerOrInfinity(index); + return integer < 0 ? max(integer + length, 0) : min(integer, length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-indexed-object.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-indexed-object.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +// toObject with fallback for non-array-like ES3 strings +var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "../node_modules/core-js/internals/indexed-object.js"); +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +module.exports = function (it) { + return IndexedObject(requireObjectCoercible(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-integer-or-infinity.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/to-integer-or-infinity.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var trunc = __webpack_require__(/*! ../internals/math-trunc */ "../node_modules/core-js/internals/math-trunc.js"); + +// `ToIntegerOrInfinity` abstract operation +// https://tc39.es/ecma262/#sec-tointegerorinfinity +module.exports = function (argument) { + var number = +argument; + // eslint-disable-next-line no-self-compare -- NaN check + return number !== number || number === 0 ? 0 : trunc(number); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-length.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-length.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var min = Math.min; + +// `ToLength` abstract operation +// https://tc39.es/ecma262/#sec-tolength +module.exports = function (argument) { + var len = toIntegerOrInfinity(argument); + return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +var $Object = Object; + +// `ToObject` abstract operation +// https://tc39.es/ecma262/#sec-toobject +module.exports = function (argument) { + return $Object(requireObjectCoercible(argument)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-primitive.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/to-primitive.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); +var getMethod = __webpack_require__(/*! ../internals/get-method */ "../node_modules/core-js/internals/get-method.js"); +var ordinaryToPrimitive = __webpack_require__(/*! ../internals/ordinary-to-primitive */ "../node_modules/core-js/internals/ordinary-to-primitive.js"); +var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "../node_modules/core-js/internals/well-known-symbol.js"); + +var $TypeError = TypeError; +var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); + +// `ToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-toprimitive +module.exports = function (input, pref) { + if (!isObject(input) || isSymbol(input)) return input; + var exoticToPrim = getMethod(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = call(exoticToPrim, input, pref); + if (!isObject(result) || isSymbol(result)) return result; + throw new $TypeError("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-property-key.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/to-property-key.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ "../node_modules/core-js/internals/to-primitive.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); + +// `ToPropertyKey` abstract operation +// https://tc39.es/ecma262/#sec-topropertykey +module.exports = function (argument) { + var key = toPrimitive(argument, 'string'); + return isSymbol(key) ? key : key + ''; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/try-to-string.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/try-to-string.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +var $String = String; + +module.exports = function (argument) { + try { + return $String(argument); + } catch (error) { + return 'Object'; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/uid.js": +/*!************************************************!*\ + !*** ../node_modules/core-js/internals/uid.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var id = 0; +var postfix = Math.random(); +var toString = uncurryThis(1.0.toString); + +module.exports = function (key) { + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/use-symbol-as-uid.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/use-symbol-as-uid.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); + +module.exports = NATIVE_SYMBOL + && !Symbol.sham + && typeof Symbol.iterator == 'symbol'; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/v8-prototype-define-bug.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/v8-prototype-define-bug.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// V8 ~ Chrome 36- +// https://bugs.chromium.org/p/v8/issues/detail?id=3334 +module.exports = DESCRIPTORS && fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype !== 42; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/weak-map-basic-detection.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/weak-map-basic-detection.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var WeakMap = globalThis.WeakMap; + +module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap)); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/well-known-symbol.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/well-known-symbol.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var Symbol = globalThis.Symbol; +var WellKnownSymbolsStore = shared('wks'); +var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid; + +module.exports = function (name) { + if (!hasOwn(WellKnownSymbolsStore, name)) { + WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name) + ? Symbol[name] + : createWellKnownSymbol('Symbol.' + name); + } return WellKnownSymbolsStore[name]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/modules/es.array.push.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/modules/es.array.push.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var $ = __webpack_require__(/*! ../internals/export */ "../node_modules/core-js/internals/export.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); +var setArrayLength = __webpack_require__(/*! ../internals/array-set-length */ "../node_modules/core-js/internals/array-set-length.js"); +var doesNotExceedSafeInteger = __webpack_require__(/*! ../internals/does-not-exceed-safe-integer */ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +var INCORRECT_TO_LENGTH = fails(function () { + return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; +}); + +// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError +// https://bugs.chromium.org/p/v8/issues/detail?id=12681 +var properErrorOnNonWritableLength = function () { + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).push(); + } catch (error) { + return error instanceof TypeError; + } +}; + +var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); + +// `Array.prototype.push` method +// https://tc39.es/ecma262/#sec-array.prototype.push +$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + push: function push(item) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var argCount = arguments.length; + doesNotExceedSafeInteger(len + argCount); + for (var i = 0; i < argCount; i++) { + O[len] = arguments[i]; + len++; + } + setArrayLength(O, len); + return len; + } +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!***************************************************************!*\ + !*** ../modules/display-conditions/assets/js/editor/index.js ***! + \***************************************************************/ + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _module = _interopRequireDefault(__webpack_require__(/*! ./module.js */ "../modules/display-conditions/assets/js/editor/module.js")); +new _module.default(); +})(); + +/******/ })() +; +//# sourceMappingURL=display-conditions.js.map \ No newline at end of file diff --git a/assets/js/display-conditions.min.js b/assets/js/display-conditions.min.js new file mode 100644 index 00000000..9fa9ec2c --- /dev/null +++ b/assets/js/display-conditions.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +(()=>{var e={40:(e,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.replaceUtmPlaceholders=r.htmlDecodeTextContent=r.arrayToClassName=void 0;r.arrayToClassName=(e,r)=>e.filter((e=>"object"==typeof e?Object.entries(e)[0][1]:e)).map((e=>{const n="object"==typeof e?Object.entries(e)[0][0]:e;return r?r(n):n})).join(" ");r.htmlDecodeTextContent=e=>(new DOMParser).parseFromString(e,"text/html").documentElement.textContent;r.replaceUtmPlaceholders=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e&&r?(Object.keys(r).forEach((n=>{const o=new RegExp(`%%${n}%%`,"g");e=e.replace(o,r[n])})),e):e}},3842:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956),u=i(n(7971));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const App=e=>{const[r,n]=(0,a.useState)(!0);(0,a.useEffect)((()=>{if(!r){const r=setTimeout((()=>{e.onClose()}),500);return()=>clearTimeout(r)}}),[r]);return a.default.createElement(s.DirectionProvider,{rtl:e.isRTL},a.default.createElement(s.LocalizationProvider,null,a.default.createElement(s.ThemeProvider,{colorScheme:e.colorScheme},a.default.createElement(s.Dialog,{open:r,fullWidth:!0,maxWidth:"lg",TransitionComponent:s.Fade,transitionDuration:{enter:500,exit:500},sx:{"& .MuiDialog-paper":{height:"calc(100vh - 4rem)",maxHeight:775}}},a.default.createElement(u.default,{getControlValue:e.getControlValue,setControlValue:e.setControlValue,fetchData:e.fetchData,onClose:()=>{n(!1)},conditionsConfig:e.conditionsConfig,setCacheNoticeStatus:e.setCacheNoticeStatus})))))};App.propTypes={colorScheme:o.oneOf(["auto","light","dark"]),isRTL:o.bool,getControlValue:o.func.isRequired,setControlValue:o.func.isRequired,fetchData:o.func.isRequired,onClose:o.func.isRequired,conditionsConfig:o.object.isRequired,setCacheNoticeStatus:o.func.isRequired};r.default=App},19:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=i(n(3842));class DisplayConditionsBehavior extends Marionette.Behavior{ui(){const e=".eicon-flow.e-control-display-conditions";return{displayConditionsButton:e,displayConditionsPromoButton:`${e}-promo`}}events(){return{"click @ui.displayConditionsButton":"onClickControlButtonDisplayConditions","mouseenter @ui.displayConditionsPromoButton":"onHoverControlButtonDisplayConditions"}}onClickControlButtonDisplayConditions(e){e.stopPropagation(),this.mount()}onHoverControlButtonDisplayConditions(e){e.stopPropagation(),elementor.promotion.showDialog({title:o("Display Conditions","elementor-pro"),content:o("","elementor-pro"),targetElement:this.el,actionButton:{url:"https://go.elementor.com/go-pro-advanced-display-conditions/",text:o("Upgrade Now","elementor-pro"),classes:["elementor-button","go-pro"]}})}getRootElement(){let e=window.parent.document.getElementById("elementor-conditions__modal");return e||(e=document.createElement("div"),e.setAttribute("id","elementor-conditions__modal"),e)}mount(){const e=elementor?.getPreferences?.("ui_theme")||"auto",r=elementorCommon.config.isRTL,n=this.getRootElement();window.parent.document.body.appendChild(n),ReactDOM.render(a.default.createElement(s.default,{colorScheme:e,isRTL:r,getControlValue:this.getOption("getControlValue"),setControlValue:this.getOption("setControlValue"),fetchData:this.getOption("fetchData"),onClose:()=>this.unmount(n),conditionsConfig:this.getOption("conditionsConfig"),setCacheNoticeStatus:this.getOption("setCacheNoticeStatus")}),n)}unmount(e){ReactDOM.unmountComponentAtNode(e),e.remove()}}r.default=DisplayConditionsBehavior},5305:(e,r,n)=>{"use strict";var o=n(2688);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),a=n(2470),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const CacheNotice=e=>{let{setCacheNoticeStatus:r}=e;const[n,o]=(0,i.useState)(!0);return i.default.createElement(s.Box,null,i.default.createElement(s.Collapse,{in:n,sx:{px:3}},i.default.createElement(s.Alert,{color:"info",severity:"error",variant:"standard",onClose:async()=>{await r()&&o(!1)},sx:{mt:3}},(0,a.__)("Keep in mind: Certain cache plugins can conflict with your display conditions. ","elementor-pro"),i.default.createElement(s.Link,{href:"https://go.elementor.com/app-display-conditions-cache-notice/",underline:"hover",color:"info.main",target:"_blank",sx:{"&:hover":{color:e=>e.palette.info.main}}},(0,a.__)("Learn more","elementor-pro")))))};CacheNotice.propTypes={setCacheNoticeStatus:o.func.isRequired};r.default=CacheNotice},7946:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=_interopRequireWildcard(n(2688)),s=o(n(7976)),u=n(6956),c=o(n(7459)),f=o(n(6794)),p=o(n(678)),g=o(n(248)),C=n(3726),v=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const ConditionsRepeaterRow=e=>{let{andConditionIndex:r,orConditionIndex:n}=e;const{selectedConditions:o,conditionsConfig:a,dispatch:_}=(0,s.default)(),{conditions:b,flattenedConditionOptions:x}=a,E=o[n][r],R=E?.condition,w=b[R]?.controls||{},P=Object.keys(w).length;return i.createElement(u.Container,{maxWidth:"md",sx:{display:"flex",gap:.5,mb:1,position:"relative"},className:`and-condition-repeater-row and-condition-${r}`},i.createElement(f.default,{id:"condition-select",value:E.condition||"",onChange:e=>(e=>{const o=e.target.value,i={condition:o,...(0,C.getConditionInitialState)(b,o)};_({type:v.ACTION_TYPES.CHANGE_CONDITION_TYPE,orConditionIndex:n,andConditionIndex:r,conditionToChange:i})})(e),controlCount:P},x.map((e=>{let{key:r,label:n,isGroup:o}=e;return o?i.createElement(u.ListSubheader,{key:r},i.createElement(p.default,{variant:"caption",controlCount:P},n)):i.createElement(u.MenuItem,{key:r,value:r},i.createElement(p.default,{controlCount:P},n))}))),Object.keys(w).map((e=>i.createElement(c.default,{key:e,controlKey:e,andConditionIndex:r,orConditionIndex:n,controlCount:P}))),i.createElement(g.default,{orConditionIndex:n,andConditionIndex:r}))};ConditionsRepeaterRow.propTypes={andConditionIndex:a.number.isRequired,orConditionIndex:a.number.isRequired};r.default=ConditionsRepeaterRow},5213:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=i(n(7976)),u=n(6956),c=i(n(7946));const ConditionsSelectors=e=>{let{orConditionIndex:r}=e;const{selectedConditions:n}=(0,s.default)(),o=n[r];return a.default.createElement(u.Box,{sx:{my:2,gap:1},className:`or-condition-repeater or-condition-${r}`},o.map(((e,n)=>a.default.createElement(c.default,{key:"or-condition-row-"+n,andConditionIndex:n,orConditionIndex:r}))))};ConditionsSelectors.propTypes={orConditionIndex:o.number.isRequired};r.default=ConditionsSelectors},2822:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956),u=i(n(7432)),c=i(n(174));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}r.default=e=>a.createElement(s.Box,{display:"flex",justifyContent:"center",alignItems:"flex-start",sx:{flex:1,overflow:"auto"}},a.createElement(s.Stack,{maxWidth:"md",width:"100%",justifyContent:"center",textAlign:"center",sx:{pt:5,pb:10,px:6}},a.createElement(u.default,{fontSize:"large",sx:{mb:1,mx:"auto"}}),a.createElement(s.Typography,{component:"h6",variant:"h6",color:"text.primary"},o("Set one or more conditions for this element","elementor-pro")),a.createElement(s.Typography,{variant:"body2",color:"text.tertiary",sx:{mb:4}},o("It will only appear on your website when all the conditions are met.","elementor-pro")," ",a.createElement(s.Link,{href:"https://go.elementor.com/app-display-conditions/",target:"_blank",rel:"noreferrer",color:"info.main",underline:"hover",sx:{"&:hover":{color:e=>e.palette.info.main}}},o("Learn more","elementor-pro"))),a.createElement(c.default,e)))},7971:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(4372),u=n(9148),c=n(6956),f=n(3726),p=i(n(1677)),g=i(n(799)),C=i(n(2822)),v=i(n(5305)),_=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Content=e=>{let{getControlValue:r,setControlValue:n,conditionsConfig:o,onClose:i,fetchData:b,setCacheNoticeStatus:x}=e;const E=r(),R={conditionsConfig:o,selectedConditions:E||[],fetchData:b},[w,P]=a.default.useState(!0),[j,T]=(0,a.useReducer)(s.conditionsReducer,R),[I,W]=(0,a.useState)(!1),{selectedConditions:q}=j;(0,a.useEffect)((()=>{I||W(!0)}),[q]),(0,a.useEffect)((()=>{W(!1)}),[]);const handleEmptyFieldsPerConditionSet=(e,r)=>{let n=!1,o=null;return e.forEach(((e,i)=>{const{condition:a}=e,s=getRequiredControlKeys(a);handleInvalidRequiredKeysPerCondition({requiredKeys:s,andCondition:e,orConditionIndex:r,andConditionIndex:i})&&!n&&(o=i,n=!0)})),{hasFoundInvalidConditionInConditionSet:n,invalidAndConditionIndex:o}},handleInvalidRequiredKeysPerCondition=e=>{let{requiredKeys:r,andCondition:n,orConditionIndex:i,andConditionIndex:a}=e;const{condition:s}=n;let u=!1;return r.forEach((e=>{const r=n[e],{type:c,variant:p=null}=o.conditions[s].controls[e];r?.length||(0,f.shouldEmptyValuePassValidation)(n.condition,n.comparator)||(u||(u=!0),T({type:_.ACTION_TYPES.SET_ERRORS,andConditionIndex:a,orConditionIndex:i,errors:{[e]:(0,f.getInvalidInputFeedback)(c,p,r,!0)}}))})),u},handleSave=()=>{const{hasFoundInvalidCondition:e,invalidOrConditionIndex:r,invalidAndConditionIndex:o}=(()=>{let e=!1,r=null,n=null;return q.forEach(((o,i)=>{const{hasFoundInvalidConditionInConditionSet:a,invalidAndConditionIndex:s}=handleEmptyFieldsPerConditionSet(o,i);a&&!e&&(e=!0,n=s,r=i)})),{hasFoundInvalidCondition:e,invalidOrConditionIndex:r,invalidAndConditionIndex:n}})();if(e){const e=`.or-condition-repeater.or-condition-${r} .and-condition-repeater-row.and-condition-${o}`,n=document.querySelector(e);setTimeout((()=>n?.scrollIntoView({behavior:"smooth"})),100)}else n([JSON.stringify(getSanitizedConditions())]),i()},getRequiredControlKeys=e=>{const{controls:r}=o.conditions[e];return Object.keys(r).filter((e=>r[e].required))},getSanitizedConditions=()=>q.map((e=>e.map((e=>{const r={...e};return delete r.errors,r}))));return a.default.createElement(a.default.Fragment,null,a.default.createElement(p.default,{onClose:i}),a.default.createElement(c.Divider,{orientation:"horizontal"}),o.show_cache_notice&&a.default.createElement(v.default,{setCacheNoticeStatus:x}),a.default.createElement(u.ConditionsContext.Provider,{value:{dispatch:T,...j}},a.default.createElement(C.default,{showConditions:w,setShowConditions:P})),a.default.createElement(c.Divider,{orientation:"horizontal"}),a.default.createElement(g.default,{onClickSaveButton:()=>handleSave(),showConditions:w,setShowConditions:P,isButtonDisabled:I}))};Content.propTypes={getControlValue:o.func.isRequired,setControlValue:o.func.isRequired,fetchData:o.func.isRequired,onClose:o.func.isRequired,conditionsConfig:o.object.isRequired,setCacheNoticeStatus:o.func.isRequired};r.default=Content},7459:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=_interopRequireWildcard(n(2688)),s=o(n(7976)),u=o(n(4565)),c=o(n(6373)),f=o(n(6929)),p=o(n(5523)),g=o(n(6936)),C=o(n(6987)),v=n(4934),_=n(3726);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const ControlRenderer=e=>{let{controlKey:r,andConditionIndex:n,orConditionIndex:o,controlCount:a}=e;const{conditionsConfig:b,selectedConditions:x,dispatch:E}=(0,s.default)(),{conditions:R}=b,w=x[o][n],P=w.condition,{controls:j={}}=R[P],T=({}=j[r]),{options:I={}}=T;if("__settings"===r)return null;const extractControlPropsFromGlobals=e=>{const o=getControlValueRelatedProps(e),i=getControlInvalidInputRelatedProps(),s={controlKey:r,control:T,conditionIndex:n,condition:w,conditions:R,options:I,onChangeOption:handleChangeOption,controlCount:a};return(0,_.shouldDisableControl)(r,s.condition.comparator)&&(s.disabled=!0),{...o,...i,...s}},getControlValueRelatedProps=e=>{e=(0,_.getControlValue)(e,v.DEFAULT_CONTROL_VALUES[T.type]);const n=(0,_.getControlValue)(T?.default,Object.keys(I)[0]||e);return{defaultValue:n,value:(0,_.getControlValue)(w[r],n),placeholder:T?.placeholder||"",isMultiple:T?.multiple||!1}},getControlInvalidInputRelatedProps=()=>{const e=(w.errors||{})[r]||{},n=e.shouldShow&&e.message||"";return{errorMessage:n,shouldShowError:Boolean(n)}},handleChangeOption=e=>{const{type:i,variant:a}=j[r],s=(0,_.getInvalidInputFeedback)(i,a,e);E({type:v.ACTION_TYPES.CHANGE_CONTROL_VALUE,orConditionIndex:o,andConditionIndex:n,controlKey:r,value:e}),E({type:v.ACTION_TYPES.SET_ERRORS,andConditionIndex:n,orConditionIndex:o,errors:{[r]:s}})};switch(T.type){case v.CONTROL_TYPES.SELECT:return i.createElement(u.default,extractControlPropsFromGlobals());case v.CONTROL_TYPES.MULTIPLE_SELECT:return i.createElement(c.default,extractControlPropsFromGlobals());case v.CONTROL_TYPES.DATE_TIME:return(e=>{switch(e){case"date":return i.createElement(g.default,extractControlPropsFromGlobals());case"time":return i.createElement(C.default,extractControlPropsFromGlobals())}})(T?.variant);case v.CONTROL_TYPES.QUERY:return i.createElement(f.default,extractControlPropsFromGlobals())}return i.createElement(p.default,extractControlPropsFromGlobals())};ControlRenderer.propTypes={controlKey:a.string.isRequired,andConditionIndex:a.number.isRequired,orConditionIndex:a.number.isRequired,controlCount:a.number.isRequired};r.default=ControlRenderer},6373:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=_interopRequireWildcard(n(1594)),s=a,u=_interopRequireWildcard(n(2688)),c=n(6956),f=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const formatValue=e=>Array.isArray(e)?e:[e],AutocompleteControl=e=>{let{conditions:r,condition:n,controlKey:o,onChangeOption:u,options:p,value:g,shouldShowError:C,errorMessage:v,isMultiple:_,controlCount:b}=e;const[x,E]=(0,a.useState)(formatValue(g)),R=x?.length?"":r[n.condition].label||"";(0,a.useEffect)((()=>{E(formatValue(g))}),[n]);return s.createElement(c.Autocomplete,{multiple:_,id:`select-${o}`,value:x,options:Object.keys(p),getOptionLabel:e=>p[e],sx:{flex:1},ChipProps:{sx:{"&.MuiAutocomplete-tag":{maxWidth:"100px"}}},renderInput:e=>s.createElement(c.TextField,(0,i.default)({error:C,helperText:v},e,{placeholder:R,color:"secondary"})),ListboxProps:{sx:{maxHeight:280}},size:"small",onChange:(e,r)=>{return n=formatValue(r),u(n),void E(n);var n},renderOption:(e,r)=>s.createElement(c.Typography,(0,i.default)({component:"li"},e),s.createElement(f.default,{component:"span",variant:"inherit",noWrap:!0,controlCount:b},p[r])),forcePopupIcon:!Object.keys(p).length<=1})};AutocompleteControl.propTypes={conditions:u.object.isRequired,condition:u.object.isRequired,controlKey:u.string.isRequired,onChangeOption:u.func.isRequired,value:u.array.isRequired,options:u.object.isRequired,errorMessage:u.string.isRequired,shouldShowError:u.bool.isRequired,isMultiple:u.bool.isRequired,optionsStyles:u.object.isRequired,menuStyles:u.object.isRequired,controlCount:u.number.isRequired};r.default=AutocompleteControl},6936:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(5285));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const f="MM-DD-YYYY",formattedValue=e=>(0,c.default)(e,f,!0).isValid()?(0,c.default)(e,f):null,DatePickerControl=e=>{let{condition:r,onChangeOption:n,controlKey:o,value:s,shouldShowError:p,errorMessage:g}=e;const[C,v]=(0,i.useState)(formattedValue(s));(0,i.useEffect)((()=>{v(formattedValue(s))}),[r]);return a.createElement(u.DatePicker,{value:C,sx:{flex:1},id:`select-${o}`,slotProps:{openPickerButton:{size:"small"},textField:{size:"small",color:"secondary",error:p,helperText:g}},onChange:e=>(e=>{(0,c.default)(e,f,!0).isValid()?(n(e.format(f)),v(formattedValue(e))):n("")})(e)})};DatePickerControl.propTypes={condition:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,value:s.string,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired};r.default=DatePickerControl},6929:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=o(n(8304)),s=_interopRequireWildcard(n(2688)),u=n(2470),c=n(9148),f=n(6956),p=n(40),g=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const formatValue=e=>Array.isArray(e)?e:[e],QueryControl=e=>{let{conditions:r,condition:n,control:o,controlKey:s,onChangeOption:C,value:v,shouldShowError:_,errorMessage:b,isMultiple:x,controlCount:E}=e;const{fetchData:R}=(0,i.useContext)(c.ConditionsContext),[w,P]=(0,i.useState)(formatValue(v)),[j,T]=(0,i.useState)([]),[I,W]=(0,i.useState)(!1),q=w?.length?"":r[n.condition].label||"";(0,i.useEffect)((()=>{P(formatValue(v))}),[n]);return i.default.createElement(f.Autocomplete,{multiple:x,id:`select-${s}`,value:w,options:j,getOptionLabel:e=>e?e.text:"",isOptionEqualToValue:(e,r)=>e.id===r.id,filterOptions:e=>e,noOptionsText:(0,u.__)("No results","elementor-pro"),loading:I,loadingText:(0,u.__)("Searching...","elementor-pro"),size:"small",sx:{flex:1},ChipProps:{sx:{"&.MuiAutocomplete-tag":{maxWidth:"100px"}}},renderInput:e=>i.default.createElement(f.TextField,(0,a.default)({},e,{placeholder:q,color:"secondary",error:_,helperText:b,InputProps:{...e.InputProps,endAdornment:i.default.createElement(i.default.Fragment,null,I?i.default.createElement(f.CircularProgress,{color:"inherit",size:20}):null,e.InputProps.endAdornment)}})),ListboxProps:{sx:{maxHeight:280}},onChange:(e,r)=>{return C(n=r),void P(n);var n},onInputChange:(e,r)=>(async(e,r,n)=>{if(""===r)return void T([]);W(!0);const i=(await R(r,o)).filter((e=>(e.text=(0,p.htmlDecodeTextContent)(e.text),!n.some((r=>r?.id===e?.id)))));T(i),W(!1)})(0,r,w),renderOption:(e,r)=>i.default.createElement(f.Typography,(0,a.default)({component:"li"},e),i.default.createElement(g.default,{component:"span",variant:"inherit",noWrap:!0,controlCount:E},r.text))})};QueryControl.propTypes={conditions:s.object.isRequired,condition:s.object.isRequired,onChangeOption:s.func.isRequired,controlKey:s.string.isRequired,control:s.object.isRequired,value:s.array.isRequired,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired,isMultiple:s.bool.isRequired,controlCount:s.number.isRequired};r.default=QueryControl},4565:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(6794)),f=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const SelectControl=e=>{let{condition:r,control:n,controlKey:o,onChangeOption:s,options:p,value:g,controlCount:C}=e;const[v,_]=(0,i.useState)(g);(0,i.useEffect)((()=>{_(g)}),[r]);return a.createElement(c.default,{id:`select-${o}`,value:v,onChange:e=>{return r=e.target.value,s(r),void _(r);var r},disabled:Object.keys(p).length<=1,controlCount:C},Object.entries(p).map((e=>{let[r,o]=e;if(!o)return null;if("group"===o.type)return a.createElement(u.ListSubheader,{key:r},a.createElement(f.default,{controlCount:C},o.label));const i=n?.disabled_options?.includes(r);return a.createElement(u.MenuItem,{key:r,value:r,disabled:i,className:i&&"hidden"===n?.disabled_type?"elementor-hidden":""},a.createElement(f.default,{controlCount:C},o))})))};SelectControl.propTypes={condition:s.object.isRequired,control:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,options:s.object.isRequired,value:s.string.isRequired,controlCount:s.number.isRequired};r.default=SelectControl},5523:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=_interopRequireWildcard(n(1594)),s=a,u=_interopRequireWildcard(n(2688)),c=n(6956),f=n(3726);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const TextFieldControl=e=>{let{condition:r,controlKey:n,control:o,onChangeOption:u,value:p,errorMessage:g,shouldShowError:C,placeholder:v,disabled:_}=e;const[b,x]=(0,a.useState)(p),{step:E=1,min:R=0,variant:w=null}=o,P="number"===w?{type:"number",inputProps:{step:E,min:R}}:{};(0,a.useEffect)((()=>{x(p)}),[r]);return s.createElement(c.TextField,(0,i.default)({},P,{sx:{flex:1},error:C,helperText:g,value:b,id:`text-${n}`,variant:"outlined",onChange:e=>((e,r)=>{let n=null;"number"===r&&(0,f.hasDecimalSeparator)(e)&&(n=Math.floor(parseFloat(e))),u(n??e.trim()),x(n??e)})(e.target.value,w),size:"small",color:"secondary",placeholder:v,disabled:_??!1}))};TextFieldControl.propTypes={condition:u.object.isRequired,controlKey:u.string.isRequired,control:u.object.isRequired,onChangeOption:u.func.isRequired,value:u.oneOfType([u.string,u.number]).isRequired,errorMessage:u.string.isRequired,shouldShowError:u.bool.isRequired,placeholder:u.string.isRequired,disabled:u.bool};r.default=TextFieldControl},6987:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(5285));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const f="HH:mm",p="MM-DD-YYYY "+f,TimePickerControl=e=>{let{condition:r,controlKey:n,onChangeOption:o,value:s,shouldShowError:g,errorMessage:C}=e;const v=(0,i.useRef)((x=s,(0,c.default)(x,f,!0).isValid()?(0,c.default)(x,f):null)),[_,b]=(0,i.useState)(v.current);var x;(0,i.useEffect)((()=>{b(v.current)}),[r]);return a.createElement(u.TimePicker,{sx:{flex:1},id:`select-${n}`,value:_,slotProps:{textField:{size:"small",error:g,helperText:C}},onChange:e=>(e=>{const r=(0,c.default)(e,p,!0).isValid()?e.format(p):"";o(r),v.current=e,b(e)})(e)})};TimePickerControl.propTypes={condition:s.object.isRequired,control:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,value:s.string,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired};r.default=TimePickerControl},6794:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=o(n(8304)),s=n(6956),u=n(3726),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const ConditionSelect=e=>{let{controlCount:r,...n}=e;return i.default.createElement(s.Select,(0,a.default)({},n,{size:"small",sx:{flex:1,textAlign:"start",alignSelf:"flex-start",".MuiSelect-select .MuiTypography-root":{maxWidth:(0,u.getControlValueMaxWidth)(r)}},color:"secondary",MenuProps:{PaperProps:{sx:{maxHeight:280,"& .MuiListSubheader-root":{position:"initial"}}},classes:{paper:"e-conditions-select-menu"}}}))};ConditionSelect.propTypes={controlCount:c.number.isRequired};r.default=ConditionSelect},678:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=o(n(8304)),s=n(6956),u=n(3726),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const ConditionSelectOption=e=>{let{controlCount:r,sx:n={},...o}=e;return i.default.createElement(s.Typography,(0,a.default)({noWrap:!0},o,{variant:o.variant||"inherit",sx:{maxWidth:(0,u.getSelectOptionMaxWidth)(r),...n}}))};ConditionSelectOption.propTypes={sx:c.object,isDropdownItem:c.bool,variant:c.string,controlCount:c.number.isRequired};r.default=ConditionSelectOption},799:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(2688);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Footer=e=>{let{onClickSaveButton:r,isButtonDisabled:n}=e;return a.createElement(s.Stack,{direction:"row",justifyContent:"flex-end",sx:{py:1,px:3}},a.createElement(s.Button,{variant:"contained",className:"save-and-close-button",disabled:!n,onClick:r},o("Save & Close","elementor-pro")))};Footer.propTypes={onClickSaveButton:i.func,isButtonDisabled:i.bool.isRequired};r.default=Footer},1677:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688)),s=n(2470),u=n(6956),c=o(n(4448)),f=n(4048);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Header=e=>{let{onClose:r}=e;return i.default.createElement(u.AppBar,{sx:{fontWeight:"normal"},color:"transparent",position:"relative"},i.default.createElement(u.Toolbar,{variant:"dense"},i.default.createElement(c.default,{sx:{mr:1}}),i.default.createElement(u.Typography,{component:"span",variant:"subtitle2",sx:{fontWeight:"bold",textTransform:"uppercase"}},(0,s.__)("Display Conditions","elementor-pro")),i.default.createElement(u.Stack,{direction:"row",spacing:1,alignItems:"center",sx:{ml:"auto"}},i.default.createElement(u.IconButton,{size:"small","aria-label":(0,s.__)("Close","elementor-pro"),onClick:r,sx:{"&.MuiButtonBase-root":{mr:-1}}},i.default.createElement(f.XIcon,null)))))};Header.propTypes={onClose:a.func.isRequired};r.default=Header},4448:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}r.default=e=>a.createElement(s.SvgIcon,(0,i.default)({viewBox:"0 0 32 32"},e),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.69648 24.8891C0.938383 22.2579 0 19.1645 0 16C0 11.7566 1.68571 7.68687 4.68629 4.68629C7.68687 1.68571 11.7566 0 16 0C19.1645 0 22.2579 0.938383 24.8891 2.69648C27.5203 4.45459 29.5711 6.95344 30.7821 9.87706C31.9931 12.8007 32.3099 16.0177 31.6926 19.1214C31.0752 22.2251 29.5514 25.0761 27.3137 27.3137C25.0761 29.5514 22.2251 31.0752 19.1214 31.6926C16.0177 32.3099 12.8007 31.9931 9.87706 30.7821C6.95344 29.5711 4.45459 27.5203 2.69648 24.8891ZM12.0006 9.33281H9.33437V22.6665H12.0006V9.33281ZM22.6657 9.33281H14.6669V11.9991H22.6657V9.33281ZM22.6657 14.6654H14.6669V17.3316H22.6657V14.6654ZM22.6657 20.0003H14.6669V22.6665H22.6657V20.0003Z"}))},7432:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const u=a.forwardRef(((e,r)=>a.createElement(s.SvgIcon,(0,i.default)({viewBox:"0 0 24 24"},e,{ref:r}),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11 3.75C10.3096 3.75 9.75 4.30964 9.75 5V7C9.75 7.69036 10.3096 8.25 11 8.25H13C13.6904 8.25 14.25 7.69036 14.25 7V5C14.25 4.30964 13.6904 3.75 13 3.75H11ZM12.75 9.75H13C14.5188 9.75 15.75 8.51878 15.75 7V5C15.75 3.48122 14.5188 2.25 13 2.25H11C9.48122 2.25 8.25 3.48122 8.25 5V7C8.25 8.51878 9.48122 9.75 11 9.75H11.25V11.25H8C7.27065 11.25 6.57118 11.5397 6.05546 12.0555C5.53973 12.5712 5.25 13.2707 5.25 14V14.25H5C3.48122 14.25 2.25 15.4812 2.25 17V19C2.25 20.5188 3.48122 21.75 5 21.75H7C8.51878 21.75 9.75 20.5188 9.75 19V17C9.75 15.4812 8.51878 14.25 7 14.25H6.75V14C6.75 13.6685 6.8817 13.3505 7.11612 13.1161C7.35054 12.8817 7.66848 12.75 8 12.75H16C16.3315 12.75 16.6495 12.8817 16.8839 13.1161C17.1183 13.3505 17.25 13.6685 17.25 14V14.25H17C15.4812 14.25 14.25 15.4812 14.25 17V19C14.25 20.5188 15.4812 21.75 17 21.75H19C20.5188 21.75 21.75 20.5188 21.75 19V17C21.75 15.4812 20.5188 14.25 19 14.25H18.75V14C18.75 13.2707 18.4603 12.5712 17.9445 12.0555C17.4288 11.5397 16.7293 11.25 16 11.25H12.75V9.75ZM17 15.75C16.3096 15.75 15.75 16.3096 15.75 17V19C15.75 19.6904 16.3096 20.25 17 20.25H19C19.6904 20.25 20.25 19.6904 20.25 19V17C20.25 16.3096 19.6904 15.75 19 15.75H17ZM5 15.75C4.30964 15.75 3.75 16.3096 3.75 17V19C3.75 19.6904 4.30964 20.25 5 20.25H7C7.69036 20.25 8.25 19.6904 8.25 19V17C8.25 16.3096 7.69036 15.75 7 15.75H5Z"})))),c=(0,s.styled)(u)((e=>{let{theme:r}=e;return{"& path":{fill:r.palette.text.primary}}}));r.default=c},174:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(2688),a=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var s=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),u=n(6956),c=n(4048),f=a(n(5213)),p=a(n(7976)),g=n(3726),C=a(n(5513)),v=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const OrRowGroup=e=>{let{showConditions:r,setShowConditions:n}=e;const{selectedConditions:i,conditionsConfig:a,dispatch:_}=(0,p.default)(),{conditions:b,conditionsByGroup:x}=a,E=i.length?o("Add condition group","elementor-pro"):o("Add Condition","elementor-pro");return s.default.createElement(u.Box,null,r&&i.map(((e,r)=>s.default.createElement(s.Fragment,{key:r},r>0&&s.default.createElement(C.default,null),s.default.createElement(f.default,{orConditionIndex:r})))),s.default.createElement(u.Button,{variant:"contained",className:"add-or-condition-button",color:"secondary",startIcon:s.default.createElement(c.PlusIcon,null),sx:{mt:1,mb:5},onClick:()=>(()=>{const e=(0,g.getDefaultActiveCondition)(x),r={condition:e,...(0,g.getConditionInitialState)(b,e)};_({type:v.ACTION_TYPES.ADD_OR_CONDITION,andCondition:r}),n(!0)})()},E))};OrRowGroup.propTypes={showConditions:i.bool.isRequired,setShowConditions:i.func.isRequired};r.default=OrRowGroup},5513:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=n(6956);r.default=()=>a.default.createElement(s.Divider,{sx:{px:3}},o("OR","elementor-pro"))},248:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=n(6956),s=n(2470),u=n(4048),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),f=n(3726),p=i(n(7976)),g=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const RowControls=e=>{let{orConditionIndex:r,andConditionIndex:n}=e;const{conditionsConfig:o,dispatch:i}=(0,p.default)(),{conditions:C,conditionsByGroup:v}=o;return c.createElement(a.Stack,{direction:"row",alignItems:"center",sx:{left:"100%",gap:.5,ml:-1,mt:"2.5px",position:"absolute"}},c.createElement(a.Button,{color:"secondary",variant:"outlined",sx:{px:1,minWidth:"unset"},className:"add-single-condition-button",onClick:()=>{const e=(0,f.getDefaultActiveCondition)(v),o={condition:e,...(0,f.getConditionInitialState)(C,e)};i({type:g.ACTION_TYPES.ADD_AND_CONDITION,andCondition:o,andConditionIndex:n,orConditionIndex:r})}},(0,s.__)("AND","elementor-pro")),c.createElement(a.IconButton,{color:"secondary","aria-label":(0,s.__)("Delete","elementor-pro"),className:"remove-single-condition-button",onClick:()=>{i({type:g.ACTION_TYPES.REMOVE_AND_CONDITION,andConditionIndex:n,orConditionIndex:r})}},c.createElement(u.XIcon,{fontSize:"small"})))};RowControls.propTypes={andConditionIndex:o.number.isRequired,orConditionIndex:o.number.isRequired};r.default=RowControls},9148:(e,r,n)=>{"use strict";var o=n(1594);Object.defineProperty(r,"__esModule",{value:!0}),r.ConditionsContext=void 0;r.ConditionsContext=o.createContext()},7976:(e,r,n)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var o=n(1594),i=n(9148);r.default=function useConditions(){return(0,o.useContext)(i.ConditionsContext)}},9097:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0,n(6281),n(5724);var a=i(n(19));class Module extends elementorModules.editor.utils.Module{pasteAction="paste";clearAction="clear";getDefaultSettings(){return{selectors:{icon:".eicon-flow.e-control-display-conditions"},controls:{displayConditions:"e_display_conditions",trigger:"e_display_conditions_trigger"}}}onElementorInit(){elementor.hooks.addFilter("controls/base/behaviors",this.registerControlBehavior),elementor.channels.editor.on("section:activated",this.highlightIconIfFilled),elementor.on("navigator:init",this.onNavigatorInit.bind(this));["widget","section","column","container"].forEach((e=>{elementor.hooks.addFilter(`elements/${e}/contextMenuGroups`,this.registerContextMenuGroups.bind(this))}))}onElementorInitComponents(){$e.commands.register("document/elements","paste-display-conditions",(e=>{this.tryContextMenuActions(e,this.pasteAction)})),$e.commands.register("document/elements","clear-display-conditions",(e=>{this.tryContextMenuActions(e,this.clearAction)}))}registerContextMenuGroups(e,r){const n=e.find((e=>"clipboard"===e.name));if(!n)return e;const i=n.actions.findIndex((e=>"pasteStyle"===e.name));return-1!==i&&n.actions.splice(i+1,0,{name:"pasteDisplayConditions",isEnabled:()=>this.isPasteDisplayConditionsEnabled(r),isVisible:()=>this.isPasteDisplayConditionsEnabled(r),title:o("Paste display conditions","elementor-pro"),callback:()=>$e.run("document/elements/paste-display-conditions",elementor.selection.getElements(r.getContainer()))}),n.actions.push({name:"clearDisplayConditions",isEnabled:()=>this.isClearDisplayConditionsEnabled(r),isVisible:()=>this.isClearDisplayConditionsEnabled(r),title:o("Clear display conditions","elementor-pro"),callback:()=>$e.run("document/elements/clear-display-conditions",elementor.selection.getElements(r.getContainer()))}),e}isPasteDisplayConditionsEnabled(e){const r=this.getSelectedElementDisplayCondition(e),n=!!JSON.parse(this.getDisplayConditionsFromClipboard()).length;return!r.length&&!elementor.selection.isMultiple()&&n}isClearDisplayConditionsEnabled(e){return this.getSelectedElementDisplayCondition(e).length&&!elementor.selection.isMultiple()}getSelectedElementDisplayCondition(e){return JSON.parse(e?.model?.getSetting(this.getSettings("controls").displayConditions)||"[]")}getDisplayConditionsFromClipboard(){const e=elementorCommon.storage.get("clipboard"),r=e?.elements||[];return 1!==r.length?"[]":r[0]?.settings?.e_display_conditions||"[]"}tryContextMenuActions(e,r){const n=e?.[0]||null,o=this.pasteAction===r?this.getDisplayConditionsFromClipboard():"";if(n){$e.run("document/elements/settings",{container:n,settings:{e_display_conditions:o}}),n.panel.refresh();try{const e=n.panel.getControlView(this.getSettings("controls").displayConditions),r=this.getEditorControlView(this.getSettings("controls").trigger).$el.find(this.getSettings("selectors").icon);this.highlightIcon(r,e)}catch(e){return!1}}}registerControlBehavior=(e,r)=>{if(this.getSettings("controls").trigger!==r.options.model.get("name"))return e;e||(e={});const n=this._getGroupedConditionKeys(elementor.config.displayConditions||{}),o=this._getFlattenedConditionOptions(n);return e.displayConditions={behaviorClass:a.default,getControlValue:()=>{const e=this.getEditorControlView(this.getSettings("controls").displayConditions);return e?this._getStructuredConditions(JSON.parse(e.getControlValue()||"[]")):[]},setControlValue:e=>{const r=this.getEditorControlView(this.getSettings("controls").displayConditions),n=this.getEditorControlView(this.getSettings("controls").trigger);if(r&&(e=e?.length&&"[]"!==e[0]?e:"",r.setValue(e),r.applySavedValue()),n.$el){const e=n.$el.find(this.getSettings("selectors").icon);this.highlightIcon(e,r)}},fetchData:async(e,r)=>{const n=await this.doAjaxRequest("pro_panel_posts_control_filter_autocomplete",{autocomplete:r.autocomplete,q:e});return n?.results??[]},setCacheNoticeStatus:async()=>{const e=await this.doAjaxRequest("display_conditions_set_cache_notice_status");return e&&(elementor.config.displayConditions.show_cache_notice=!1),e},conditionsConfig:{...elementor.config.displayConditions,conditionsByGroup:n,flattenedConditionOptions:o}},e};highlightIconIfFilled=(e,r)=>{if(!["section_advanced","_section_style","section_layout"].includes(e))return;const n=this.getEditorControlView(this.getSettings("controls").displayConditions);if(!n)return;const o=r.$childViewContainer.find(this.getSettings("selectors").icon);this.highlightIcon(o,n)};onNavigatorInit(){elementor.navigator.indicators.displayConditions={icon:"flow",title:o("Display Conditions","elementor-pro"),settingKeys:["e_display_conditions"],section:"e_display_conditions_trigger"}}highlightIcon=(e,r)=>{if(!e[0])return;const n=r.getControlValue()||"[]";("[]"!==n?this._getStructuredConditions(JSON.parse(n)):[]).length?e[0]?.classList?.add("filled"):e[0]?.classList?.remove("filled")};doAjaxRequest=(e,r)=>{try{return new Promise(((n,o)=>{elementorCommon.ajax.addRequest(e,{data:r,error:()=>o(),success:e=>{n(e)}})}))}catch(e){return!1}};_getStructuredConditions=e=>this._shouldConvertConditionsStructure(e)?[e]:e;_shouldConvertConditionsStructure=e=>e.length&&!Array.isArray(e[0]);_getGroupedConditionKeys=e=>Object.keys(e?.groups||{}).reduce(((r,n)=>{const o=this._getConditionKeyByGroup(e.conditions,n);return o.length&&(r[n]=o),r}),{});_getConditionKeyByGroup=(e,r)=>Object.keys(e).filter((n=>r===e[n].group));_getFlattenedConditionOptions=e=>{const{conditions:r={},groups:n={}}=elementor.config.displayConditions||{};return Object.entries(e).reduce(((e,o)=>{let[i,a]=o;const s=a.map((e=>({key:e,label:r[e].label,isGroup:!1})));return e.push({key:i,label:n[i].label,isGroup:!0},...s),e}),[])}}r.default=Module},4372:(e,r,n)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.conditionsReducer=void 0,n(5724);var o=n(4934);r.conditionsReducer=(e,r)=>{switch(r.type){case o.ACTION_TYPES.CHANGE_CONDITION_TYPE:return{...e,selectedConditions:_changeConditionType({...e,...r})};case o.ACTION_TYPES.CHANGE_CONTROL_VALUE:return{...e,selectedConditions:_changeControlValue({...e,...r})};case o.ACTION_TYPES.ADD_AND_CONDITION:return{...e,selectedConditions:_addAndCondition({...e,...r})};case o.ACTION_TYPES.ADD_OR_CONDITION:return{...e,selectedConditions:[...e.selectedConditions,[r.andCondition]]};case o.ACTION_TYPES.REMOVE_AND_CONDITION:return{...e,selectedConditions:_removeAndCondition({...e,...r})};case o.ACTION_TYPES.REMOVE_OR_CONDITION:return{...e,selectedConditions:e.selectedConditions.filter(((e,n)=>n!==r.orConditionIndex))};case o.ACTION_TYPES.SET_ERRORS:return{...e,selectedConditions:_setErrors({...e,...r})};default:return e}};const _changeConditionType=e=>{let{selectedConditions:r,conditionToChange:n,orConditionIndex:o,andConditionIndex:i}=e;const a=r[o].map(((e,r)=>r===i?n:{...e}));return r.map(((e,r)=>r===o?a:[...e]))},_changeControlValue=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,controlKey:i,value:a}=e;const s=[...r[n]],u={...{...s[o]},[i]:a},c=s.map(((e,r)=>r===o?u:{...e}));return r.map(((e,r)=>r===n?c:[...e]))},_addAndCondition=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,andCondition:i}=e;const a=r[n],s=a.reduce(((e,r,n)=>(e.push({...r}),(n===o||a.length===o&&a.length-1===n)&&e.push(i),e)),[]);return r.map(((e,r)=>r===n?s:[...e]))},_removeAndCondition=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o}=e;const i=r[n].reduce(((e,r,n)=>(n!==o&&e.push({...r}),e)),[]);return r.reduce(((e,r,o)=>(o===n&&i.length&&e.push(i),o!==n&&e.push([...r]),e)),[])},_setErrors=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,errors:i}=e;const a=[...r[n]],s={...a[o]};return s.errors={...s.errors,...i},a[o]=s,r.map(((e,r)=>r===n?[...a]:[...e]))}},4934:(e,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.DISABLED_CONTROL_CONFIG=r.DEFAULT_CONTROL_VALUES=r.CONTROL_TYPES=r.ACTION_TYPES=void 0;r.CONTROL_TYPES={MULTIPLE_SELECT:"select2",SELECT:"select",QUERY:"query",DATE_TIME:"date_time",TEXT_FIELD:"text"},r.DEFAULT_CONTROL_VALUES={select2:[],query:[],select:"",text:"",date_time:null},r.ACTION_TYPES={CHANGE_CONTROL_VALUE:"CHANGE_CONTROL_VALUE",SET_ERRORS:"SET_ERRORS",ADD_OR_CONDITION:"ADD_OR_CONDITION",CHANGE_CONDITION_TYPE:"CHANGE_CONDITION_TYPE",ADD_AND_CONDITION:"ADD_AND_CONDITION",REMOVE_AND_CONDITION:"REMOVE_AND_CONDITION",REMOVE_OR_CONDITION:"REMOVE_OR_CONDITION"},r.DISABLED_CONTROL_CONFIG={CONDITION_NAME:"dynamic_tags",CONTROL_NAME:"dynamic_tag_value",COMPARATORS:["is_empty","is_not_empty"]}},3726:(e,r,n)=>{"use strict";var o=n(2470).__;Object.defineProperty(r,"__esModule",{value:!0}),r.getControlDefaults=r.getConditionInitialState=void 0,r.getControlValue=function getControlValue(e,r){return void 0!==e?e:r},r.getControlValueMaxWidth=function getControlValueMaxWidth(e){return 3===e?190:135},r.getDefaultActiveCondition=function getDefaultActiveCondition(e){return Object.values(e)[0][0]},r.getInvalidInputFeedback=getInvalidInputFeedback,r.getSelectOptionMaxWidth=function getSelectOptionMaxWidth(e){return 3===e?200:150},r.hasDecimalSeparator=function hasDecimalSeparator(e){if(isNaN(parseFloat(e)))return!1;if(-1!==e.toString().indexOf("."))return!0;if(-1!==e.toString().indexOf(","))return!0},r.shouldCastToArray=shouldCastToArray,r.shouldDisableControl=function shouldDisableControl(e,r){return i.DISABLED_CONTROL_CONFIG.CONTROL_NAME===e&&i.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(r)},r.shouldEmptyValuePassValidation=function shouldEmptyValuePassValidation(e,r){return i.DISABLED_CONTROL_CONFIG.CONDITION_NAME===e&&i.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(r)},n(6281);var i=n(4934);function shouldCastToArray(e){return i.CONTROL_TYPES.MULTIPLE_SELECT===e||i.CONTROL_TYPES.QUERY===e}function getInvalidInputFeedback(e,r,n){let o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];return n?.length?{}:{message:_getErrorMessage(e,r),shouldShow:o}}const getControlDefaults=(e,r)=>{const{type:n,variant:o=null,options:a}=r,s=r?.default||(a&&i.CONTROL_TYPES.MULTIPLE_SELECT!==n?Object.keys(a)[0]:i.DEFAULT_CONTROL_VALUES[n]),u=shouldCastToArray(n)&&!Array.isArray(s)?[s]:s;return{defaultValue:u,error:getInvalidInputFeedback(n,o,u)}};r.getControlDefaults=getControlDefaults;function _getErrorMessage(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return shouldCastToArray(e)?o("Select an option","elementor-pro"):i.CONTROL_TYPES.DATE_TIME===e?o("time"===r?"Select a time":"Select a date","elementor-pro"):o("Enter a value","elementor-pro")}r.getConditionInitialState=(e,r)=>{const{controls:n={}}=e?.[r]||{};return Object.keys(n).reduce(((e,r)=>{if("__settings"===r)return e;const{defaultValue:o,error:i}=getControlDefaults(0,n[r]);return e[r]=o,e.errors[r]=i,e}),{errors:{}})}},5285:function(e){e.exports=function(){"use strict";var e=1e3,r=6e4,n=36e5,o="millisecond",i="second",a="minute",s="hour",u="day",c="week",f="month",p="quarter",g="year",C="date",v="Invalid Date",_=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,b=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,x={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(e){var r=["th","st","nd","rd"],n=e%100;return"["+e+(r[(n-20)%10]||r[n]||r[0])+"]"}},m=function(e,r,n){var o=String(e);return!o||o.length>=r?e:""+Array(r+1-o.length).join(n)+e},E={s:m,z:function(e){var r=-e.utcOffset(),n=Math.abs(r),o=Math.floor(n/60),i=n%60;return(r<=0?"+":"-")+m(o,2,"0")+":"+m(i,2,"0")},m:function t(e,r){if(e.date()1)return t(a[0])}else{var s=e.name;w[s]=e,o=s}return!n&&o&&(R=o),o||!n&&R},O=function(e,r){if(S(e))return e.clone();var n="object"==typeof r?r:{};return n.date=e,n.args=arguments,new I(n)},T=E;T.l=j,T.i=S,T.w=function(e,r){return O(e,{locale:r.$L,utc:r.$u,x:r.$x,$offset:r.$offset})};var I=function(){function M(e){this.$L=j(e.locale,null,!0),this.parse(e),this.$x=this.$x||e.x||{},this[P]=!0}var x=M.prototype;return x.parse=function(e){this.$d=function(e){var r=e.date,n=e.utc;if(null===r)return new Date(NaN);if(T.u(r))return new Date;if(r instanceof Date)return new Date(r);if("string"==typeof r&&!/Z$/i.test(r)){var o=r.match(_);if(o){var i=o[2]-1||0,a=(o[7]||"0").substring(0,3);return n?new Date(Date.UTC(o[1],i,o[3]||1,o[4]||0,o[5]||0,o[6]||0,a)):new Date(o[1],i,o[3]||1,o[4]||0,o[5]||0,o[6]||0,a)}}return new Date(r)}(e),this.init()},x.init=function(){var e=this.$d;this.$y=e.getFullYear(),this.$M=e.getMonth(),this.$D=e.getDate(),this.$W=e.getDay(),this.$H=e.getHours(),this.$m=e.getMinutes(),this.$s=e.getSeconds(),this.$ms=e.getMilliseconds()},x.$utils=function(){return T},x.isValid=function(){return!(this.$d.toString()===v)},x.isSame=function(e,r){var n=O(e);return this.startOf(r)<=n&&n<=this.endOf(r)},x.isAfter=function(e,r){return O(e){"use strict";var o=n(6441);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,e.exports=function(){function shim(e,r,n,i,a,s){if(s!==o){var u=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function getShim(){return shim}shim.isRequired=shim;var e={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return e.PropTypes=e,e}},2688:(e,r,n)=>{e.exports=n(362)()},6441:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},1594:e=>{"use strict";e.exports=React},4048:e=>{"use strict";e.exports=elementorV2.icons},6956:e=>{"use strict";e.exports=elementorV2.ui},2470:e=>{"use strict";e.exports=wp.i18n},8304:e=>{function _extends(){return e.exports=_extends=Object.assign?Object.assign.bind():function(e){for(var r=1;r{e.exports=function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports},8120:(e,r,n)=>{"use strict";var o=n(1483),i=n(8761),a=TypeError;e.exports=function(e){if(o(e))return e;throw new a(i(e)+" is not a function")}},7095:(e,r,n)=>{"use strict";var o=n(1),i=n(5290),a=n(5835).f,s=o("unscopables"),u=Array.prototype;void 0===u[s]&&a(u,s,{configurable:!0,value:i(null)}),e.exports=function(e){u[s][e]=!0}},2293:(e,r,n)=>{"use strict";var o=n(1704),i=String,a=TypeError;e.exports=function(e){if(o(e))return e;throw new a(i(e)+" is not an object")}},6651:(e,r,n)=>{"use strict";var o=n(5599),i=n(3392),a=n(6960),createMethod=function(e){return function(r,n,s){var u=o(r),c=a(u);if(0===c)return!e&&-1;var f,p=i(s,c);if(e&&n!=n){for(;c>p;)if((f=u[p++])!=f)return!0}else for(;c>p;p++)if((e||p in u)&&u[p]===n)return e||p||0;return!e&&-1}};e.exports={includes:createMethod(!0),indexOf:createMethod(!1)}},9273:(e,r,n)=>{"use strict";var o=n(382),i=n(4914),a=TypeError,s=Object.getOwnPropertyDescriptor,u=o&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=u?function(e,r){if(i(e)&&!s(e,"length").writable)throw new a("Cannot set read only .length");return e.length=r}:function(e,r){return e.length=r}},1278:(e,r,n)=>{"use strict";var o=n(4762),i=o({}.toString),a=o("".slice);e.exports=function(e){return a(i(e),8,-1)}},6726:(e,r,n)=>{"use strict";var o=n(5755),i=n(9497),a=n(4961),s=n(5835);e.exports=function(e,r,n){for(var u=i(r),c=s.f,f=a.f,p=0;p{"use strict";var o=n(382),i=n(5835),a=n(7738);e.exports=o?function(e,r,n){return i.f(e,r,a(1,n))}:function(e,r,n){return e[r]=n,e}},7738:e=>{"use strict";e.exports=function(e,r){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:r}}},7914:(e,r,n)=>{"use strict";var o=n(1483),i=n(5835),a=n(169),s=n(2095);e.exports=function(e,r,n,u){u||(u={});var c=u.enumerable,f=void 0!==u.name?u.name:r;if(o(n)&&a(n,f,u),u.global)c?e[r]=n:s(r,n);else{try{u.unsafe?e[r]&&(c=!0):delete e[r]}catch(e){}c?e[r]=n:i.f(e,r,{value:n,enumerable:!1,configurable:!u.nonConfigurable,writable:!u.nonWritable})}return e}},2095:(e,r,n)=>{"use strict";var o=n(5578),i=Object.defineProperty;e.exports=function(e,r){try{i(o,e,{value:r,configurable:!0,writable:!0})}catch(n){o[e]=r}return r}},382:(e,r,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},3145:(e,r,n)=>{"use strict";var o=n(5578),i=n(1704),a=o.document,s=i(a)&&i(a.createElement);e.exports=function(e){return s?a.createElement(e):{}}},1091:e=>{"use strict";var r=TypeError;e.exports=function(e){if(e>9007199254740991)throw r("Maximum allowed index exceeded");return e}},4741:e=>{"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},9461:(e,r,n)=>{"use strict";var o=n(5578).navigator,i=o&&o.userAgent;e.exports=i?String(i):""},6477:(e,r,n)=>{"use strict";var o,i,a=n(5578),s=n(9461),u=a.process,c=a.Deno,f=u&&u.versions||c&&c.version,p=f&&f.v8;p&&(i=(o=p.split("."))[0]>0&&o[0]<4?1:+(o[0]+o[1])),!i&&s&&(!(o=s.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=s.match(/Chrome\/(\d+)/))&&(i=+o[1]),e.exports=i},8612:(e,r,n)=>{"use strict";var o=n(5578),i=n(4961).f,a=n(9037),s=n(7914),u=n(2095),c=n(6726),f=n(8730);e.exports=function(e,r){var n,p,g,C,v,_=e.target,b=e.global,x=e.stat;if(n=b?o:x?o[_]||u(_,{}):o[_]&&o[_].prototype)for(p in r){if(C=r[p],g=e.dontCallGetSet?(v=i(n,p))&&v.value:n[p],!f(b?p:_+(x?".":"#")+p,e.forced)&&void 0!==g){if(typeof C==typeof g)continue;c(C,g)}(e.sham||g&&g.sham)&&a(C,"sham",!0),s(n,p,C,e)}}},8473:e=>{"use strict";e.exports=function(e){try{return!!e()}catch(e){return!0}}},274:(e,r,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},1807:(e,r,n)=>{"use strict";var o=n(274),i=Function.prototype.call;e.exports=o?i.bind(i):function(){return i.apply(i,arguments)}},2048:(e,r,n)=>{"use strict";var o=n(382),i=n(5755),a=Function.prototype,s=o&&Object.getOwnPropertyDescriptor,u=i(a,"name"),c=u&&"something"===function something(){}.name,f=u&&(!o||o&&s(a,"name").configurable);e.exports={EXISTS:u,PROPER:c,CONFIGURABLE:f}},4762:(e,r,n)=>{"use strict";var o=n(274),i=Function.prototype,a=i.call,s=o&&i.bind.bind(a,a);e.exports=o?s:function(e){return function(){return a.apply(e,arguments)}}},1409:(e,r,n)=>{"use strict";var o=n(5578),i=n(1483);e.exports=function(e,r){return arguments.length<2?(n=o[e],i(n)?n:void 0):o[e]&&o[e][r];var n}},2564:(e,r,n)=>{"use strict";var o=n(8120),i=n(5983);e.exports=function(e,r){var n=e[r];return i(n)?void 0:o(n)}},5578:function(e,r,n){"use strict";var check=function(e){return e&&e.Math===Math&&e};e.exports=check("object"==typeof globalThis&&globalThis)||check("object"==typeof window&&window)||check("object"==typeof self&&self)||check("object"==typeof n.g&&n.g)||check("object"==typeof this&&this)||function(){return this}()||Function("return this")()},5755:(e,r,n)=>{"use strict";var o=n(4762),i=n(2347),a=o({}.hasOwnProperty);e.exports=Object.hasOwn||function hasOwn(e,r){return a(i(e),r)}},1507:e=>{"use strict";e.exports={}},2811:(e,r,n)=>{"use strict";var o=n(1409);e.exports=o("document","documentElement")},1799:(e,r,n)=>{"use strict";var o=n(382),i=n(8473),a=n(3145);e.exports=!o&&!i((function(){return 7!==Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},2121:(e,r,n)=>{"use strict";var o=n(4762),i=n(8473),a=n(1278),s=Object,u=o("".split);e.exports=i((function(){return!s("z").propertyIsEnumerable(0)}))?function(e){return"String"===a(e)?u(e,""):s(e)}:s},7268:(e,r,n)=>{"use strict";var o=n(4762),i=n(1483),a=n(1831),s=o(Function.toString);i(a.inspectSource)||(a.inspectSource=function(e){return s(e)}),e.exports=a.inspectSource},4483:(e,r,n)=>{"use strict";var o,i,a,s=n(4644),u=n(5578),c=n(1704),f=n(9037),p=n(5755),g=n(1831),C=n(5409),v=n(1507),_="Object already initialized",b=u.TypeError,x=u.WeakMap;if(s||g.state){var E=g.state||(g.state=new x);E.get=E.get,E.has=E.has,E.set=E.set,o=function(e,r){if(E.has(e))throw new b(_);return r.facade=e,E.set(e,r),r},i=function(e){return E.get(e)||{}},a=function(e){return E.has(e)}}else{var R=C("state");v[R]=!0,o=function(e,r){if(p(e,R))throw new b(_);return r.facade=e,f(e,R,r),r},i=function(e){return p(e,R)?e[R]:{}},a=function(e){return p(e,R)}}e.exports={set:o,get:i,has:a,enforce:function(e){return a(e)?i(e):o(e,{})},getterFor:function(e){return function(r){var n;if(!c(r)||(n=i(r)).type!==e)throw new b("Incompatible receiver, "+e+" required");return n}}}},4914:(e,r,n)=>{"use strict";var o=n(1278);e.exports=Array.isArray||function isArray(e){return"Array"===o(e)}},1483:e=>{"use strict";var r="object"==typeof document&&document.all;e.exports=void 0===r&&void 0!==r?function(e){return"function"==typeof e||e===r}:function(e){return"function"==typeof e}},8730:(e,r,n)=>{"use strict";var o=n(8473),i=n(1483),a=/#|\.prototype\./,isForced=function(e,r){var n=u[s(e)];return n===f||n!==c&&(i(r)?o(r):!!r)},s=isForced.normalize=function(e){return String(e).replace(a,".").toLowerCase()},u=isForced.data={},c=isForced.NATIVE="N",f=isForced.POLYFILL="P";e.exports=isForced},5983:e=>{"use strict";e.exports=function(e){return null==e}},1704:(e,r,n)=>{"use strict";var o=n(1483);e.exports=function(e){return"object"==typeof e?null!==e:o(e)}},9557:e=>{"use strict";e.exports=!1},1423:(e,r,n)=>{"use strict";var o=n(1409),i=n(1483),a=n(4815),s=n(5022),u=Object;e.exports=s?function(e){return"symbol"==typeof e}:function(e){var r=o("Symbol");return i(r)&&a(r.prototype,u(e))}},6960:(e,r,n)=>{"use strict";var o=n(8324);e.exports=function(e){return o(e.length)}},169:(e,r,n)=>{"use strict";var o=n(4762),i=n(8473),a=n(1483),s=n(5755),u=n(382),c=n(2048).CONFIGURABLE,f=n(7268),p=n(4483),g=p.enforce,C=p.get,v=String,_=Object.defineProperty,b=o("".slice),x=o("".replace),E=o([].join),R=u&&!i((function(){return 8!==_((function(){}),"length",{value:8}).length})),w=String(String).split("String"),P=e.exports=function(e,r,n){"Symbol("===b(v(r),0,7)&&(r="["+x(v(r),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),n&&n.getter&&(r="get "+r),n&&n.setter&&(r="set "+r),(!s(e,"name")||c&&e.name!==r)&&(u?_(e,"name",{value:r,configurable:!0}):e.name=r),R&&n&&s(n,"arity")&&e.length!==n.arity&&_(e,"length",{value:n.arity});try{n&&s(n,"constructor")&&n.constructor?u&&_(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var o=g(e);return s(o,"source")||(o.source=E(w,"string"==typeof r?r:"")),e};Function.prototype.toString=P((function toString(){return a(this)&&C(this).source||f(this)}),"toString")},1703:e=>{"use strict";var r=Math.ceil,n=Math.floor;e.exports=Math.trunc||function trunc(e){var o=+e;return(o>0?n:r)(o)}},5290:(e,r,n)=>{"use strict";var o,i=n(2293),a=n(5799),s=n(4741),u=n(1507),c=n(2811),f=n(3145),p=n(5409),g="prototype",C="script",v=p("IE_PROTO"),EmptyConstructor=function(){},scriptTag=function(e){return"<"+C+">"+e+""},NullProtoObjectViaActiveX=function(e){e.write(scriptTag("")),e.close();var r=e.parentWindow.Object;return e=null,r},NullProtoObject=function(){try{o=new ActiveXObject("htmlfile")}catch(e){}var e,r,n;NullProtoObject="undefined"!=typeof document?document.domain&&o?NullProtoObjectViaActiveX(o):(r=f("iframe"),n="java"+C+":",r.style.display="none",c.appendChild(r),r.src=String(n),(e=r.contentWindow.document).open(),e.write(scriptTag("document.F=Object")),e.close(),e.F):NullProtoObjectViaActiveX(o);for(var i=s.length;i--;)delete NullProtoObject[g][s[i]];return NullProtoObject()};u[v]=!0,e.exports=Object.create||function create(e,r){var n;return null!==e?(EmptyConstructor[g]=i(e),n=new EmptyConstructor,EmptyConstructor[g]=null,n[v]=e):n=NullProtoObject(),void 0===r?n:a.f(n,r)}},5799:(e,r,n)=>{"use strict";var o=n(382),i=n(3896),a=n(5835),s=n(2293),u=n(5599),c=n(3658);r.f=o&&!i?Object.defineProperties:function defineProperties(e,r){s(e);for(var n,o=u(r),i=c(r),f=i.length,p=0;f>p;)a.f(e,n=i[p++],o[n]);return e}},5835:(e,r,n)=>{"use strict";var o=n(382),i=n(1799),a=n(3896),s=n(2293),u=n(3815),c=TypeError,f=Object.defineProperty,p=Object.getOwnPropertyDescriptor,g="enumerable",C="configurable",v="writable";r.f=o?a?function defineProperty(e,r,n){if(s(e),r=u(r),s(n),"function"==typeof e&&"prototype"===r&&"value"in n&&v in n&&!n[v]){var o=p(e,r);o&&o[v]&&(e[r]=n.value,n={configurable:C in n?n[C]:o[C],enumerable:g in n?n[g]:o[g],writable:!1})}return f(e,r,n)}:f:function defineProperty(e,r,n){if(s(e),r=u(r),s(n),i)try{return f(e,r,n)}catch(e){}if("get"in n||"set"in n)throw new c("Accessors not supported");return"value"in n&&(e[r]=n.value),e}},4961:(e,r,n)=>{"use strict";var o=n(382),i=n(1807),a=n(7611),s=n(7738),u=n(5599),c=n(3815),f=n(5755),p=n(1799),g=Object.getOwnPropertyDescriptor;r.f=o?g:function getOwnPropertyDescriptor(e,r){if(e=u(e),r=c(r),p)try{return g(e,r)}catch(e){}if(f(e,r))return s(!i(a.f,e,r),e[r])}},2278:(e,r,n)=>{"use strict";var o=n(6742),i=n(4741).concat("length","prototype");r.f=Object.getOwnPropertyNames||function getOwnPropertyNames(e){return o(e,i)}},4347:(e,r)=>{"use strict";r.f=Object.getOwnPropertySymbols},4815:(e,r,n)=>{"use strict";var o=n(4762);e.exports=o({}.isPrototypeOf)},6742:(e,r,n)=>{"use strict";var o=n(4762),i=n(5755),a=n(5599),s=n(6651).indexOf,u=n(1507),c=o([].push);e.exports=function(e,r){var n,o=a(e),f=0,p=[];for(n in o)!i(u,n)&&i(o,n)&&c(p,n);for(;r.length>f;)i(o,n=r[f++])&&(~s(p,n)||c(p,n));return p}},3658:(e,r,n)=>{"use strict";var o=n(6742),i=n(4741);e.exports=Object.keys||function keys(e){return o(e,i)}},7611:(e,r)=>{"use strict";var n={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!n.call({1:2},1);r.f=i?function propertyIsEnumerable(e){var r=o(this,e);return!!r&&r.enumerable}:n},348:(e,r,n)=>{"use strict";var o=n(1807),i=n(1483),a=n(1704),s=TypeError;e.exports=function(e,r){var n,u;if("string"===r&&i(n=e.toString)&&!a(u=o(n,e)))return u;if(i(n=e.valueOf)&&!a(u=o(n,e)))return u;if("string"!==r&&i(n=e.toString)&&!a(u=o(n,e)))return u;throw new s("Can't convert object to primitive value")}},9497:(e,r,n)=>{"use strict";var o=n(1409),i=n(4762),a=n(2278),s=n(4347),u=n(2293),c=i([].concat);e.exports=o("Reflect","ownKeys")||function ownKeys(e){var r=a.f(u(e)),n=s.f;return n?c(r,n(e)):r}},3312:(e,r,n)=>{"use strict";var o=n(5983),i=TypeError;e.exports=function(e){if(o(e))throw new i("Can't call method on "+e);return e}},5409:(e,r,n)=>{"use strict";var o=n(7255),i=n(1866),a=o("keys");e.exports=function(e){return a[e]||(a[e]=i(e))}},1831:(e,r,n)=>{"use strict";var o=n(9557),i=n(5578),a=n(2095),s="__core-js_shared__",u=e.exports=i[s]||a(s,{});(u.versions||(u.versions=[])).push({version:"3.38.1",mode:o?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE",source:"https://github.com/zloirock/core-js"})},7255:(e,r,n)=>{"use strict";var o=n(1831);e.exports=function(e,r){return o[e]||(o[e]=r||{})}},6029:(e,r,n)=>{"use strict";var o=n(6477),i=n(8473),a=n(5578).String;e.exports=!!Object.getOwnPropertySymbols&&!i((function(){var e=Symbol("symbol detection");return!a(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&o&&o<41}))},3392:(e,r,n)=>{"use strict";var o=n(3005),i=Math.max,a=Math.min;e.exports=function(e,r){var n=o(e);return n<0?i(n+r,0):a(n,r)}},5599:(e,r,n)=>{"use strict";var o=n(2121),i=n(3312);e.exports=function(e){return o(i(e))}},3005:(e,r,n)=>{"use strict";var o=n(1703);e.exports=function(e){var r=+e;return r!=r||0===r?0:o(r)}},8324:(e,r,n)=>{"use strict";var o=n(3005),i=Math.min;e.exports=function(e){var r=o(e);return r>0?i(r,9007199254740991):0}},2347:(e,r,n)=>{"use strict";var o=n(3312),i=Object;e.exports=function(e){return i(o(e))}},2355:(e,r,n)=>{"use strict";var o=n(1807),i=n(1704),a=n(1423),s=n(2564),u=n(348),c=n(1),f=TypeError,p=c("toPrimitive");e.exports=function(e,r){if(!i(e)||a(e))return e;var n,c=s(e,p);if(c){if(void 0===r&&(r="default"),n=o(c,e,r),!i(n)||a(n))return n;throw new f("Can't convert object to primitive value")}return void 0===r&&(r="number"),u(e,r)}},3815:(e,r,n)=>{"use strict";var o=n(2355),i=n(1423);e.exports=function(e){var r=o(e,"string");return i(r)?r:r+""}},8761:e=>{"use strict";var r=String;e.exports=function(e){try{return r(e)}catch(e){return"Object"}}},1866:(e,r,n)=>{"use strict";var o=n(4762),i=0,a=Math.random(),s=o(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+s(++i+a,36)}},5022:(e,r,n)=>{"use strict";var o=n(6029);e.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},3896:(e,r,n)=>{"use strict";var o=n(382),i=n(8473);e.exports=o&&i((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},4644:(e,r,n)=>{"use strict";var o=n(5578),i=n(1483),a=o.WeakMap;e.exports=i(a)&&/native code/.test(String(a))},1:(e,r,n)=>{"use strict";var o=n(5578),i=n(7255),a=n(5755),s=n(1866),u=n(6029),c=n(5022),f=o.Symbol,p=i("wks"),g=c?f.for||f:f&&f.withoutSetter||s;e.exports=function(e){return a(p,e)||(p[e]=u&&a(f,e)?f[e]:g("Symbol."+e)),p[e]}},6281:(e,r,n)=>{"use strict";var o=n(8612),i=n(6651).includes,a=n(8473),s=n(7095);o({target:"Array",proto:!0,forced:a((function(){return!Array(1).includes()}))},{includes:function includes(e){return i(this,e,arguments.length>1?arguments[1]:void 0)}}),s("includes")},5724:(e,r,n)=>{"use strict";var o=n(8612),i=n(2347),a=n(6960),s=n(9273),u=n(1091);o({target:"Array",proto:!0,arity:1,forced:n(8473)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function push(e){var r=i(this),n=a(r),o=arguments.length;u(n+o);for(var c=0;c{"use strict";new(__webpack_require__(6784)(__webpack_require__(9097)).default)})()})(); \ No newline at end of file diff --git a/assets/js/e8eba20060a4b0fa29dc.bundle.js b/assets/js/e8eba20060a4b0fa29dc.bundle.js new file mode 100644 index 00000000..71390a5a --- /dev/null +++ b/assets/js/e8eba20060a4b0fa29dc.bundle.js @@ -0,0 +1,347 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +"use strict"; +(self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["modules_floating-buttons_assets_js_frontend_classes_floatin-bar-dom_js-modules_floating-butto-2c1e90"],{ + +/***/ "../modules/floating-buttons/assets/js/frontend/classes/floatin-bar-dom.js": +/*!*********************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/frontend/classes/floatin-bar-dom.js ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class FloatingBarDomHelper { + constructor($element) { + this.$element = $element; + } + maybeMoveToTop() { + const el = this.$element[0]; + const widget = el.querySelector('.e-floating-bars'); + if (elementorFrontend.isEditMode()) { + widget.classList.add('is-sticky'); + return; + } + if (el.dataset.widget_type.startsWith('floating-bars') && widget.classList.contains('has-vertical-position-top') && !widget.classList.contains('is-sticky')) { + const wpAdminBar = document.getElementById('wpadminbar'); + const elementToInsert = el.closest('.elementor'); + if (wpAdminBar) { + wpAdminBar.after(elementToInsert); + } else { + document.body.prepend(elementToInsert); + } + } + } +} +exports["default"] = FloatingBarDomHelper; + +/***/ }), + +/***/ "../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js": +/*!****************************************************************************************!*\ + !*** ../modules/floating-buttons/assets/js/shared/frontend/handlers/click-tracking.js ***! + \****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _base = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/handlers/base */ "../../elementor/assets/dev/js/frontend/handlers/base.js")); +class ClickTrackingHandler extends _base.default { + clicks = []; + getDefaultSettings() { + return { + selectors: { + contentWrapper: '.e-contact-buttons__content-wrapper', + contentWrapperFloatingBars: '.e-floating-bars', + floatingBarCouponButton: '.e-floating-bars__coupon-button', + floatingBarsHeadline: '.e-floating-bars__headline', + contactButtonsVar4: '.e-contact-buttons__contact-icon-link', + contactButtonsVar5: '.e-contact-buttons__chat-button', + contactButtonsVar6: '.e-contact-buttons-var-6', + contactButtonsVar8: '.e-contact-buttons-var-8', + elementorWrapper: '[data-elementor-type="floating-buttons"]', + contactButtonCore: '.e-contact-buttons__send-button' + } + }; + } + getDefaultElements() { + const selectors = this.getSettings('selectors'); + return { + contentWrapper: this.$element[0].querySelector(selectors.contentWrapper), + contentWrapperFloatingBars: this.$element[0].querySelector(selectors.contentWrapperFloatingBars), + contactButtonsVar5: this.$element[0].querySelector(selectors.contactButtonsVar5), + contactButtonsVar6: this.$element[0].querySelector(selectors.contactButtonsVar6) + }; + } + bindEvents() { + if (this.elements.contentWrapper) { + this.elements.contentWrapper.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar5) { + this.elements.contactButtonsVar5.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contactButtonsVar6) { + this.elements.contactButtonsVar6.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + if (this.elements.contentWrapperFloatingBars) { + this.elements.contentWrapperFloatingBars.addEventListener('click', this.onChatButtonTrackClick.bind(this)); + } + window.addEventListener('beforeunload', () => { + if (this.clicks.length > 0) { + this.sendClicks(); + } + }); + } + onChatButtonTrackClick(event) { + const targetElement = event.target || event.srcElement; + const selectors = this.getSettings('selectors'); + const buttonSelectors = [selectors.contactButtonsVar4, selectors.contactButtonsVar6, selectors.floatingBarCouponButton, selectors.floatingBarsHeadline, selectors.contactButtonCore]; + for (const selector of buttonSelectors) { + if (targetElement.matches(selector) || targetElement.closest(selector)) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + if ((targetElement.matches(selectors.contactButtonsVar5) || targetElement.closest(selectors.contactButtonsVar5)) && targetElement.closest('.e-contact-buttons-var-5')) { + this.getDocumentIdAndTrack(targetElement, selectors); + } + } + getDocumentIdAndTrack(targetElement, selectors) { + const documentId = targetElement.closest(selectors.elementorWrapper).dataset.elementorId; + this.trackClick(documentId); + } + trackClick(documentId) { + if (!documentId) { + return; + } + this.clicks.push(documentId); + if (this.clicks.length >= 10) { + this.sendClicks(); + } + } + sendClicks() { + const formData = new FormData(); + formData.append('action', 'elementor_send_clicks'); + formData.append('_nonce', elementorFrontendConfig?.nonces?.floatingButtonsClickTracking); + this.clicks.forEach(documentId => formData.append('clicks[]', documentId)); + fetch(elementorFrontendConfig?.urls?.ajaxurl, { + method: 'POST', + body: formData + }).then(() => { + this.clicks = []; + }); + } +} +exports["default"] = ClickTrackingHandler; + +/***/ }), + +/***/ "../../elementor/assets/dev/js/frontend/handlers/base.js": +/*!***************************************************************!*\ + !*** ../../elementor/assets/dev/js/frontend/handlers/base.js ***! + \***************************************************************/ +/***/ ((module) => { + + + +module.exports = elementorModules.ViewModule.extend({ + $element: null, + editorListeners: null, + onElementChange: null, + onEditSettingsChange: null, + onPageSettingsChange: null, + isEdit: null, + __construct(settings) { + if (!this.isActive(settings)) { + return; + } + this.$element = settings.$element; + this.isEdit = this.$element.hasClass('elementor-element-edit-mode'); + if (this.isEdit) { + this.addEditorListeners(); + } + }, + isActive() { + return true; + }, + isElementInTheCurrentDocument() { + if (!elementorFrontend.isEditMode()) { + return false; + } + return elementor.documents.currentDocument.id.toString() === this.$element[0].closest('.elementor').dataset.elementorId; + }, + findElement(selector) { + var $mainElement = this.$element; + return $mainElement.find(selector).filter(function () { + // Start `closest` from parent since self can be `.elementor-element`. + return jQuery(this).parent().closest('.elementor-element').is($mainElement); + }); + }, + getUniqueHandlerID(cid, $element) { + if (!cid) { + cid = this.getModelCID(); + } + if (!$element) { + $element = this.$element; + } + return cid + $element.attr('data-element_type') + this.getConstructorID(); + }, + initEditorListeners() { + var self = this; + self.editorListeners = [{ + event: 'element:destroy', + to: elementor.channels.data, + callback(removedModel) { + if (removedModel.cid !== self.getModelCID()) { + return; + } + self.onDestroy(); + } + }]; + if (self.onElementChange) { + const elementType = self.getWidgetType() || self.getElementType(); + let eventName = 'change'; + if ('global' !== elementType) { + eventName += ':' + elementType; + } + self.editorListeners.push({ + event: eventName, + to: elementor.channels.editor, + callback(controlView, elementView) { + var elementViewHandlerID = self.getUniqueHandlerID(elementView.model.cid, elementView.$el); + if (elementViewHandlerID !== self.getUniqueHandlerID()) { + return; + } + self.onElementChange(controlView.model.get('name'), controlView, elementView); + } + }); + } + if (self.onEditSettingsChange) { + self.editorListeners.push({ + event: 'change:editSettings', + to: elementor.channels.editor, + callback(changedModel, view) { + if (view.model.cid !== self.getModelCID()) { + return; + } + const propName = Object.keys(changedModel.changed)[0]; + self.onEditSettingsChange(propName, changedModel.changed[propName]); + } + }); + } + ['page'].forEach(function (settingsType) { + var listenerMethodName = 'on' + settingsType[0].toUpperCase() + settingsType.slice(1) + 'SettingsChange'; + if (self[listenerMethodName]) { + self.editorListeners.push({ + event: 'change', + to: elementor.settings[settingsType].model, + callback(model) { + self[listenerMethodName](model.changed); + } + }); + } + }); + }, + getEditorListeners() { + if (!this.editorListeners) { + this.initEditorListeners(); + } + return this.editorListeners; + }, + addEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.addListenerOnce(uniqueHandlerID, listener.event, listener.callback, listener.to); + }); + }, + removeEditorListeners() { + var uniqueHandlerID = this.getUniqueHandlerID(); + this.getEditorListeners().forEach(function (listener) { + elementorFrontend.removeListeners(uniqueHandlerID, listener.event, null, listener.to); + }); + }, + getElementType() { + return this.$element.data('element_type'); + }, + getWidgetType() { + const widgetType = this.$element.data('widget_type'); + if (!widgetType) { + return; + } + return widgetType.split('.')[0]; + }, + getID() { + return this.$element.data('id'); + }, + getModelCID() { + return this.$element.data('model-cid'); + }, + getElementSettings(setting) { + let elementSettings = {}; + const modelCID = this.getModelCID(); + if (this.isEdit && modelCID) { + const settings = elementorFrontend.config.elements.data[modelCID], + attributes = settings.attributes; + let type = attributes.widgetType || attributes.elType; + if (attributes.isInner) { + type = 'inner-' + type; + } + let settingsKeys = elementorFrontend.config.elements.keys[type]; + if (!settingsKeys) { + settingsKeys = elementorFrontend.config.elements.keys[type] = []; + jQuery.each(settings.controls, (name, control) => { + if (control.frontend_available || control.editor_available) { + settingsKeys.push(name); + } + }); + } + jQuery.each(settings.getActiveControls(), function (controlKey) { + if (-1 !== settingsKeys.indexOf(controlKey)) { + let value = attributes[controlKey]; + if (value.toJSON) { + value = value.toJSON(); + } + elementSettings[controlKey] = value; + } + }); + } else { + elementSettings = this.$element.data('settings') || {}; + } + return this.getItems(elementSettings, setting); + }, + getEditSettings(setting) { + var attributes = {}; + if (this.isEdit) { + attributes = elementorFrontend.config.elements.editSettings[this.getModelCID()].attributes; + } + return this.getItems(attributes, setting); + }, + getCurrentDeviceSetting(settingKey) { + return elementorFrontend.getCurrentDeviceSetting(this.getElementSettings(), settingKey); + }, + onInit() { + if (this.isActive(this.getSettings())) { + elementorModules.ViewModule.prototype.onInit.apply(this, arguments); + } + }, + onDestroy() { + if (this.isEdit) { + this.removeEditorListeners(); + } + if (this.unbindEvents) { + this.unbindEvents(); + } + } +}); + +/***/ }) + +}]); +//# sourceMappingURL=e8eba20060a4b0fa29dc.bundle.js.map \ No newline at end of file diff --git a/assets/js/editor.js b/assets/js/editor.js new file mode 100644 index 00000000..10abe8ef --- /dev/null +++ b/assets/js/editor.js @@ -0,0 +1,10052 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../assets/dev/js/editor/element-editor-module.js": +/*!********************************************************!*\ + !*** ../assets/dev/js/editor/element-editor-module.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + elementType: null, + __construct(elementType) { + this.elementType = elementType; + this.addEditorListener(); + }, + updateOptions(name, options) { + const controlView = this.getEditorControlView(name); + if (controlView) { + this.getEditorControlModel(name).set('options', options); + controlView.render(); + } + }, + addEditorListener() { + var self = this; + if (self.onElementChange) { + var eventName = 'change'; + if ('global' !== self.elementType) { + eventName += ':' + self.elementType; + } + elementor.channels.editor.on(eventName, function (controlView, elementView) { + self.onElementChange(controlView.model.get('name'), controlView, elementView); + }); + } + }, + /** + * Add a spinner to a control inside its control title. + * + * @param {string} controlName - The control name to add the spinner to. + * + * @return {void} + */ + addControlSpinner(controlName) { + const $el = this.getEditorControlView(controlName).$el; + + // Exit if there is a spinner already. + if ($el.find('.elementor-control-spinner').length) { + return; + } + const $input = $el.find(':input'); + $input.attr('disabled', true); + $el.find('.elementor-control-title').after(' '); + }, + /** + * Remove a spinner from a control. + * + * @param {string} controlName - The control name to remove the spinner from. + * + * @return {void} + */ + removeControlSpinner(controlName) { + const $controlEl = this.getEditorControlView(controlName).$el; + $controlEl.find(':input').attr('disabled', false); + $controlEl.find('.elementor-control-spinner').remove(); + }, + /** + * Add an error message under the control. + * + * @param {string} controlName - The control name to add the error to. + * @param {string} error - Set an error message. + * @param {string} location - A CSS selector to the element which the error will be appended to. + * + * @return {void} + */ + addControlError(controlName, error, location = '.elementor-control-content') { + const $el = this.getEditorControlView(controlName).$el; + + // Remove any existing error in order to override it. + if ($el.find('.e-control-error').length) { + $el.find('.e-control-error').remove(); + } + + // Select only the first elements to prevent cases where the error is added to many elements. + // (usually in repeater controls). + $el.find(location).first().after(`${error}`); + }, + /** + * Remove the control error message. + * + * @param {string} controlName - The control name to add the error to. + * + * @return {void} + */ + removeControlError(controlName) { + const $el = this.getEditorControlView(controlName).$el; + $el.find('.e-control-error').remove(); + }, + /** + * Remove any indicators that are related to the control. (e.g. spinner, error, etc.) + * + * @param {string} controlName - The control name to reset. + * + * @return {void} + */ + resetControlIndicators(controlName) { + this.removeControlSpinner(controlName); + this.removeControlError(controlName); + }, + addSectionListener(section, callback) { + const self = this; + elementor.channels.editor.on('section:activated', function (sectionName, editor) { + var model = editor.getOption('editedElementView').getEditModel(), + currentElementType = model.get('elType'), + _arguments = arguments; + if ('widget' === currentElementType) { + currentElementType = model.get('widgetType'); + } + if (self.elementType === currentElementType && section === sectionName) { + setTimeout(function () { + callback.apply(self, _arguments); + }, 10); + } + }); + } +}); + +/***/ }), + +/***/ "../assets/dev/js/editor/inline-controls-stack.js": +/*!********************************************************!*\ + !*** ../assets/dev/js/editor/inline-controls-stack.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.views.ControlsStack.extend({ + activeTab: 'content', + activeSection: 'settings', + initialize() { + this.collection = new Backbone.Collection(_.values(this.options.controls)); + }, + filter(model) { + if ('section' === model.get('type')) { + return true; + } + var section = model.get('section'); + return !section || section === this.activeSection; + }, + childViewOptions() { + return { + elementSettingsModel: this.model + }; + } +}); + +/***/ }), + +/***/ "../assets/dev/js/editor/tiers.js": +/*!****************************************!*\ + !*** ../assets/dev/js/editor/tiers.js ***! + \****************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isTierAtLeast = exports.TIERS_PRIORITY = void 0; +// TODO: Read from Core. +const TIERS_PRIORITY = exports.TIERS_PRIORITY = Object.freeze(['free', 'essential', 'essential-oct2023', 'advanced', 'expert', 'agency']); +const isTierAtLeast = (currentTier, expectedTier) => { + const currentTierIndex = TIERS_PRIORITY.indexOf(currentTier); + const expectedTierIndex = TIERS_PRIORITY.indexOf(expectedTier); + if (-1 === currentTierIndex || -1 === expectedTierIndex) { + return false; + } + return currentTierIndex >= expectedTierIndex; +}; +exports.isTierAtLeast = isTierAtLeast; + +/***/ }), + +/***/ "../assets/dev/js/preview/utils/document-handle.js": +/*!*********************************************************!*\ + !*** ../assets/dev/js/preview/utils/document-handle.js ***! + \*********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.SAVE_CONTEXT = exports.EDIT_CONTEXT = void 0; +exports.createElement = createElement; +exports["default"] = addDocumentHandle; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +const EDIT_HANDLE_CLASS_NAME = 'elementor-document-handle'; +const EDIT_MODE_CLASS_NAME = 'elementor-edit-mode'; +const EDIT_CONTEXT = exports.EDIT_CONTEXT = 'edit'; +const SAVE_HANDLE_CLASS_NAME = 'elementor-document-save-back-handle'; +const SAVE_CONTEXT = exports.SAVE_CONTEXT = 'save'; + +/** + * @param {Object} handleTarget + * @param {HTMLElement} handleTarget.element + * @param {string|number} handleTarget.id - Document ID. + * @param {string} handleTarget.title + * @param {string} context - Edit/Save + * @param {Function|null} onCloseDocument - Callback to run when outgoing document is closed. + * @param {string} selector + */ +function addDocumentHandle({ + element, + id, + title = __('Template', 'elementor-pro') +}, context = EDIT_CONTEXT, onCloseDocument = null, selector = null) { + if (EDIT_CONTEXT === context) { + if (!id || !element) { + throw Error('`id` and `element` are required.'); + } + if (isCurrentlyEditing(element) || hasHandle(element)) { + return; + } + } + const handleElement = createHandleElement({ + title, + onClick: () => onDocumentClick(id, context, onCloseDocument, selector) + }, context, element); + element.prepend(handleElement); + if (EDIT_CONTEXT === context) { + element.dataset.editableElementorDocument = id; + } +} + +/** + * @param {HTMLElement} element + * + * @return {boolean} Whether the element is currently being edited. + */ +function isCurrentlyEditing(element) { + return element.classList.contains(EDIT_MODE_CLASS_NAME); +} + +/** + * @param {HTMLElement} element + * + * @return {boolean} Whether the element has a handle. + */ +function hasHandle(element) { + return !!element.querySelector(`:scope > .${EDIT_HANDLE_CLASS_NAME}`); +} + +/** + * @param {Object} handleProperties + * @param {string} handleProperties.title + * @param {Function} handleProperties.onClick + * @param {string} context + * @param {HTMLElement} element + * + * @return {HTMLElement} The newly generated Handle element + */ +function createHandleElement({ + title, + onClick +}, context, element = null) { + const handleTitle = ['header', 'footer'].includes(element?.dataset.elementorType) ? '%s' : __('Edit %s', 'elementor-pro'); + const innerElement = createElement({ + tag: 'div', + classNames: [`${EDIT_HANDLE_CLASS_NAME}__inner`], + children: [createElement({ + tag: 'i', + classNames: [getHandleIcon(context)] + }), createElement({ + tag: 'div', + classNames: [`${EDIT_CONTEXT === context ? EDIT_HANDLE_CLASS_NAME : SAVE_HANDLE_CLASS_NAME}__title`], + children: [document.createTextNode(EDIT_CONTEXT === context ? handleTitle.replace('%s', title) : __('Save %s', 'elementor-pro').replace('%s', title))] + })] + }); + const classNames = [EDIT_HANDLE_CLASS_NAME]; + if (EDIT_CONTEXT !== context) { + classNames.push(SAVE_HANDLE_CLASS_NAME); + } + const containerElement = createElement({ + tag: 'div', + classNames, + children: [innerElement] + }); + containerElement.addEventListener('click', onClick); + return containerElement; +} +function getHandleIcon(context) { + let icon = 'eicon-edit'; + if (SAVE_CONTEXT === context) { + icon = elementorFrontend.config.is_rtl ? 'eicon-arrow-right' : 'eicon-arrow-left'; + } + return icon; +} + +/** + * Util for creating HTML element. + * + * @param {Object} elementProperties + * @param {string} elementProperties.tag + * @param {string[]} elementProperties.classNames + * @param {HTMLElement[]} elementProperties.children + * + * @return {HTMLElement} Generated Element + */ +function createElement({ + tag, + classNames = [], + children = [] +}) { + const element = document.createElement(tag); + element.classList.add(...classNames); + children.forEach(child => element.appendChild(child)); + return element; +} + +/** + * @param {string|number} id + * @param {string} context + * @param {Function|null} onCloseDocument + * @param {string} selector + * @return {Promise} + */ +async function onDocumentClick(id, context, onCloseDocument = null, selector = null) { + if (EDIT_CONTEXT === context) { + window.top.$e.internal('panel/state-loading'); + await window.top.$e.run('editor/documents/switch', { + id: parseInt(id), + onClose: onCloseDocument, + selector + }); + window.top.$e.internal('panel/state-ready'); + } else { + elementorCommon.api.internal('panel/state-loading'); + elementorCommon.api.run('editor/documents/switch', { + id: elementor.config.initial_document.id, + mode: 'save', + shouldScroll: false, + selector + }).finally(() => elementorCommon.api.internal('panel/state-ready')); + } +} + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js": +/*!************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ConditionsConfig = void 0; +class ConditionsConfig extends $e.modules.CommandData { + static signature = 'site-editor/conditions-config'; + static getEndpointFormat() { + return 'site-editor/conditions-config/{id}'; + } +} +exports.ConditionsConfig = ConditionsConfig; +var _default = exports["default"] = ConditionsConfig; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/index.js": +/*!************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/index.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ConditionsConfig", ({ + enumerable: true, + get: function () { + return _conditionsConfig.ConditionsConfig; + } +})); +Object.defineProperty(exports, "Templates", ({ + enumerable: true, + get: function () { + return _templates.Templates; + } +})); +Object.defineProperty(exports, "TemplatesConditions", ({ + enumerable: true, + get: function () { + return _templatesConditions.TemplatesConditions; + } +})); +Object.defineProperty(exports, "TemplatesConditionsConflicts", ({ + enumerable: true, + get: function () { + return _templatesConditionsConflicts.TemplatesConditionsConflicts; + } +})); +var _templates = __webpack_require__(/*! ./templates */ "../core/app/modules/site-editor/assets/js/data/commands/templates.js"); +var _conditionsConfig = __webpack_require__(/*! ./conditions-config */ "../core/app/modules/site-editor/assets/js/data/commands/conditions-config.js"); +var _templatesConditions = __webpack_require__(/*! ./templates-conditions */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js"); +var _templatesConditionsConflicts = __webpack_require__(/*! ./templates-conditions-conflicts */ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js"); + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js": +/*!*************************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions-conflicts.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditionsConflicts = void 0; +class TemplatesConditionsConflicts extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions-conflicts'; + static getEndpointFormat() { + return `${TemplatesConditionsConflicts.signature}/{id}`; + } +} +exports.TemplatesConditionsConflicts = TemplatesConditionsConflicts; +var _default = exports["default"] = TemplatesConditionsConflicts; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js": +/*!***************************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates-conditions.js ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.TemplatesConditions = void 0; +class TemplatesConditions extends $e.modules.CommandData { + static signature = 'site-editor/templates-conditions'; + static getEndpointFormat() { + return 'site-editor/templates-conditions/{id}'; + } +} +exports.TemplatesConditions = TemplatesConditions; +var _default = exports["default"] = TemplatesConditions; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/commands/templates.js": +/*!****************************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/commands/templates.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Templates = void 0; +class Templates extends $e.modules.CommandData { + static signature = 'site-editor/templates'; + static getEndpointFormat() { + return 'site-editor/templates/{id}'; + } +} +exports.Templates = Templates; +var _default = exports["default"] = Templates; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/data/component.js": +/*!*******************************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/data/component.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var dataCommands = _interopRequireWildcard(__webpack_require__(/*! ./commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + static namespace = 'site-editor'; + getNamespace() { + return this.constructor.namespace; + } + defaultData() { + return this.importCommands(dataCommands); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../core/app/modules/site-editor/assets/js/editor.js": +/*!***********************************************************!*\ + !*** ../core/app/modules/site-editor/assets/js/editor.js ***! + \***********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./data/component */ "../core/app/modules/site-editor/assets/js/data/component.js")); +var _commands = __webpack_require__(/*! ./data/commands */ "../core/app/modules/site-editor/assets/js/data/commands/index.js"); +class Module extends elementorModules.editor.utils.Module { + onElementorInit() { + const config = elementor.documents.getCurrent().config; + if (config.support_site_editor) { + $e.components.register(new _component.default()); + $e.data.deleteCache($e.components.get(_component.default.namespace), _commands.Templates.signature); + } + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/editor/editor.js": +/*!************************************************************!*\ + !*** ../modules/assets-manager/assets/js/editor/editor.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + onElementorInit() { + var FontsManager = __webpack_require__(/*! ./font-manager */ "../modules/assets-manager/assets/js/editor/font-manager.js"); + this.assets = { + font: new FontsManager() + }; + } +}); + +/***/ }), + +/***/ "../modules/assets-manager/assets/js/editor/font-manager.js": +/*!******************************************************************!*\ + !*** ../modules/assets-manager/assets/js/editor/font-manager.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +module.exports = elementorModules.Module.extend({ + _enqueuedFonts: [], + _enqueuedTypekit: false, + onFontChange(fontType, font) { + if ('custom' !== fontType && 'typekit' !== fontType && 'variable' !== fontType) { + return; + } + if (-1 !== this._enqueuedFonts.indexOf(font)) { + return; + } + if ('typekit' === fontType && this._enqueuedTypekit) { + return; + } + this.getCustomFont(fontType, font); + }, + getCustomFont(fontType, font) { + elementorPro.ajax.addRequest('assets_manager_panel_action_data', { + unique_id: 'font_' + fontType + font, + data: { + service: 'font', + type: fontType, + font + }, + success(data) { + if (data.font_face) { + elementor.$previewContents.find('style').last().after(''); + } + if (data.font_url) { + elementor.$previewContents.find('link').last().after(''); + } + } + }); + this._enqueuedFonts.push(font); + if ('typekit' === fontType) { + this._enqueuedTypekit = true; + } + }, + onInit() { + elementor.channels.editor.on('font:insertion', this.onFontChange.bind(this)); + } +}); + +/***/ }), + +/***/ "../modules/custom-css/assets/js/editor/editor.js": +/*!********************************************************!*\ + !*** ../modules/custom-css/assets/js/editor/editor.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.editor.utils.Module { + addCustomCss(css, context) { + if (!context) { + return; + } + const model = context.model, + customCSS = model.get('settings').get('custom_css'); + let selector = '.elementor-element.elementor-element-' + model.get('id'); + if ('document' === model.get('elType')) { + selector = elementor.config.document.settings.cssWrapperSelector; + } + if (customCSS) { + css += customCSS.replace(/selector/g, selector); + } + return css; + } + onElementorInit() { + elementor.hooks.addFilter('editor/style/styleText', this.addCustomCss); + elementor.on('navigator:init', this.onNavigatorInit.bind(this)); + } + onNavigatorInit() { + elementor.navigator.indicators.customCSS = { + icon: 'code-bold', + settingKeys: ['custom_css'], + title: __('Custom CSS', 'elementor-pro'), + section: 'section_custom_css' + }; + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/flip-box/assets/js/editor/editor.js": +/*!******************************************************!*\ + !*** ../modules/flip-box/assets/js/editor/editor.js ***! + \******************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + onElementorInit() { + elementor.channels.editor.on('section:activated', this.onSectionActivated); + }, + onSectionActivated(sectionName, editor) { + var editedElement = editor.getOption('editedElementView'); + if ('flip-box' !== editedElement.model.get('widgetType')) { + return; + } + var isSideBSection = -1 !== ['section_side_b_content', 'section_style_b'].indexOf(sectionName); + editedElement.$el.toggleClass('elementor-flip-box--flipped', isSideBSection); + var $backLayer = editedElement.$el.find('.elementor-flip-box__back'); + if (isSideBSection) { + $backLayer.css('transition', 'none'); + } + if (!isSideBSection) { + setTimeout(function () { + $backLayer.css('transition', ''); + }, 10); + } + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/component.js": +/*!******************************************************!*\ + !*** ../modules/forms/assets/js/editor/component.js ***! + \******************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/forms/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + getNamespace() { + return 'forms'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields-map-control.js": +/*!***************************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields-map-control.js ***! + \***************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +module.exports = elementor.modules.controls.Repeater.extend({ + onBeforeRender() { + this.$el.hide(); + }, + updateMap(fields) { + var self = this, + savedMapObject = {}; + self.collection.each(function (model) { + savedMapObject[model.get('remote_id')] = model.get('local_id'); + }); + self.collection.reset(); + _.each(fields, function (field) { + var model = { + remote_id: field.remote_id, + remote_label: field.remote_label, + remote_type: field.remote_type ? field.remote_type : '', + remote_required: field.remote_required ? field.remote_required : false, + local_id: savedMapObject[field.remote_id] ? savedMapObject[field.remote_id] : '' + }; + self.collection.add(model); + }); + self.render(); + }, + onRender() { + elementor.modules.controls.Base.prototype.onRender.apply(this, arguments); + var self = this; + self.children.each(function (view) { + var localFieldsControl = view.children.last(), + options = { + '': '- ' + __('None', 'elementor-pro') + ' -' + }, + label = view.model.get('remote_label'); + if (view.model.get('remote_required')) { + label += '*'; + } + _.each(self.elementSettingsModel.get('form_fields').models, function (model, index) { + // If it's an email field, add only email fields from thr form + var remoteType = view.model.get('remote_type'); + if ('text' !== remoteType && remoteType !== model.get('field_type')) { + return; + } + options[model.get('custom_id')] = model.get('field_label') || 'Field #' + (index + 1); + }); + localFieldsControl.model.set('label', label); + localFieldsControl.model.set('options', options); + localFieldsControl.render(); + view.$el.find('.elementor-repeater-row-tools').hide(); + view.$el.find('.elementor-repeater-row-controls').removeClass('elementor-repeater-row-controls').find('.elementor-control').css({ + paddingBottom: 0 + }); + }); + self.$el.find('.elementor-button-wrapper').remove(); + if (self.children.length) { + self.$el.show(); + } + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields-repeater-control.js": +/*!********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields-repeater-control.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _fieldsRepeaterRow = _interopRequireDefault(__webpack_require__(/*! ./fields-repeater-row */ "../modules/forms/assets/js/editor/fields-repeater-row.js")); +module.exports = class extends elementor.modules.controls.Repeater { + className() { + let classes = super.className(); + classes += ' elementor-control-type-repeater'; + return classes; + } + getChildView() { + return _fieldsRepeaterRow.default; + } + initialize(...args) { + super.initialize(...args); + const formFields = this.container.settings.get('form_fields'); + this.listenTo(formFields, 'change', model => this.onFormFieldChange(model)).listenTo(formFields, 'remove', model => this.onFormFieldRemove(model)); + } + getFirstChild() { + return this.children.findByModel(this.collection.models[0]); + } + lockFirstStep() { + const firstChild = this.getFirstChild(); + if ('step' !== firstChild.model.get('field_type')) { + return; + } + const stepFields = this.collection.where({ + field_type: 'step' + }); + if (1 < stepFields.length) { + firstChild.toggleFieldTypeControl(false); + firstChild.toggleTools(false); + } + firstChild.toggleSort(false); + } + onFormFieldChange(model) { + const fieldType = model.changed.field_type; + if (!fieldType || 'step' !== fieldType && 'step' !== model._previousAttributes.field_type) { + return; + } + const isStep = 'step' === fieldType; + this.children.findByModel(model).toggleStepField(isStep); + this.onStepFieldChanged(isStep); + } + onFormFieldRemove(model) { + if ('step' === model.get('field_type')) { + this.onStepFieldChanged(false); + } + } + onStepFieldChanged(isStep) { + if (isStep) { + this.lockFirstStep(); + return; + } + const stepFields = this.collection.where({ + field_type: 'step' + }); + if (stepFields.length > 1) { + return; + } + const firstChild = this.getFirstChild(); + if (1 === stepFields.length) { + firstChild.toggleTools(true); + firstChild.toggleFieldTypeControl(true); + return; + } + firstChild.toggleSort(true); + } + onAddChild(childView) { + super.onAddChild(childView); + if ('step' === childView.model.get('field_type')) { + this.lockFirstStep(); + childView.toggleStepField(true); + } + } +}; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields-repeater-row.js": +/*!****************************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields-repeater-row.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementor.modules.controls.RepeaterRow { + toggleFieldTypeControl(show) { + const fieldTypeModel = this.collection.findWhere({ + name: 'field_type' + }), + fieldTypeControl = this.children.findByModel(fieldTypeModel); + fieldTypeControl.$el.toggle(show); + } + toggleStepField(isStep) { + this.$el.toggleClass('elementor-repeater-row--form-step', isStep); + } + toggleTools(show) { + this.ui.removeButton.add(this.ui.duplicateButton).toggle(show); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields/acceptance.js": +/*!**************************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields/acceptance.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + renderField(inputField, item, i, settings) { + var itemClasses = _.escape(item.css_classes), + required = '', + label = '', + checked = ''; + if (item.required) { + required = 'required'; + } + if (item.acceptance_text) { + label = ''; + } + if (item.checked_by_default) { + checked = ' checked="checked"'; + } + return '
    ' + '' + ' ' + label + '
    '; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/acceptance', this.renderField, 10, 4); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields/date.js": +/*!********************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields/date.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + renderField(inputField, item, i, settings) { + var itemClasses = _.escape(item.css_classes), + required = '', + min = '', + max = '', + placeholder = ''; + if (item.required) { + required = 'required'; + } + if (item.min_date) { + min = ' min="' + item.min_date + '"'; + } + if (item.max_date) { + max = ' max="' + item.max_date + '"'; + } + if (item.placeholder) { + placeholder = ' placeholder="' + item.placeholder + '"'; + } + if ('yes' === item.use_native_date) { + itemClasses += ' elementor-use-native'; + } + return ''; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/date', this.renderField, 10, 4); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields/tel.js": +/*!*******************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields/tel.js ***! + \*******************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + renderField(inputField, item, i, settings) { + var itemClasses = _.escape(item.css_classes), + required = '', + placeholder = ''; + if (item.required) { + required = 'required'; + } + if (item.placeholder) { + placeholder = ' placeholder="' + item.placeholder + '"'; + } + itemClasses = 'elementor-field-textual ' + itemClasses; + return ''; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/tel', this.renderField, 10, 4); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields/time.js": +/*!********************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields/time.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + renderField(inputField, item, i, settings) { + var itemClasses = _.escape(item.css_classes), + required = '', + placeholder = ''; + if (item.required) { + required = 'required'; + } + if (item.placeholder) { + placeholder = ' placeholder="' + item.placeholder + '"'; + } + if ('yes' === item.use_native_time) { + itemClasses += ' elementor-use-native'; + } + return ''; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/time', this.renderField, 10, 4); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/fields/upload.js": +/*!**********************************************************!*\ + !*** ../modules/forms/assets/js/editor/fields/upload.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + renderField(inputField, item, i, settings) { + var itemClasses = _.escape(item.css_classes), + required = '', + multiple = '', + fieldName = 'form_field_'; + if (item.required) { + required = 'required'; + } + if (item.allow_multiple_upload) { + multiple = ' multiple="multiple"'; + fieldName += '[]'; + } + return ''; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/upload', this.renderField, 10, 4); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hints/email-deliverability.js": +/*!***********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hints/email-deliverability.js ***! + \***********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +module.exports = elementorModules.editor.utils.Module.extend({ + eventName: 'site_mailer_forms_email_notice', + suffix: '', + control: null, + onSectionActive(sectionName) { + // Check if the section is the email section + if (!['section_email', 'section_email_2'].includes(sectionName)) { + return; + } + this.suffix = 'section_email_2' === sectionName ? '_2' : ''; + this.control = null; + + // Check if control exists + if (!this.hasPromoControl()) { + return; + } + + // Check if the user has dismissed the hint + if (elementor.config.user.dismissed_editor_notices.includes('site_mailer_forms_email_notice')) { + this.getPromoControl().remove(); + return; + } + this.registerEvents(); + }, + registerEvents() { + // Handle dismiss and action buttons + const dismissBtn = this.getPromoControl().$el.find('.elementor-control-notice-dismiss'); + const onDismissBtnClick = event => { + dismissBtn.off('click', onDismissBtnClick); // Remove the event listener + event.preventDefault(); + this.dismiss(); + this.getPromoControl().remove(); + }; + dismissBtn.on('click', onDismissBtnClick); + + // Handle action button + const actionBtn = this.getPromoControl().$el.find('.e-btn-1'); + const onActionBtn = event => { + actionBtn.off('click', onActionBtn); // Remove the event listener + event.preventDefault(); + this.onAction(event); + this.getPromoControl().remove(); + }; + actionBtn.on('click', onActionBtn); + }, + getPromoControl() { + if (!this.control) { + this.control = this.getEditorControlView('site_mailer_promo' + this.suffix); + } + return this.control; + }, + hasPromoControl() { + return !!this.getPromoControl(); + }, + ajaxRequest(name, data) { + elementorCommon.ajax.addRequest(name, { + data + }); + }, + dismiss() { + this.ajaxRequest('dismissed_editor_notices', { + dismissId: this.eventName + }); + + // Prevent opening the same hint again in current editor session. + this.ensureNoPromoControlInSession(); + }, + ensureNoPromoControlInSession() { + // Prevent opening the same hint again in current editor session. + elementor.config.user.dismissed_editor_notices.push(this.eventName); + }, + onAction(event) { + const { + action_url: actionURL = null + } = JSON.parse(event.target.closest('button').dataset.settings); + if (actionURL) { + window.open(actionURL, '_blank'); + } + this.ajaxRequest('elementor_site_mailer_campaign', { + source: 'sm-form-install' + }); + this.ensureNoPromoControlInSession(); + }, + onInit() { + elementor.channels.editor.on('section:activated', sectionName => this.onSectionActive(sectionName)); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hints/submission-analysis.js": +/*!**********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hints/submission-analysis.js ***! + \**********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +module.exports = elementorModules.editor.utils.Module.extend({ + eventName: 'send_app_forms_actions_notice', + suffix: '', + control: null, + onSectionActive(sectionName) { + if (!this.isCurrentSection(sectionName)) { + return; + } + this.control = null; + if (!this.hasPromoControl()) { + return; + } + if (this.isNoticeDismissed('send_app_forms_actions_notice')) { + this.getPromoControl().remove(); + return; + } + this.registerEvents(); + }, + isCurrentSection(sectionName) { + return ['section_integration'].includes(sectionName); + }, + isNoticeDismissed(noticeName) { + return elementor.config.user.dismissed_editor_notices.includes(noticeName); + }, + registerEvents() { + const dismissBtn = this.getPromoControl().$el.find('.elementor-control-notice-dismiss'); + const onDismissBtnClick = event => { + dismissBtn.off('click', onDismissBtnClick); + event.preventDefault(); + this.dismiss(); + this.getPromoControl().remove(); + }; + dismissBtn.on('click', onDismissBtnClick); + const actionBtn = this.getPromoControl().$el.find('.e-btn-1'); + const onActionBtn = event => { + actionBtn.off('click', onActionBtn); + event.preventDefault(); + this.onAction(event); + this.getPromoControl().remove(); + }; + actionBtn.on('click', onActionBtn); + }, + getPromoControl() { + if (this.control) { + return this.control; + } + if (!!this.getEditorControlModel('send_app_promo' + this.suffix)) { + this.control = this.getEditorControlView('send_app_promo' + this.suffix); + } + return this.control; + }, + hasPromoControl() { + return !!this.getPromoControl(); + }, + ajaxRequest(name, data) { + elementorCommon.ajax.addRequest(name, { + data + }); + }, + dismiss() { + this.ajaxRequest('dismissed_editor_notices', { + dismissId: this.eventName + }); + this.ensureNoPromoControlInSession(); + }, + ensureNoPromoControlInSession() { + elementor.config.user.dismissed_editor_notices.push(this.eventName); + }, + onAction(event) { + const { + action_url: actionURL = null + } = JSON.parse(event.currentTarget.dataset.settings); + if (actionURL) { + window.open(actionURL, '_blank'); + } + this.ajaxRequest('elementor_send_app_campaign', { + source: 'snd-form-install' + }); + this.ensureNoPromoControlInSession(); + }, + onInit() { + elementor.channels.editor.on('section:activated', sectionName => this.onSectionActive(sectionName)); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/data/form-fields-sanitize-custom-id.js": +/*!**************************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/data/form-fields-sanitize-custom-id.js ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FormFieldsSanitizeCustomId = void 0; +class FormFieldsSanitizeCustomId extends $e.modules.hookData.Dependency { + ID_SANITIZE_FILTER = /[^\w]/g; + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-forms-fields-sanitize-custom-id'; + } + getContainerType() { + return 'repeater'; + } + getConditions(args) { + return undefined !== args.settings.custom_id; + } + apply(args) { + const { + containers = [args.container], + settings + } = args, + // `custom_id` is the control name. + { + custom_id: customId + } = settings; + if (customId.match(this.ID_SANITIZE_FILTER)) { + // Re-render with old settings. + containers.forEach(container => { + const panelView = container.panel.getControlView('form_fields'), + currentItemView = panelView.children.findByModel(container.settings), + idView = currentItemView.children.find(view => 'custom_id' === view.model.get('name')); + idView.render(); + idView.$el.find('input').trigger('focus'); + }); + + // Hook-Break. + return false; + } + return true; + } +} +exports.FormFieldsSanitizeCustomId = FormFieldsSanitizeCustomId; +var _default = exports["default"] = FormFieldsSanitizeCustomId; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/data/form-fields-set-custom-id.js": +/*!*********************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/data/form-fields-set-custom-id.js ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FormFieldsSetCustomId = void 0; +class FormFieldsSetCustomId extends $e.modules.hookData.After { + getCommand() { + return 'document/repeater/insert'; + } + getId() { + return 'elementor-pro-forms-fields-set-custom-id'; + } + getContainerType() { + return 'widget'; + } + getConditions(args) { + return 'form_fields' === args.name; + } + apply(args, model) { + const { + containers = [args.container] + } = args, + isDuplicate = $e.commands.isCurrentFirstTrace('document/repeater/duplicate'); + containers.forEach((/** Container */container) => { + const itemContainer = container.repeaters.form_fields.children.find(childrenContainer => { + // Sometimes, one of children is {Empty}. + if (childrenContainer) { + return model.get('_id') === childrenContainer.id; + } + return false; + }); + if (!isDuplicate && itemContainer.settings.get('custom_id')) { + return; + } + $e.run('document/elements/settings', { + container: itemContainer, + settings: { + custom_id: 'field_' + itemContainer.id + }, + options: { + external: true + } + }); + }); + return true; + } +} +exports.FormFieldsSetCustomId = FormFieldsSetCustomId; +var _default = exports["default"] = FormFieldsSetCustomId; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/data/form-fields-step.js": +/*!************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/data/form-fields-step.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FormFieldsAddFirstStep = void 0; +class FormFieldsAddFirstStep extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-forms-fields-first-step'; + } + getContainerType() { + return 'repeater'; + } + getConditions(args) { + const { + containers = [args.container] + } = args; + return 'form' === containers[0].parent.parent.model.get('widgetType') && 'step' === args.settings.field_type; + } + apply(args) { + const { + containers = [args.container] + } = args; + containers.forEach((/** Container */container) => { + const firstItem = container.parent.children[0]; + if ('step' === firstItem.settings.get('field_type')) { + return; + } + $e.run('document/repeater/insert', { + container: container.parent.parent, + // Widget + name: 'form_fields', + model: { + field_type: 'step' + }, + options: { + at: 0, + external: true + } + }); + }); + return true; + } +} +exports.FormFieldsAddFirstStep = FormFieldsAddFirstStep; +var _default = exports["default"] = FormFieldsAddFirstStep; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/data/form-sanitize-id.js": +/*!************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/data/form-sanitize-id.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FormSanitizeId = void 0; +class FormSanitizeId extends $e.modules.hookData.Dependency { + ID_SANITIZE_FILTER = /[^\w]/g; + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-forms-sanitize-id'; + } + getContainerType() { + return 'widget'; + } + getConditions(args) { + return undefined !== args.settings.form_id; + } + apply(args) { + const { + container, + settings + } = args; + const { + form_id: formId + } = settings; + + // Re-render with old settings. + if (formId.match(this.ID_SANITIZE_FILTER)) { + const formIdView = container.panel.getControlView('form_id'); + formIdView.render(); + formIdView.$el.find('input').trigger('focus'); + + // Hook-Break. + return false; + } + return true; + } +} +exports.FormSanitizeId = FormSanitizeId; +var _default = exports["default"] = FormSanitizeId; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/data/index.js": +/*!*************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/data/index.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "FormFieldsAddFirstStep", ({ + enumerable: true, + get: function () { + return _formFieldsStep.FormFieldsAddFirstStep; + } +})); +Object.defineProperty(exports, "FormFieldsSanitizeCustomId", ({ + enumerable: true, + get: function () { + return _formFieldsSanitizeCustomId.FormFieldsSanitizeCustomId; + } +})); +Object.defineProperty(exports, "FormFieldsSetCustomId", ({ + enumerable: true, + get: function () { + return _formFieldsSetCustomId.FormFieldsSetCustomId; + } +})); +Object.defineProperty(exports, "FormSanitizeId", ({ + enumerable: true, + get: function () { + return _formSanitizeId.FormSanitizeId; + } +})); +var _formFieldsSanitizeCustomId = __webpack_require__(/*! ./form-fields-sanitize-custom-id */ "../modules/forms/assets/js/editor/hooks/data/form-fields-sanitize-custom-id.js"); +var _formFieldsSetCustomId = __webpack_require__(/*! ./form-fields-set-custom-id */ "../modules/forms/assets/js/editor/hooks/data/form-fields-set-custom-id.js"); +var _formFieldsStep = __webpack_require__(/*! ./form-fields-step */ "../modules/forms/assets/js/editor/hooks/data/form-fields-step.js"); +var _formSanitizeId = __webpack_require__(/*! ./form-sanitize-id */ "../modules/forms/assets/js/editor/hooks/data/form-sanitize-id.js"); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/index.js": +/*!********************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/index.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data/ */ "../modules/forms/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); +var _ui = __webpack_require__(/*! ./ui/ */ "../modules/forms/assets/js/editor/hooks/ui/index.js"); +Object.keys(_ui).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _ui[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _ui[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/ui/form-fields-update-shortcode.js": +/*!**********************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/ui/form-fields-update-shortcode.js ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FormFieldsUpdateShortCode = void 0; +class FormFieldsUpdateShortCode extends $e.modules.hookUI.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-forms-fields-update-shortcode'; + } + getContainerType() { + return 'repeater'; + } + getConditions(args) { + if (!$e.routes.isPartOf('panel/editor') || undefined === args.settings.custom_id) { + return false; + } + return true; + } + apply(args) { + const { + containers = [args.container] + } = args; + containers.forEach((/** Container */container) => { + const panelView = container.panel.getControlView('form_fields'), + currentItemView = panelView.children.find(view => container.id === view.model.get('_id')), + shortcodeView = currentItemView.children.find(view => 'shortcode' === view.model.get('name')); + shortcodeView.render(); + }); + } +} +exports.FormFieldsUpdateShortCode = FormFieldsUpdateShortCode; +var _default = exports["default"] = FormFieldsUpdateShortCode; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/hooks/ui/index.js": +/*!***********************************************************!*\ + !*** ../modules/forms/assets/js/editor/hooks/ui/index.js ***! + \***********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "FormFieldsUpdateShortCode", ({ + enumerable: true, + get: function () { + return _formFieldsUpdateShortcode.FormFieldsUpdateShortCode; + } +})); +var _formFieldsUpdateShortcode = __webpack_require__(/*! ./form-fields-update-shortcode */ "../modules/forms/assets/js/editor/hooks/ui/form-fields-update-shortcode.js"); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/activecampaign.js": +/*!************************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/activecampaign.js ***! + \************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + fields: {}, + getName() { + return 'activecampaign'; + }, + onElementChange(setting) { + switch (setting) { + case 'activecampaign_api_credentials_source': + case 'activecampaign_api_key': + case 'activecampaign_api_url': + this.onApiUpdate(); + break; + case 'activecampaign_list': + this.onListUpdate(); + break; + } + }, + onApiUpdate() { + const self = this, + apikeyControlView = self.getEditorControlView('activecampaign_api_key'), + apiUrlControlView = self.getEditorControlView('activecampaign_api_url'), + apiCredControlView = self.getEditorControlView('activecampaign_api_credentials_source'); + if ('default' !== apiCredControlView.getControlValue() && ('' === apikeyControlView.getControlValue() || '' === apiUrlControlView.getControlValue())) { + self.updateOptions('activecampaign_list', []); + self.getEditorControlView('activecampaign_list').setValue(''); + return; + } + self.addControlSpinner('activecampaign_list'); + const cacheKey = this.getCacheKey({ + controls: [apiCredControlView.getControlValue(), apiUrlControlView.getControlValue(), apikeyControlView.getControlValue()] + }); + self.getActiveCampaignCache('lists', 'activecampaign_list', cacheKey).done(function (data) { + self.updateOptions('activecampaign_list', data.lists); + self.fields = data.fields; + }); + }, + onListUpdate() { + this.updateFieldsMapping(); + }, + updateFieldsMapping() { + var controlView = this.getEditorControlView('activecampaign_list'); + if (!controlView.getControlValue()) { + return; + } + var remoteFields = [{ + remote_label: __('Email', 'elementor-pro'), + remote_type: 'email', + remote_id: 'email', + remote_required: true + }, { + remote_label: __('First Name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'first_name', + remote_required: false + }, { + remote_label: __('Last Name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'last_name', + remote_required: false + }, { + remote_label: __('Phone', 'elementor-pro'), + remote_type: 'text', + remote_id: 'phone', + remote_required: false + }, { + remote_label: __('Organization name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'orgname', + remote_required: false + }]; + for (var field in this.fields) { + if (Object.prototype.hasOwnProperty.call(this.fields, field)) { + remoteFields.push(this.fields[field]); + } + } + this.getEditorControlView('activecampaign_fields_map').updateMap(remoteFields); + }, + getActiveCampaignCache(type, action, cacheKey, requestArgs) { + if (_.has(this.cache[type], cacheKey)) { + var data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'activecampaign', + activecampaign_action: action, + api_key: this.getEditorControlView('activecampaign_api_key').getControlValue(), + api_url: this.getEditorControlView('activecampaign_api_url').getControlValue(), + api_cred: this.getEditorControlView('activecampaign_api_credentials_source').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/base.js": +/*!**************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/base.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var ElementEditorModule = __webpack_require__(/*! elementor-pro/editor/element-editor-module */ "../assets/dev/js/editor/element-editor-module.js"); +module.exports = ElementEditorModule.extend({ + __construct() { + this.cache = {}; + ElementEditorModule.prototype.__construct.apply(this, arguments); + }, + getName() { + return ''; + }, + getCacheKey(args) { + return JSON.stringify({ + service: this.getName(), + data: args + }); + }, + fetchCache(type, cacheKey, requestArgs, immediately = false) { + return elementorPro.ajax.addRequest('forms_panel_action_data', { + unique_id: 'integrations_' + this.getName(), + data: requestArgs, + success: data => { + this.cache[type] = _.extend({}, this.cache[type]); + this.cache[type][cacheKey] = data[type]; + } + }, immediately); + }, + onInit() { + this.addSectionListener('section_' + this.getName(), this.onSectionActive); + }, + onSectionActive() { + this.onApiUpdate(); + }, + onApiUpdate() {} +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/convertkit.js": +/*!********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/convertkit.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + getName() { + return 'convertkit'; + }, + onElementChange(setting) { + switch (setting) { + case 'convertkit_api_key_source': + case 'convertkit_custom_api_key': + this.onApiUpdate(); + break; + case 'convertkit_form': + this.onListUpdate(); + break; + } + }, + onApiUpdate() { + var self = this, + apiKeyControlView = self.getEditorControlView('convertkit_api_key_source'), + customApikeyControlView = self.getEditorControlView('convertkit_custom_api_key'); + if ('default' !== apiKeyControlView.getControlValue() && '' === customApikeyControlView.getControlValue()) { + self.updateOptions('convertkit_form', []); + self.getEditorControlView('convertkit_form').setValue(''); + return; + } + self.addControlSpinner('convertkit_form'); + const cacheKey = this.getCacheKey({ + type: 'data', + controls: [apiKeyControlView.getControlValue(), customApikeyControlView.getControlValue()] + }); + self.getConvertKitCache('data', 'convertkit_get_forms', cacheKey).done(function (data) { + self.updateOptions('convertkit_form', data.data.forms); + self.updateOptions('convertkit_tags', data.data.tags); + }); + }, + onListUpdate() { + this.updateFieldsMapping(); + }, + updateFieldsMapping() { + var controlView = this.getEditorControlView('convertkit_form'); + if (!controlView.getControlValue()) { + return; + } + var remoteFields = [{ + remote_label: __('Email', 'elementor-pro'), + remote_type: 'email', + remote_id: 'email', + remote_required: true + }, { + remote_label: __('First Name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'first_name', + remote_required: false + }]; + this.getEditorControlView('convertkit_fields_map').updateMap(remoteFields); + }, + getConvertKitCache(type, action, cacheKey, requestArgs) { + if (_.has(this.cache[type], cacheKey)) { + var data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'convertkit', + convertkit_action: action, + api_key: this.getEditorControlView('convertkit_api_key_source').getControlValue(), + custom_api_key: this.getEditorControlView('convertkit_custom_api_key').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/drip.js": +/*!**************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/drip.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + getName() { + return 'drip'; + }, + onElementChange(setting) { + switch (setting) { + case 'drip_api_token_source': + case 'drip_custom_api_token': + this.onApiUpdate(); + break; + case 'drip_account': + this.onDripAccountsUpdate(); + break; + } + }, + onApiUpdate() { + var self = this, + controlView = self.getEditorControlView('drip_api_token_source'), + customControlView = self.getEditorControlView('drip_custom_api_token'); + if ('default' !== controlView.getControlValue() && '' === customControlView.getControlValue()) { + self.updateOptions('drip_account', []); + self.getEditorControlView('drip_account').setValue(''); + return; + } + self.addControlSpinner('drip_account'); + this.getCacheKey({ + type: 'accounts', + controls: [controlView.getControlValue(), customControlView.getControlValue()] + }); + self.getDripCache('accounts', 'accounts', controlView.getControlValue()).done(function (data) { + self.updateOptions('drip_account', data.accounts); + }); + }, + onDripAccountsUpdate() { + this.updateFieldsMapping(); + }, + updateFieldsMapping() { + var controlView = this.getEditorControlView('drip_account'); + if (!controlView.getControlValue()) { + return; + } + var remoteFields = { + remote_label: __('Email', 'elementor-pro'), + remote_type: 'email', + remote_id: 'email', + remote_required: true + }; + this.getEditorControlView('drip_fields_map').updateMap([remoteFields]); + }, + getDripCache(type, action, cacheKey, requestArgs) { + if (_.has(this.cache[type], cacheKey)) { + var data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'drip', + drip_action: action, + api_token: this.getEditorControlView('drip_api_token_source').getControlValue(), + custom_api_token: this.getEditorControlView('drip_custom_api_token').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/getresponse.js": +/*!*********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/getresponse.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + getName() { + return 'getresponse'; + }, + onElementChange(setting) { + switch (setting) { + case 'getresponse_custom_api_key': + case 'getresponse_api_key_source': + this.onApiUpdate(); + break; + case 'getresponse_list': + this.onGetResonseListUpdate(); + break; + } + }, + onApiUpdate() { + var self = this, + controlView = self.getEditorControlView('getresponse_api_key_source'), + customControlView = self.getEditorControlView('getresponse_custom_api_key'); + if ('default' !== controlView.getControlValue() && '' === customControlView.getControlValue()) { + self.updateOptions('getresponse_list', []); + self.getEditorControlView('getresponse_list').setValue(''); + return; + } + self.addControlSpinner('getresponse_list'); + const cacheKey = this.getCacheKey({ + type: 'lists', + controls: [controlView.getControlValue(), customControlView.getControlValue()] + }); + self.getCache('lists', 'lists', cacheKey).done(function (data) { + self.updateOptions('getresponse_list', data.lists); + }); + }, + onGetResonseListUpdate() { + this.updatGetResonseList(); + }, + updatGetResonseList() { + var self = this, + controlView = self.getEditorControlView('getresponse_list'); + if (!controlView.getControlValue()) { + return; + } + self.addControlSpinner('getresponse_fields_map'); + const cacheKey = this.getCacheKey({ + type: 'fields', + controls: [controlView.getControlValue()] + }); + self.getCache('fields', 'get_fields', cacheKey, { + getresponse_list: controlView.getControlValue() + }).done(function (data) { + self.getEditorControlView('getresponse_fields_map').updateMap(data.fields); + }); + }, + getCache(type, action, cacheKey, requestArgs) { + if (_.has(this.cache[type], cacheKey)) { + var data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'getresponse', + getresponse_action: action, + api_key: this.getEditorControlView('getresponse_api_key_source').getControlValue(), + custom_api_key: this.getEditorControlView('getresponse_custom_api_key').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs); + }, + onSectionActive() { + BaseIntegrationModule.prototype.onSectionActive.apply(this, arguments); + this.updatGetResonseList(); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/mailchimp.js": +/*!*******************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/mailchimp.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + getName() { + return 'mailchimp'; + }, + onElementChange(setting) { + switch (setting) { + case 'mailchimp_api_key_source': + case 'mailchimp_api_key': + this.onApiUpdate(); + break; + case 'mailchimp_list': + this.onMailchimpListUpdate(); + break; + } + }, + onApiUpdate() { + var self = this, + controlView = self.getEditorControlView('mailchimp_api_key'), + GlobalApiKeycontrolView = self.getEditorControlView('mailchimp_api_key_source'); + if ('default' !== GlobalApiKeycontrolView.getControlValue() && '' === controlView.getControlValue()) { + self.updateOptions('mailchimp_list', []); + self.getEditorControlView('mailchimp_list').setValue(''); + return; + } + + // Add a spinner to the `Audience` list control. + self.resetControlIndicators('mailchimp_list'); + self.addControlSpinner('mailchimp_list'); + const cacheKey = this.getCacheKey({ + type: 'lists', + controls: [controlView.getControlValue(), GlobalApiKeycontrolView.getControlValue()] + }); + + // Fetch data + self.getMailchimpCache('lists', 'lists', cacheKey).done(function (data) { + self.updateOptions('mailchimp_list', data.lists); + self.updatMailchimpList(); + }).fail(function (error) { + self.addControlError('mailchimp_list', error); + }).always(function () { + self.removeControlSpinner('mailchimp_list'); + }); + }, + onMailchimpListUpdate() { + this.updateOptions('mailchimp_groups', []); + this.getEditorControlView('mailchimp_groups').setValue(''); + this.updatMailchimpList(); + }, + updatMailchimpList() { + var self = this, + controlView = self.getEditorControlView('mailchimp_list'); + if (!controlView.getControlValue()) { + return; + } + + // Add a spinner to the groups select box. + self.resetControlIndicators('mailchimp_groups'); + self.addControlSpinner('mailchimp_groups'); + this.getCacheKey({ + type: 'list_details', + controls: [controlView.getControlValue()] + }); + + // Fetch The data + self.getMailchimpCache('list_details', 'list_details', controlView.getControlValue(), { + mailchimp_list: controlView.getControlValue() + }).done(function (data) { + self.updateOptions('mailchimp_groups', data.list_details.groups); + self.getEditorControlView('mailchimp_fields_map').updateMap(data.list_details.fields); + }).fail(function (error) { + self.addControlError('mailchimp_groups', error); + }).always(function () { + self.removeControlSpinner('mailchimp_groups'); + }); + + // Get list fields. + // The requests needed to be executed immediately in order to fill the `Field Mapping` select-boxes + // without waiting for other requests to finish. + const args = { + type: 'fields', + action: 'fields', + cacheKey: controlView.getControlValue(), + args: { + mailchimp_list: controlView.getControlValue() + }, + immediately: true + }; + self.getMailchimpCache(...Object.values(args)).done(function (data) { + self.getEditorControlView('mailchimp_fields_map').updateMap(data.fields); + }); + }, + getMailchimpCache(type, action, cacheKey, requestArgs, immediately = false) { + if (_.has(this.cache[type], cacheKey)) { + var data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'mailchimp', + mailchimp_action: action, + api_key: this.getEditorControlView('mailchimp_api_key').getControlValue(), + use_global_api_key: this.getEditorControlView('mailchimp_api_key_source').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs, immediately); + }, + onSectionActive() { + BaseIntegrationModule.prototype.onSectionActive.apply(this, arguments); + this.onApiUpdate(); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/integrations/mailerlite.js": +/*!********************************************************************!*\ + !*** ../modules/forms/assets/js/editor/integrations/mailerlite.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +const BaseIntegrationModule = __webpack_require__(/*! ./base */ "../modules/forms/assets/js/editor/integrations/base.js"); +module.exports = BaseIntegrationModule.extend({ + fields: {}, + getName() { + return 'mailerlite'; + }, + onElementChange(setting) { + switch (setting) { + case 'mailerlite_api_key_source': + case 'mailerlite_custom_api_key': + this.onMailerliteApiKeyUpdate(); + break; + case 'mailerlite_group': + this.updateFieldsMapping(); + break; + } + }, + onMailerliteApiKeyUpdate() { + var self = this, + controlView = self.getEditorControlView('mailerlite_custom_api_key'), + GlobalApiKeycontrolView = self.getEditorControlView('mailerlite_api_key_source'); + if ('default' !== GlobalApiKeycontrolView.getControlValue() && '' === controlView.getControlValue()) { + self.updateOptions('mailerlite_group', []); + self.getEditorControlView('mailerlite_group').setValue(''); + return; + } + self.addControlSpinner('mailerlite_group'); + const cacheKey = this.getCacheKey({ + type: 'groups', + controls: [controlView.getControlValue(), GlobalApiKeycontrolView.getControlValue()] + }); + self.getMailerliteCache('groups', 'groups', cacheKey).done(function (data) { + self.updateOptions('mailerlite_group', data.groups); + self.fields = data.fields; + }); + }, + updateFieldsMapping() { + const controlView = this.getEditorControlView('mailerlite_group'); + if (!controlView.getControlValue()) { + return; + } + const remoteFields = [{ + remote_label: __('Email', 'elementor-pro'), + remote_type: 'email', + remote_id: 'email', + remote_required: true + }, { + remote_label: __('Name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'name', + remote_required: false + }, { + remote_label: __('Last Name', 'elementor-pro'), + remote_type: 'text', + remote_id: 'last_name', + remote_required: false + }, { + remote_label: __('Company', 'elementor-pro'), + remote_type: 'text', + remote_id: 'company', + remote_required: false + }, { + remote_label: __('Phone', 'elementor-pro'), + remote_type: 'text', + remote_id: 'phone', + remote_required: false + }, { + remote_label: __('Country', 'elementor-pro'), + remote_type: 'text', + remote_id: 'country', + remote_required: false + }, { + remote_label: __('State', 'elementor-pro'), + remote_type: 'text', + remote_id: 'state', + remote_required: false + }, { + remote_label: __('City', 'elementor-pro'), + remote_type: 'text', + remote_id: 'city', + remote_required: false + }, { + remote_label: __('Zip', 'elementor-pro'), + remote_type: 'text', + remote_id: 'zip', + remote_required: false + }]; + for (const field in this.fields) { + if (Object.prototype.hasOwnProperty.call(this.fields, field)) { + remoteFields.push(this.fields[field]); + } + } + this.getEditorControlView('mailerlite_fields_map').updateMap(remoteFields); + }, + getMailerliteCache(type, action, cacheKey, requestArgs) { + if (_.has(this.cache[type], cacheKey)) { + const data = {}; + data[type] = this.cache[type][cacheKey]; + return jQuery.Deferred().resolve(data); + } + requestArgs = _.extend({}, requestArgs, { + service: 'mailerlite', + mailerlite_action: action, + custom_api_key: this.getEditorControlView('mailerlite_custom_api_key').getControlValue(), + api_key: this.getEditorControlView('mailerlite_api_key_source').getControlValue() + }); + return this.fetchCache(type, cacheKey, requestArgs); + }, + onSectionActive() { + BaseIntegrationModule.prototype.onSectionActive.apply(this, arguments); + this.onMailerliteApiKeyUpdate(); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/module.js": +/*!***************************************************!*\ + !*** ../modules/forms/assets/js/editor/module.js ***! + \***************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/forms/assets/js/editor/component.js")); +class FormsModule extends elementorModules.editor.utils.Module { + onElementorInit() { + const ReplyToField = __webpack_require__(/*! ./reply-to-field */ "../modules/forms/assets/js/editor/reply-to-field.js"), + Recaptcha = __webpack_require__(/*! ./recaptcha */ "../modules/forms/assets/js/editor/recaptcha.js"), + MailerLite = __webpack_require__(/*! ./integrations/mailerlite */ "../modules/forms/assets/js/editor/integrations/mailerlite.js"), + Mailchimp = __webpack_require__(/*! ./integrations/mailchimp */ "../modules/forms/assets/js/editor/integrations/mailchimp.js"), + Drip = __webpack_require__(/*! ./integrations/drip */ "../modules/forms/assets/js/editor/integrations/drip.js"), + ActiveCampaign = __webpack_require__(/*! ./integrations/activecampaign */ "../modules/forms/assets/js/editor/integrations/activecampaign.js"), + GetResponse = __webpack_require__(/*! ./integrations/getresponse */ "../modules/forms/assets/js/editor/integrations/getresponse.js"), + ConvertKit = __webpack_require__(/*! ./integrations/convertkit */ "../modules/forms/assets/js/editor/integrations/convertkit.js"), + EmailDeliverability = __webpack_require__(/*! ./hints/email-deliverability */ "../modules/forms/assets/js/editor/hints/email-deliverability.js"), + SubmissionAnalysis = __webpack_require__(/*! ./hints/submission-analysis */ "../modules/forms/assets/js/editor/hints/submission-analysis.js"); + this.replyToField = new ReplyToField(); + this.mailchimp = new Mailchimp('form'); + this.recaptcha = new Recaptcha('form'); + this.drip = new Drip('form'); + this.activecampaign = new ActiveCampaign('form'); + this.getresponse = new GetResponse('form'); + this.convertkit = new ConvertKit('form'); + this.mailerlite = new MailerLite('form'); + + // Form fields + const TimeField = __webpack_require__(/*! ./fields/time */ "../modules/forms/assets/js/editor/fields/time.js"), + DateField = __webpack_require__(/*! ./fields/date */ "../modules/forms/assets/js/editor/fields/date.js"), + AcceptanceField = __webpack_require__(/*! ./fields/acceptance */ "../modules/forms/assets/js/editor/fields/acceptance.js"), + UploadField = __webpack_require__(/*! ./fields/upload */ "../modules/forms/assets/js/editor/fields/upload.js"), + TelField = __webpack_require__(/*! ./fields/tel */ "../modules/forms/assets/js/editor/fields/tel.js"); + this.Fields = { + time: new TimeField('form'), + date: new DateField('form'), + tel: new TelField('form'), + acceptance: new AcceptanceField('form'), + upload: new UploadField('form') + }; + elementor.addControlView('Fields_map', __webpack_require__(/*! ./fields-map-control */ "../modules/forms/assets/js/editor/fields-map-control.js")); + elementor.addControlView('form-fields-repeater', __webpack_require__(/*! ./fields-repeater-control */ "../modules/forms/assets/js/editor/fields-repeater-control.js")); + this.hints = { + emailDeliverability: new EmailDeliverability(), + submissionAnalysis: new SubmissionAnalysis() + }; + } + onElementorInitComponents() { + $e.components.register(new _component.default({ + manager: this + })); + } +} +exports["default"] = FormsModule; + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/recaptcha.js": +/*!******************************************************!*\ + !*** ../modules/forms/assets/js/editor/recaptcha.js ***! + \******************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + enqueueRecaptchaJs(url, type) { + if (!elementorFrontend.elements.$body.find('[src="' + url + '"]').length) { + elementorFrontend.elements.$body.append(''); + } + }, + renderField(inputField, item) { + inputField += '
    '; + inputField += this.getDataSettings(item); + inputField += '
    '; + return inputField; + }, + getDataSettings(item) { + const config = elementorPro.config.forms[item.field_type], + srcURL = 'https://www.google.com/recaptcha/api.js?render=explicit'; + if (!config.enabled) { + return '
    ' + config.setup_message + '
    '; + } + let recaptchaData = 'data-sitekey="' + config.site_key + '" data-type="' + config.type + '"'; + switch (config.type) { + case 'v3': + recaptchaData += ' data-action="form" data-size="invisible" data-badge="' + item.recaptcha_badge + '"'; + break; + case 'v2_checkbox': + recaptchaData += ' data-theme="' + item.recaptcha_style + '"'; + recaptchaData += ' data-size="' + item.recaptcha_size + '"'; + break; + } + this.enqueueRecaptchaJs(srcURL, config.type); + return '
    '; + }, + filterItem(item) { + if ('recaptcha' === item.field_type) { + item.field_label = false; + } + return item; + }, + onInit() { + elementor.hooks.addFilter('elementor_pro/forms/content_template/item', this.filterItem); + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/recaptcha', this.renderField, 10, 2); + elementor.hooks.addFilter('elementor_pro/forms/content_template/field/recaptcha_v3', this.renderField, 10, 2); + } +}); + +/***/ }), + +/***/ "../modules/forms/assets/js/editor/reply-to-field.js": +/*!***********************************************************!*\ + !*** ../modules/forms/assets/js/editor/reply-to-field.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var sprintf = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["sprintf"]; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +module.exports = function () { + var editor, editedModel, replyToControl; + var setReplyToControl = function () { + replyToControl = editor.collection.findWhere({ + name: 'email_reply_to' + }); + }; + var getReplyToView = function () { + return editor.children.findByModelCid(replyToControl.cid); + }; + var refreshReplyToElement = function () { + var replyToView = getReplyToView(); + if (replyToView) { + replyToView.render(); + } + }; + var updateReplyToOptions = function () { + var settingsModel = editedModel.get('settings'), + emailModels = settingsModel.get('form_fields').where({ + field_type: 'email' + }), + emailFields; + emailModels = _.reject(emailModels, { + field_label: '' + }); + emailFields = _.map(emailModels, function (model) { + return { + id: model.get('custom_id'), + label: sprintf(__('%s Field', 'elementor-pro'), model.get('field_label')) + }; + }); + replyToControl.set('options', { + '': replyToControl.get('options')[''] + }); + _.each(emailFields, function (emailField) { + replyToControl.get('options')[emailField.id] = emailField.label; + }); + refreshReplyToElement(); + }; + var updateDefaultReplyTo = function (settingsModel) { + replyToControl.get('options')[''] = settingsModel.get('email_from'); + refreshReplyToElement(); + }; + var onFormFieldsChange = function (changedModel) { + // If it's repeater field + if (changedModel.get('custom_id')) { + if ('email' === changedModel.get('field_type')) { + updateReplyToOptions(); + } + } + if (changedModel.changed.email_from) { + updateDefaultReplyTo(changedModel); + } + }; + var onPanelShow = function (panel, model) { + editor = panel.getCurrentPageView(); + editedModel = model; + setReplyToControl(); + var settingsModel = editedModel.get('settings'); + settingsModel.on('change', onFormFieldsChange); + updateDefaultReplyTo(settingsModel); + updateReplyToOptions(); + }; + var init = function () { + elementor.hooks.addAction('panel/open_editor/widget/form', onPanelShow); + }; + init(); +}; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands-data/index.js": +/*!************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands-data/index.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "Templates", ({ + enumerable: true, + get: function () { + return _templates.Templates; + } +})); +var _templates = __webpack_require__(/*! ./templates */ "../modules/global-widget/assets/js/editor/commands-data/templates.js"); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands-data/templates.js": +/*!****************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands-data/templates.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Templates = void 0; +/** + * Data command: 'document/global/templates', accessing 'global-widget/templates' remote endpoint. + * Used to get global templates from the backend/cache. + */ +class Templates extends $e.modules.CommandData { + static getEndpointFormat() { + return 'global-widget/templates'; + } + onAfterApply(args = {}, result) { + // TODO: Remove - Manually handling of cache - This behavior should be automatically handled by passed `options` to $e.data. + $e.data.deleteCache(this.component, 'document/global/global-widget/templates', args.query); + Object.entries(result.data).forEach(([templateID, data]) => { + $e.data.setCache(this.component, `document/global/global-widget/templates/${templateID}`, {}, data); + }); + } +} +exports.Templates = Templates; +var _default = exports["default"] = Templates; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands-internal/index.js": +/*!****************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands-internal/index.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "SaveTemplates", ({ + enumerable: true, + get: function () { + return _saveTemplates.SaveTemplates; + } +})); +var _saveTemplates = __webpack_require__(/*! ./save-templates */ "../modules/global-widget/assets/js/editor/commands-internal/save-templates.js"); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands-internal/save-templates.js": +/*!*************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands-internal/save-templates.js ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.SaveTemplates = void 0; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +/** + * The command should run over all changed global widgets and + * update the settings of the `document/global/global-widget/templates`, + * And save cache templates according to the widget(s) which are under the save process. + */ +class SaveTemplates extends $e.modules.CommandInternalBase { + apply() { + const templateModels = this.getCurrentTemplatesModels(this.component.changedContainersId); + if (!templateModels.length) { + return; + } + return new Promise((resolve, reject) => { + elementorCommon.ajax.addRequest('update_templates', { + data: { + templates: templateModels.map(templateModel => { + // Map it to backend format. + return { + id: templateModel.get('id'), + content: JSON.stringify([templateModel.toJSON()]), + source: 'local', + type: 'widget' + }; + }) + }, + error: reject, + success: () => { + /** + * Since is used `document/global/global-widget/templates` to hold all globals template data. + * And currently there are no request to update template data on each update of global widget, + * editing the template will be not synced with The real latest data. + * In other words, if dont update templates on each save, + * Then the new created template will be different with the actual (saved) one, so updating the globals template + * according to saved global widget is the solution. + */ + // Clear changed containers. + this.component.changedContainersId = {}; + templateModels.forEach(template => { + const settings = template.get('settings'); + $e.data.setCache(this.component, `document/global/global-widget/templates/${template.id}`, {}, { + settings + }); + }); + resolve(templateModels); + } + }); + }); + } + getCurrentTemplatesModels(changedContainersId) { + const templatesData = []; + Object.entries(changedContainersId).forEach(([templateID, containerId]) => { + const templateData = $e.data.getCache(this.component, `document/global/global-widget/templates/${templateID}`); + if (!templateData) { + if ($e.devTools) { + $e.devTools.log.warn(`$e.data.getCache( component, \`document/global/global-widget/templates/${templateID}\` ) - not found.`); + } + } + const container = elementor.getContainer(containerId); + if (!container) { + return; + } + templatesData.push(new Backbone.Model({ + id: templateID, + elType: 'widget', + widgetType: container.model.get('widgetType'), + settings: container.settings.toJSON({ + remove: 'default' + }), + templateID + })); + }); + return templatesData; + } +} +exports.SaveTemplates = SaveTemplates; +var _default = exports["default"] = SaveTemplates; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands/index.js": +/*!*******************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "Link", ({ + enumerable: true, + get: function () { + return _link.Link; + } +})); +Object.defineProperty(exports, "Unlink", ({ + enumerable: true, + get: function () { + return _unlink.Unlink; + } +})); +var _link = __webpack_require__(/*! ./link */ "../modules/global-widget/assets/js/editor/commands/link.js"); +var _unlink = __webpack_require__(/*! ./unlink */ "../modules/global-widget/assets/js/editor/commands/unlink.js"); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands/link.js": +/*!******************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands/link.js ***! + \******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Link = void 0; +class Link extends $e.modules.editor.document.CommandHistoryBase { + validateArgs(args) { + this.requireContainer(args); + this.requireArgumentConstructor('data', Object, args); + const { + containers = [args.container] + } = args; + containers.forEach((/* Container */container) => { + if ('global' === container.model.get('widgetType')) { + throw Error(`Invalid container, id: '${container.id}' is already global.`); + } + }); + } + getHistory(args) { + const { + data + } = args; + return { + title: elementor.widgetsCache[data.widgetType].title, + subTitle: data.title, + type: __('Linked to Global', 'elementor-pro') + }; + } + apply(args) { + const { + data, + containers = [args.container] + } = args; + containers.forEach((/** Container */container) => { + const widgetModel = container.model, + widgetModelIndex = widgetModel.collection.indexOf(widgetModel); + data.elType = data.type; + data.settings = widgetModel.get('settings').attributes; + data.widgetType = widgetModel.get('widgetType'); + const elementModel = elementorPro.modules.globalWidget.addGlobalWidget(data.template_id, data), + elementModelAttributes = elementModel.attributes; + $e.data.setCache(this.component, `document/global/global-widget/templates/${data.template_id}`, {}, data); + $e.run('document/elements/create', { + container: container.parent, + model: { + id: elementorCommon.helpers.getUniqueId(), + elType: elementModelAttributes.elType, + widgetType: elementModelAttributes.widgetType, + templateID: data.template_id + }, + options: { + at: widgetModelIndex + } + }); + $e.run('document/elements/delete', { + container + }); + }); + $e.route('panel/elements/global'); + } +} +exports.Link = Link; +var _default = exports["default"] = Link; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/commands/unlink.js": +/*!********************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/commands/unlink.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Unlink = void 0; +class Unlink extends $e.modules.editor.document.CommandHistoryBase { + validateArgs(args) { + this.requireContainer(args); + } + getHistory(args) { + const { + containers = [args.container] + } = args; + return { + title: elementor.helpers.getModelLabel(containers[0].model), + // TODO: add support multi containers. + type: __('Unlink Widget', 'elementor-pro') + }; + } + async apply(args) { + const { + containers = [args.container] + } = args; + const ids = containers.map((/** Container */container) => container.model.get('templateID')); + const { + data + } = await $e.data.get('document/global/templates', { + ids + }); + containers.forEach((/** Container */container) => { + const id = container.model.get('templateID'), + elementModel = elementorPro.modules.globalWidget.createGlobalModel(id, data[id]); + $e.run('document/elements/create', { + container: container.parent, + model: { + id: elementorCommon.helpers.getUniqueId(), + elType: 'widget', + widgetType: elementModel.get('widgetType'), + settings: elementorCommon.helpers.cloneObject(elementModel.get('settings').attributes), + defaultEditSettings: elementorCommon.helpers.cloneObject(elementModel.get('editSettings').attributes) + }, + options: { + at: container.model.collection.indexOf(container.model), + edit: true + } + }); + $e.run('document/elements/delete', { + container + }); + }); + } +} +exports.Unlink = Unlink; +var _default = exports["default"] = Unlink; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/component.js": +/*!**************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/component.js ***! + \**************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var commands = _interopRequireWildcard(__webpack_require__(/*! ./commands/ */ "../modules/global-widget/assets/js/editor/commands/index.js")); +var commandsInternal = _interopRequireWildcard(__webpack_require__(/*! ./commands-internal/ */ "../modules/global-widget/assets/js/editor/commands-internal/index.js")); +var commandsData = _interopRequireWildcard(__webpack_require__(/*! ./commands-data/ */ "../modules/global-widget/assets/js/editor/commands-data/index.js")); +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/global-widget/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + /** + * Holds all the template ids, which not available due they simply not exist in document data. + * Those templates will be loaded later after requesting 'panel/elements/global' (global elements panel). + * + * @type {Array} + */ + notLoadedTemplatesIds = []; + + /** + * Last changed global widget(s). + * + * @type {null | Array} Container[] + */ + lastChangedContainers = null; + + /** + * Hold unsaved changed container id for each template id. + * + * Each settings command that run over global widget, this logic is applied: + * `changedContainersId[ templateId ] = containerId`. + * + * @type {{}} + */ + changedContainersId = {}; + registerAPI() { + super.registerAPI(); + + // TODO: Remove when route hooks are available. + $e.routes.on('run:after', (component, route) => { + if ('panel/elements/global' === route) { + this.onRoutePanelElementsGlobal(); + } + }); + } + getNamespace() { + return 'document/global'; + } + defaultCommands() { + return this.importCommands(commands); + } + defaultCommandsInternal() { + return this.importCommands(commandsInternal); + } + defaultData() { + return this.importCommands(commandsData); + } + defaultHooks() { + return this.importHooks(hooks); + } + onRoutePanelElementsGlobal() { + if (this.notLoadedTemplatesIds.length) { + $e.data.get('document/global/templates', { + ids: this.notLoadedTemplatesIds + }).then(() => { + // Clear. + this.notLoadedTemplatesIds = []; + }); + } + } + + /** + * Update each 'Backbone.Model' will handle issue when the global widget saved only in draft. + * Scenario for better understanding the issue: + * - Have global widget save with custom color, refresh the editor. + * - Change it to global global color and save as draft (no update template). + * - Create another global-widget from same template. + * - Update one of first global widget that saved in draft to use custom color. + * - By dependency of only 'container.settings' the new template will have the new custom color, + * but new custom color will unseen (since it has global). + * + * @param {Object} targetContainer Container class + */ + updateGlobalsRecursive(targetContainer) { + const modelsToUpdate = ['dynamic', 'globals', 'settings']; + elementor.getPreviewContainer().forEachChildrenRecursive(container => { + // Will skip self. + if (targetContainer !== container && parseInt(container.model.get('templateID')) === parseInt(targetContainer.model.get('templateID'))) { + modelsToUpdate.forEach(modelName => { + const model = targetContainer[modelName]; + if (model instanceof Backbone.Model) { + const accordingTo = 'settings' === modelName ? targetContainer.settings.attributes : model.changed; + Object.entries(accordingTo).forEach(([key, setting]) => { + container[modelName].set(key, setting); + }); + } + }); + container.render(); + } + }); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/base-global-widget-prepare-update.js": +/*!*************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/base-global-widget-prepare-update.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.BaseGlobalWidgetPrepareUpdate = void 0; +/** + * Hook is responsible for saving last changed global widget and update + * which containers are needed for updating the template. + */ +class BaseGlobalWidgetPrepareUpdate extends $e.modules.hookData.After { + getConditions(args) { + const { + containers = [args.container] + } = args; + + // When the container is repeater item it should add the global repeater itself to the `lastChangedContainers` and not the repeater item + return containers.some(container => container.renderer?.model?.get('templateID')); + } + apply(args) { + const { + containers = [args.container] + } = args, + component = $e.components.get('document/global'); + + // Filter only the containers that are global widgets. (Can pass multiple containers that some of them global widgets and some of them not). + const globalWidgetContainers = containers.filter(container => container.renderer?.model?.get('templateID')); + component.lastChangedContainers = globalWidgetContainers.map(container => container.renderer); + globalWidgetContainers.forEach(container => { + component.changedContainersId[container.renderer.model.get('templateID')] = container.renderer.id; + }); + } +} +exports.BaseGlobalWidgetPrepareUpdate = BaseGlobalWidgetPrepareUpdate; +var _default = exports["default"] = BaseGlobalWidgetPrepareUpdate; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/document/elements/set-settings/global-widget-prepare-update-element-set-settings.js": +/*!************************************************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/document/elements/set-settings/global-widget-prepare-update-element-set-settings.js ***! + \************************************************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetPrepareUpdateElementSetSettings = void 0; +var _baseGlobalWidgetPrepareUpdate = __webpack_require__(/*! ../../../base-global-widget-prepare-update */ "../modules/global-widget/assets/js/editor/hooks/data/base-global-widget-prepare-update.js"); +/** + * Hook is responsible for saving last changed global widget and update + * which containers are needed for updating the template. + */ + +class GlobalWidgetPrepareUpdateElementSetSettings extends _baseGlobalWidgetPrepareUpdate.BaseGlobalWidgetPrepareUpdate { + getCommand() { + return 'document/elements/set-settings'; + } + getId() { + return 'elementor-pro-global-widget-prepare-update-element-set-settings'; + } +} +exports.GlobalWidgetPrepareUpdateElementSetSettings = GlobalWidgetPrepareUpdateElementSetSettings; +var _default = exports["default"] = GlobalWidgetPrepareUpdateElementSetSettings; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/document/history/end-log/global-widget-do-update.js": +/*!****************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/document/history/end-log/global-widget-do-update.js ***! + \****************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetDoUpdate = void 0; +/** + * On after all `document/elements/set-settings` has stop, the history mechanism will call to + * `document/history/end-log` the hook will update all other global widgets according to this last change. + */ +class GlobalWidgetDoUpdate extends $e.modules.hookData.After { + getCommand() { + return 'document/history/end-log'; + } + getId() { + return 'elementor-pro-global-widget-do-update'; + } + getConditions() { + return $e.components.get('document/global').lastChangedContainers; + } + apply() { + const component = $e.components.get('document/global'), + containers = component.lastChangedContainers; + containers.forEach(container => component.updateGlobalsRecursive(container)); + component.lastChangedContainers = null; + } +} +exports.GlobalWidgetDoUpdate = GlobalWidgetDoUpdate; +var _default = exports["default"] = GlobalWidgetDoUpdate; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/document/repeater/insert/global-widget-prepare-update-repeater-insert.js": +/*!*************************************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/document/repeater/insert/global-widget-prepare-update-repeater-insert.js ***! + \*************************************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetPrepareUpdateRepeaterInsert = void 0; +var _baseGlobalWidgetPrepareUpdate = _interopRequireDefault(__webpack_require__(/*! ../../../base-global-widget-prepare-update */ "../modules/global-widget/assets/js/editor/hooks/data/base-global-widget-prepare-update.js")); +/** + * Hook is responsible for saving last changed global widget and update + * which containers are needed for updating the template. + */ + +class GlobalWidgetPrepareUpdateRepeaterInsert extends _baseGlobalWidgetPrepareUpdate.default { + getCommand() { + return 'document/repeater/insert'; + } + getId() { + return 'elementor-pro-global-widget-prepare-update-repeater-insert'; + } +} +exports.GlobalWidgetPrepareUpdateRepeaterInsert = GlobalWidgetPrepareUpdateRepeaterInsert; +var _default = exports["default"] = GlobalWidgetPrepareUpdateRepeaterInsert; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/document/repeater/remove/global-widget-prepare-update-repeater-remove.js": +/*!*************************************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/document/repeater/remove/global-widget-prepare-update-repeater-remove.js ***! + \*************************************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetPrepareUpdateRepeaterRemove = void 0; +var _baseGlobalWidgetPrepareUpdate = __webpack_require__(/*! ../../../base-global-widget-prepare-update */ "../modules/global-widget/assets/js/editor/hooks/data/base-global-widget-prepare-update.js"); +/** + * Hook is responsible for saving last changed global widget and update + * which containers are needed for updating the template. + */ + +class GlobalWidgetPrepareUpdateRepeaterRemove extends _baseGlobalWidgetPrepareUpdate.BaseGlobalWidgetPrepareUpdate { + getCommand() { + return 'document/repeater/remove'; + } + getId() { + return 'elementor-pro-global-widget-prepare-update-repeater-remove'; + } +} +exports.GlobalWidgetPrepareUpdateRepeaterRemove = GlobalWidgetPrepareUpdateRepeaterRemove; +var _default = exports["default"] = GlobalWidgetPrepareUpdateRepeaterRemove; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/document/save/save/global-widget-save-templates.js": +/*!***************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/document/save/save/global-widget-save-templates.js ***! + \***************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetSaveTemplates = void 0; +/** + * The hook is responsible for updating the global templates, on editor save, + * hook will run 'document/global/save-templates' to handle the save. + */ +class GlobalWidgetSaveTemplates extends $e.modules.hookData.After { + getCommand() { + return 'document/save/save'; + } + getId() { + return 'elementor-pro-global-widget-save-templates'; + } + getConditions(args) { + if (!Object.keys($e.components.get('document/global').changedContainersId).length) { + return false; + } + const { + document = elementor.documents.getCurrent() + } = args; + return document.config.panel.has_elements && args.status && -1 !== ['private', 'publish'].indexOf(args.status); + } + apply() { + $e.internal('document/global/save-templates'); + } +} +exports.GlobalWidgetSaveTemplates = GlobalWidgetSaveTemplates; +var _default = exports["default"] = GlobalWidgetSaveTemplates; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/editor/documents/attach-preview/global-widget-load-templates.js": +/*!****************************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/editor/documents/attach-preview/global-widget-load-templates.js ***! + \****************************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetLoadTemplates = void 0; +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +/** + * Hook responsible to load current active templates ( global widget that are in used ) to `$e.data.cache`, + * also it tells the component which templates are not active and required to be loaded from the backend. + */ +class GlobalWidgetLoadTemplates extends $e.modules.hookData.After { + /** + * Since the hook called on each document load, but requires to run only the initial attach preview. + * + * @type {boolean} + */ + static calledOnce = false; + initialize() { + // Since 'initialize' called before the component is registered. + // TODO: apply this logic at HookBase for '.initialize. + setTimeout(() => { + this.component = $e.components.get('document/global'); + }); + } + getCommand() { + return 'editor/documents/attach-preview'; + } + getId() { + return 'elementor-pro-global-widget-load-templates'; + } + getConditions() { + return !GlobalWidgetLoadTemplates.calledOnce; + } + apply() { + GlobalWidgetLoadTemplates.calledOnce = true; + Object.entries(elementorPro.config.widget_templates).forEach(([id, data]) => { + elementorPro.modules.globalWidget.addGlobalWidget(id, data); + this.addTemplateToCache(id); + }); + } + addTemplateToCache(id) { + const container = elementor.getPreviewContainer().children.findRecursive(i => parseInt(i.model.get('templateID')) === parseInt(id)); + if (!container) { + return this.component.notLoadedTemplatesIds.push(id); + } + const args = { + id: container.model.get('templateID'), + elType: 'widget', + widgetType: container.model.get('widgetType'), + settings: container.settings.toJSON({ + remove: 'default' + }), + templateID: container.model.get('templateID') + }; + $e.data.setCache(this.component, `document/global/global-widget/templates/${id}`, {}, args); + } +} +exports.GlobalWidgetLoadTemplates = GlobalWidgetLoadTemplates; +var _default = exports["default"] = GlobalWidgetLoadTemplates; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/data/index.js": +/*!*********************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/data/index.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "GlobalWidgetDoUpdate", ({ + enumerable: true, + get: function () { + return _globalWidgetDoUpdate.GlobalWidgetDoUpdate; + } +})); +Object.defineProperty(exports, "GlobalWidgetLoadTemplates", ({ + enumerable: true, + get: function () { + return _globalWidgetLoadTemplates.GlobalWidgetLoadTemplates; + } +})); +Object.defineProperty(exports, "GlobalWidgetPrepareUpdateElementSetSettings", ({ + enumerable: true, + get: function () { + return _globalWidgetPrepareUpdateElementSetSettings.GlobalWidgetPrepareUpdateElementSetSettings; + } +})); +Object.defineProperty(exports, "GlobalWidgetPrepareUpdateRepeaterInsert", ({ + enumerable: true, + get: function () { + return _globalWidgetPrepareUpdateRepeaterInsert.GlobalWidgetPrepareUpdateRepeaterInsert; + } +})); +Object.defineProperty(exports, "GlobalWidgetPrepareUpdateRepeaterRemove", ({ + enumerable: true, + get: function () { + return _globalWidgetPrepareUpdateRepeaterRemove.GlobalWidgetPrepareUpdateRepeaterRemove; + } +})); +Object.defineProperty(exports, "GlobalWidgetSaveTemplates", ({ + enumerable: true, + get: function () { + return _globalWidgetSaveTemplates.GlobalWidgetSaveTemplates; + } +})); +var _globalWidgetPrepareUpdateElementSetSettings = __webpack_require__(/*! ./document/elements/set-settings/global-widget-prepare-update-element-set-settings */ "../modules/global-widget/assets/js/editor/hooks/data/document/elements/set-settings/global-widget-prepare-update-element-set-settings.js"); +var _globalWidgetPrepareUpdateRepeaterInsert = __webpack_require__(/*! ./document/repeater/insert/global-widget-prepare-update-repeater-insert */ "../modules/global-widget/assets/js/editor/hooks/data/document/repeater/insert/global-widget-prepare-update-repeater-insert.js"); +var _globalWidgetPrepareUpdateRepeaterRemove = __webpack_require__(/*! ./document/repeater/remove/global-widget-prepare-update-repeater-remove */ "../modules/global-widget/assets/js/editor/hooks/data/document/repeater/remove/global-widget-prepare-update-repeater-remove.js"); +var _globalWidgetDoUpdate = __webpack_require__(/*! ./document/history/end-log/global-widget-do-update */ "../modules/global-widget/assets/js/editor/hooks/data/document/history/end-log/global-widget-do-update.js"); +var _globalWidgetSaveTemplates = __webpack_require__(/*! ./document/save/save/global-widget-save-templates */ "../modules/global-widget/assets/js/editor/hooks/data/document/save/save/global-widget-save-templates.js"); +var _globalWidgetLoadTemplates = __webpack_require__(/*! ./editor/documents/attach-preview/global-widget-load-templates */ "../modules/global-widget/assets/js/editor/hooks/data/editor/documents/attach-preview/global-widget-load-templates.js"); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/index.js": +/*!****************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/index.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data/ */ "../modules/global-widget/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); +var _ui = __webpack_require__(/*! ./ui/ */ "../modules/global-widget/assets/js/editor/hooks/ui/index.js"); +Object.keys(_ui).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _ui[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _ui[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/ui/document/elements/set-settings/global-widget-history-update.js": +/*!*************************************************************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/ui/document/elements/set-settings/global-widget-history-update.js ***! + \*************************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.GlobalWidgetHistoryUpdate = void 0; +/** + * Since editing of global widget applies changes to the all widgets with the same template id, + * the same needs to be done on undo/redo. + */ +class GlobalWidgetHistoryUpdate extends $e.modules.hookUI.After { + getCommand() { + return 'document/elements/set-settings'; + } + getId() { + return 'elementor-pro-global-widget-history-update'; + } + getContainerType() { + return 'widget'; + } + getConditions(args) { + const { + containers = [args.container] + } = args; + return !elementor.documents.getCurrent().history.getActive() && containers.some(container => container.model.get('templateID')); + } + apply(args) { + const { + containers = [args.container] + } = args; + containers.forEach(container => $e.components.get('document/global').updateGlobalsRecursive(container)); + } +} +exports.GlobalWidgetHistoryUpdate = GlobalWidgetHistoryUpdate; +var _default = exports["default"] = GlobalWidgetHistoryUpdate; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/hooks/ui/index.js": +/*!*******************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/hooks/ui/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "GlobalWidgetHistoryUpdate", ({ + enumerable: true, + get: function () { + return _globalWidgetHistoryUpdate.GlobalWidgetHistoryUpdate; + } +})); +var _globalWidgetHistoryUpdate = __webpack_require__(/*! ./document/elements/set-settings/global-widget-history-update */ "../modules/global-widget/assets/js/editor/hooks/ui/document/elements/set-settings/global-widget-history-update.js"); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/module.js": +/*!***********************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/module.js ***! + \***********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/global-widget/assets/js/editor/component.js")); +class Module extends elementorModules.editor.utils.Module { + panelWidgets = new Backbone.Collection(); + addGlobalWidget(templateId, templateData) { + return this.panelWidgets.add(this.createGlobalModel(templateId, templateData)); + } + createGlobalModel(templateId, templateData) { + templateData = Object.assign({}, templateData, { + id: templateId, + categories: [], + icon: elementor.widgetsCache[templateData.widgetType].icon, + widgetType: templateData.widgetType, + custom: { + templateID: templateId + } + }); + const elementModel = new elementor.modules.elements.models.Element(templateData); + elementModel.set('id', templateId); + return elementModel; + } + setWidgetType() { + elementor.hooks.addFilter('element/view', function (DefaultView, model) { + if (model.get('templateID')) { + return (__webpack_require__(/*! ./widget/view */ "../modules/global-widget/assets/js/editor/widget/view.js")["default"]); + } + return DefaultView; + }); + elementor.hooks.addFilter('element/model', function (DefaultModel, attrs) { + if (attrs.templateID) { + return (__webpack_require__(/*! ./widget/model */ "../modules/global-widget/assets/js/editor/widget/model.js")["default"]); + } + return DefaultModel; + }); + } + registerTemplateType() { + elementor.templates.registerTemplateType('widget', { + showInLibrary: false, + saveDialog: { + title: __('Save your widget as a global widget', 'elementor-pro'), + description: __('You\'ll be able to add this global widget to multiple areas on your site, and edit it from one single place.', 'elementor-pro') + }, + prepareSavedData(data) { + data.widgetType = data.content[0].widgetType; + return data; + }, + ajaxParams: { + success: this.onWidgetTemplateSaved.bind(this) + } + }); + } + addPanelPage() { + elementor.getPanelView().addPage('globalWidget', { + view: __webpack_require__(/*! ./views/panel-page */ "../modules/global-widget/assets/js/editor/views/panel-page.js") + }); + } + + /** + * @param {string} id - The ID. + * @deprecated since 3.5.0, use `$e.data.getCache( `document/global/global-widget/templates/${ id }` )` instead. + */ + getGlobalModels(id) { + elementorDevTools.deprecation.deprecated('elementorPro.modules.globalWidget.getGlobalModels( id )', '3.5.0', '$e.data.getCache( `document/global/global-widget/templates/${ id }` )'); + return $e.data.getCache(this.component, `document/global/global-widget/templates/${id}`); + } + + /** + * @deprecated since 3.5.0, use `$e.internal( 'document/global/save-templates' )` instead. + */ + saveTemplates() { + elementorDevTools.deprecation.deprecated('elementorPro.modules.globalWidget.saveTemplates()', '3.5.0', "$e.internal( 'document/global/save-templates' )"); + $e.internal('document/global/save-templates'); + } + + /** + * @param {*} globalModel - global model. + * @param {Function} callback - A callback function. + * @deprecated since 3.5.0, use `$e.data.get( 'document/global/templates' )` instead. + */ + requestGlobalModelSettings(globalModel, callback) { + elementorDevTools.deprecation.deprecated('elementorPro.modules.globalWidget.requestGlobalModelSettings()', '3.5.0', "$e.data.get( 'document/global/templates' )"); + $e.data.get('document/global/templates', { + ids: globalModel.id + }).then(data => { + callback(data); + }); + } + setWidgetContextMenuSaveAction() { + elementor.hooks.addFilter('elements/widget/contextMenuGroups', (groups, widget) => { + const saveGroup = _.findWhere(groups, { + name: 'save' + }); + if (!saveGroup) { + return groups; + } + const saveAction = _.findWhere(saveGroup.actions, { + name: 'save' + }); + if (elementorPro.config.should_show_promotion) { + const iconLink = '' + ''; + saveAction.shortcut = jQuery(iconLink); + saveAction.isEnabled = () => false; + delete saveAction.callback; + return groups; + } + saveAction.callback = widget.save.bind(widget); + delete saveAction.shortcut; + return groups; + }); + } + filterRegionViews(regionViews) { + if (elementorPro.config.should_show_promotion) { + _.extend(regionViews.global, { + view: __webpack_require__(/*! ./views/promotion */ "../modules/global-widget/assets/js/editor/views/promotion.js"), + options: {} + }); + return regionViews; + } + _.extend(regionViews.global, { + view: __webpack_require__(/*! ./views/global-templates-view */ "../modules/global-widget/assets/js/editor/views/global-templates-view.js"), + options: { + collection: this.panelWidgets + } + }); + return regionViews; + } + onElementorInit() { + elementor.on('panel:init', () => { + elementor.hooks.addFilter('panel/elements/regionViews', this.filterRegionViews.bind(this)); + }); + this.registerTemplateType(); + this.setWidgetContextMenuSaveAction(); + this.setWidgetType(); + } + onElementorInitComponents() { + $e.components.register(new _component.default()); + $e.data.get('document/global/templates', {}, { + refresh: true + }); + } + onElementorPreviewLoaded(isFirst) { + if (!isFirst) { + return; + } + this.addPanelPage(); + $e.routes.register('panel/editor', 'global', args => { + elementor.getPanelView().setPage('globalWidget', 'Global Editing', { + editedView: args.view + }); + }); + } + onWidgetTemplateSaved(data) { + elementor.templates.layout.hideModal(); + const container = elementor.getContainer(elementor.templates.layout.modalContent.currentView.model.id); + $e.run('document/global/link', { + container, + data + }); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/views/global-templates-view.js": +/*!********************************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/views/global-templates-view.js ***! + \********************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = elementor.modules.layouts.panel.pages.elements.views.Elements.extend({ + id: 'elementor-global-templates', + getEmptyView() { + if (this.collection.length) { + return null; + } + return __webpack_require__(/*! ./no-templates */ "../modules/global-widget/assets/js/editor/views/no-templates.js"); + }, + onFilterEmpty() {} +}); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/views/no-templates.js": +/*!***********************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/views/no-templates.js ***! + \***********************************************************************/ +/***/ ((module) => { + +"use strict"; + + +var GlobalWidgetsView = elementor.modules.layouts.panel.pages.elements.views.Global; +module.exports = GlobalWidgetsView.extend({ + template: '#tmpl-elementor-panel-global-widget-no-templates', + id: 'elementor-panel-global-widget-no-templates', + className: 'elementor-nerd-box elementor-panel-nerd-box e-responsive-panel-stretch' +}); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/views/panel-page.js": +/*!*********************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/views/panel-page.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +module.exports = Marionette.ItemView.extend({ + id: 'elementor-panel-global-widget', + template: '#tmpl-elementor-panel-global-widget', + ui: { + editButton: '#elementor-global-widget-locked-edit .elementor-button', + unlinkButton: '#elementor-global-widget-locked-unlink .elementor-button', + loading: '#elementor-global-widget-loading' + }, + events: { + 'click @ui.editButton': 'onEditButtonClick', + 'click @ui.unlinkButton': 'onUnlinkButtonClick' + }, + initialize() { + this.initUnlinkDialog(); + }, + buildUnlinkDialog() { + var self = this; + return elementorCommon.dialogsManager.createWidget('confirm', { + id: 'elementor-global-widget-unlink-dialog', + headerMessage: __('Unlink Widget', 'elementor-pro'), + message: __('This will make the widget stop being global. It\'ll be reverted into being just a regular widget.', 'elementor-pro'), + position: { + my: 'center center', + at: 'center center' + }, + strings: { + confirm: __('Unlink', 'elementor-pro'), + cancel: __('Cancel', 'elementor-pro') + }, + onConfirm() { + self.getOption('editedView').unlink(); + } + }); + }, + initUnlinkDialog() { + var dialog; + this.getUnlinkDialog = function () { + if (!dialog) { + dialog = this.buildUnlinkDialog(); + } + return dialog; + }; + }, + editGlobalModel() { + var editedView = this.getOption('editedView'); + $e.run('document/elements/select', { + container: editedView.getContainer() + }); + }, + onEditButtonClick() { + this.editGlobalModel(); + }, + onUnlinkButtonClick() { + this.getUnlinkDialog().show(); + } +}); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/views/promotion.js": +/*!********************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/views/promotion.js ***! + \********************************************************************/ +/***/ ((module) => { + +"use strict"; + + +var GlobalWidgetsView = elementor.modules.layouts.panel.pages.elements.views.Global; +module.exports = GlobalWidgetsView.extend({ + template: '#tmpl-elementor-promotion', + id: 'tmpl-elementor-promotion', + className: 'elementor-nerd-box elementor-panel-nerd-box e-responsive-panel-stretch' +}); + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/widget/model.js": +/*!*****************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/widget/model.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +const ElementModel = elementor.modules.elements.models.Element; +class Model extends ElementModel { + initSettings() { + // If global widget is created, the settings should come from recent template. + // The widget that's hold the panel may not have the recent data, the template can be changed during the editing. + if ($e.commands.is('document/elements/create')) { + return this.initSettingsFromTemplate(); + } + super.initSettings(); + } + initEditSettings() { + super.initEditSettings(); + + // Set default edit tab. + this.get('editSettings').set('editTab', 'global'); + } + initSettingsFromTemplate() { + const id = this.get('templateID'), + component = $e.components.get('document/global'), + data = $e.data.getCache(component, `document/global/global-widget/templates/${id}`) || this.attributes, + elementModel = elementorPro.modules.globalWidget.createGlobalModel(id, data); + this.set('settings', elementModel.get('settings')); + elementorFrontend.config.elements.data[this.cid] = this.get('settings'); + } +} +exports["default"] = Model; + +/***/ }), + +/***/ "../modules/global-widget/assets/js/editor/widget/view.js": +/*!****************************************************************!*\ + !*** ../modules/global-widget/assets/js/editor/widget/view.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +const WidgetView = elementor.modules.elements.views.Widget; +class View extends WidgetView { + className() { + return super.className() + ' elementor-global-widget elementor-global-' + this.model.get('templateID'); + } + addInlineEditingAttributes() { + // See `this.removeInlineAddingAttributes` for more information. + } + unlink() { + $e.run('document/global/unlink', { + container: this.getContainer() + }); + } + onEditRequest() { + $e.route('panel/editor/global', { + view: this + }); + } + getContextMenuGroups() { + // Remove 'Save as global' for global widget view. + return super.getContextMenuGroups().filter(group => 'save' !== group.name); + } + getContainer() { + if (this.container) { + return this.container; + } + const container = super.getContainer(); + container.label = container.label + ' (' + __('global', 'elementor-pro') + ')'; + return container; + } + render() { + super.render(); + setTimeout(this.removeInlineAddingAttributes.bind(this)); + } + + /** + * The issue is complex: + * 1. There is a mechanism in the editor which responsible for adding inline the method below: `addInlineEditingAttributes`. + * 2. There is a mechanism in the backend that adds inline attributes for each widget most of the time. + * its effect also the Global-Widget itself, in two ways: + * 1. global-widget instance is calling to `$this->get_original_element_instance()->render_content();`. + * It means that the mechanism in the backend with adds the inline attributes will be triggered. + * 2. each time you 'leave the editing mode' for most of the widgets it triggers `renderRemoteServer()`, + * which sends a request for `remoteRendering` for 'non-global widget' (the server doesn't know that it + * was linked to a template), that will trigger the original widget without knowing it's a part of the + * global mechanism. + * eventually it will trigger the logic of the backend for adding the inline attributes. + */ + removeInlineAddingAttributes() { + const globalWidgetElementDom = this.el.querySelector('.elementor-inline-editing'); + if (globalWidgetElementDom) { + globalWidgetElementDom.classList.remove('elementor-inline-editing'); + } + } +} +exports["default"] = View; + +/***/ }), + +/***/ "../modules/library/assets/js/editor.js": +/*!**********************************************!*\ + !*** ../modules/library/assets/js/editor.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + onElementorPreviewLoaded() { + var EditButton = __webpack_require__(/*! ./editor/edit-button */ "../modules/library/assets/js/editor/edit-button.js"); + this.editButton = new EditButton(); + } +}); + +/***/ }), + +/***/ "../modules/library/assets/js/editor/edit-button.js": +/*!**********************************************************!*\ + !*** ../modules/library/assets/js/editor/edit-button.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +module.exports = function () { + var self = this; + self.onPanelShow = function (panel) { + var model = panel.content.currentView.collection.findWhere({ + name: 'template_id' + }); + self.templateIdView = panel.content.currentView.children.findByModelCid(model.cid); + + // Change Edit link on render & on change template. + self.templateIdView.elementSettingsModel.on('change', self.onTemplateIdChange); + self.templateIdView.on('render', self.onTemplateIdChange); + }; + self.onTemplateIdChange = function () { + var templateID = self.templateIdView.elementSettingsModel.get('template_id'), + $editButton = self.templateIdView.$el.find('.elementor-edit-template'); + if (!templateID) { + $editButton.remove(); + return; + } + var editUrl = ElementorConfig.home_url + '?p=' + templateID + '&elementor'; + if ($editButton.length) { + $editButton.prop('href', editUrl); + } else { + $editButton = jQuery('', { + target: '_blank', + class: 'elementor-button elementor-edit-template', + href: editUrl, + html: '' + __('Edit Template', 'elementor-pro') + }); + self.templateIdView.$el.find('.elementor-control-input-wrapper').after($editButton); + } + }; + self.init = function () { + elementor.hooks.addAction('panel/open_editor/widget/template', self.onPanelShow); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/behavior.js": +/*!************************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/behavior.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class LoopBuilderBehavior extends Marionette.Behavior { + ui() { + return { + postSourceControlSelector: '[data-setting="post_taxonomy_query_post_type"]', + productSourceControlSelector: '[data-setting="product_taxonomy_query_post_type"]' + }; + } + events() { + return { + 'change @ui.postSourceControlSelector': 'onApplySourceChange', + 'change @ui.productSourceControlSelector': 'onApplySourceChange' + }; + } + onApplySourceChange(event) { + const sourceType = event.target?.value || this.getDefaultSourceType(); + this.getOption('updateTaxonomyTabsIdControls')(sourceType, true); + } + onRender() { + const postType = this.getOption('getSourceControlValue')(); + this.getOption('updateTaxonomyTabsIdControls')(postType); + } + getDefaultSourceType() { + const skinType = this.getOption('getSkinType')(); + return this.getOption('getDefaultSourceType')(skinType); + } +} +exports["default"] = LoopBuilderBehavior; + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/component.js": +/*!*************************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/component.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/loop-builder/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class LoopBuilderComponent extends $e.modules.ComponentBase { + getNamespace() { + return 'document/loop'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = LoopBuilderComponent; + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/hooks/index.js": +/*!***************************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/hooks/index.js ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "LoopBuilderAddLibraryTab", ({ + enumerable: true, + get: function () { + return _addLoopBuildersTab.LoopBuilderAddLibraryTab; + } +})); +Object.defineProperty(exports, "LoopBuilderRemoveLibraryTab", ({ + enumerable: true, + get: function () { + return _removeLoopBuildersTab.LoopBuilderRemoveLibraryTab; + } +})); +var _addLoopBuildersTab = __webpack_require__(/*! ./ui/editor/documents/open/add-loop-builders-tab */ "../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/open/add-loop-builders-tab.js"); +var _removeLoopBuildersTab = __webpack_require__(/*! ./ui/editor/documents/close/remove-loop-builders-tab */ "../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-loop-builders-tab.js"); + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-loop-builders-tab.js": +/*!************************************************************************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-loop-builders-tab.js ***! + \************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.LoopBuilderRemoveLibraryTab = void 0; +class LoopBuilderRemoveLibraryTab extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/unload'; + } + getId() { + return 'elementor-loop-items-remove-library-tab'; + } + getConditions(args) { + const { + document + } = args; + return 'loop-item' === document?.config?.type; + } + apply() { + $e.components.get('library').removeTab('templates/loop-items'); + $e.components.get('library').addTab('templates/blocks'); + $e.components.get('library').addTab('templates/pages'); + } +} +exports.LoopBuilderRemoveLibraryTab = LoopBuilderRemoveLibraryTab; +var _default = exports["default"] = LoopBuilderRemoveLibraryTab; + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/open/add-loop-builders-tab.js": +/*!********************************************************************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/hooks/ui/editor/documents/open/add-loop-builders-tab.js ***! + \********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.LoopBuilderAddLibraryTab = void 0; +class LoopBuilderAddLibraryTab extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/open'; + } + getId() { + return 'elementor-loop-items-add-library-tab'; + } + getConditions(args) { + const document = elementor.documents?.get(args.id); + return 'loop-item' === document?.config?.type; + } + apply() { + $e.components.get('library').addTab('templates/loop-items', { + title: __('Loop', 'elementor-pro'), + filter: { + source: 'remote', + type: 'lb', + subtype: elementor.config.document.settings.settings.source + } + }, 0); + $e.components.get('library').removeTab('templates/blocks'); + $e.components.get('library').removeTab('templates/pages'); + } +} +exports.LoopBuilderAddLibraryTab = LoopBuilderAddLibraryTab; +var _default = exports["default"] = LoopBuilderAddLibraryTab; + +/***/ }), + +/***/ "../modules/loop-builder/assets/js/editor/module.js": +/*!**********************************************************!*\ + !*** ../modules/loop-builder/assets/js/editor/module.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _documentHandle = _interopRequireWildcard(__webpack_require__(/*! elementor-pro/preview/utils/document-handle */ "../assets/dev/js/preview/utils/document-handle.js")); +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/loop-builder/assets/js/editor/component.js")); +var _behavior = _interopRequireDefault(__webpack_require__(/*! ./behavior */ "../modules/loop-builder/assets/js/editor/behavior.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class loopBuilderModule extends elementorModules.editor.utils.Module { + taxonomyQueryOptions = ['post_taxonomy', 'product_taxonomy']; + onElementorFrontendInit() { + elementor.hooks.addFilter('controls/base/behaviors', this.registerControlBehavior); + elementorFrontend.elements.$body.on('click', '.e-loop-empty-view__box-cta', () => { + this.createTemplate(); + }); + this.createDocumentSaveHandles(); + elementor.on('document:loaded', this.createDocumentSaveHandles.bind(this)); + } + registerControlBehavior = (behaviors = {}, view) => { + const taxonomyQueryOptions = ['post_taxonomy_query_post_type', 'product_taxonomy_query_post_type']; + if (!taxonomyQueryOptions.includes(view.options.model.get('name'))) { + return behaviors; + } + behaviors.loopBuilder = { + behaviorClass: _behavior.default, + getSourceControlValue: this.getSourceControlValue, + updateTaxonomyTabsIdControls: this.updateTaxonomyTabsIdControls + }; + return behaviors; + }; + createTemplate() { + setTimeout(() => { + elementor.getPanelView().getCurrentPageView().activateSection('section_layout')._renderChildren(); + this.getEditorControlView('template_id').createTemplate(); + }); + } + createDocumentSaveHandles() { + Object.entries(elementorFrontend.config?.elements?.data).forEach(([cid, element]) => { + const elementData = elementor.getElementData(element); + if (!elementData?.is_loop) { + return; + } + const templateId = element.attributes.template_id; + if (!templateId) { + return; + } + const widgetSelector = `.elementor-element[data-model-cid="${cid}"]`, + editHandleSelector = `[data-elementor-type="loop-item"].elementor-${templateId}`, + editHandleElement = elementorFrontend.elements.$body.find(`${widgetSelector} ${editHandleSelector}`).first()[0]; + if (editHandleElement) { + (0, _documentHandle.default)({ + element: editHandleElement, + id: 0, + title: '& Back' + }, _documentHandle.SAVE_CONTEXT, null, '.elementor-' + elementor.config.initial_document.id); + } + }); + } + onElementorLoaded() { + elementor.on('document:loaded', this.onDocumentLoaded.bind(this)); + elementor.on('document:unload', this.onDocumentUnloaded.bind(this)); + this.component = $e.components.register(new _component.default({ + manager: this + })); + } + onDocumentLoaded = document => { + if (!document.config.theme_builder) { + return; + } + elementor.channels.editor.on('elementorLoopBuilder:ApplySourceChange', this.onApplySourceChange); + }; + onDocumentUnloaded = document => { + if (!document.config.theme_builder) { + return; + } + elementor.channels.editor.off('elementorLoopBuilder:ApplySourceChange', this.onApplySourceChange); + }; + onApplySourceChange = () => { + this.saveAndRefresh().then(() => { + location.reload(); + }); + }; + async saveAndRefresh() { + await $e.run('document/save/update', { + force: true + }); + } + getCtaStyles = () => { + const ctaStyle = document.createElement('link'); + ctaStyle.setAttribute('rel', 'stylesheet'); + ctaStyle.setAttribute('href', `${elementorAppProConfig.baseUrl}/assets/css/modules/loop-grid-cta.min.css`); + return ctaStyle; + }; + getCtaContent = widgetName => { + const ctaContent = document.createElement('div'); + ctaContent.classList.add('e-loop-empty-view__container', 'elementor-grid', widgetName); + ctaContent.innerHTML = Marionette.Renderer.render('#tmpl-' + widgetName + '-cta'); + return ctaContent; + }; + getSourceControlValue = () => { + const skinType = this.getSkinType(), + controlView = this.getEditorControlView(`${skinType}_query_post_type`); + if (!controlView) { + return skinType.includes('product') ? 'product_cat' : 'category'; + } + return controlView.getControlValue(); + }; + getSkinType = () => { + const sectionLayout = this.getEditorControlView('section_layout'); + return sectionLayout.options.container.settings.get('_skin'); + }; + getTemplateType = templateKey => { + return templateKey.split('_')[0]; + }; + onApplySkinChange = () => { + const skinType = this.getSkinType(); + if (!this.taxonomyQueryOptions.includes(skinType)) { + return; + } + const postType = this.getDefaultSourceType(skinType); + this.updateTaxonomyTabsIdControls(postType, true); + }; + getDefaultSourceType = skinType => { + const defaultSourceTypes = { + post: 'post', + product: 'product', + post_taxonomy: 'category', + product_taxonomy: 'product_cat' + }; + return defaultSourceTypes[skinType]; + }; + updateTaxonomyTabsIdControls = (postType, shouldResetControlValues = false) => { + const skinType = this.getSkinType(); + if (!this.taxonomyQueryOptions.includes(skinType)) { + return; + } + const querySectionView = elementorPro.modules.loopBuilder.getEditorControlView('section_query'), + includeIds = querySectionView.model.collection.findWhere({ + name: `${skinType}_posts_ids` + }), + excludeIds = querySectionView.model.collection.findWhere({ + name: `${skinType}_exclude_ids` + }); + [includeIds, excludeIds].forEach(control => { + const controlView = elementor.getPanelView()?.getCurrentPageView()?.children?.findByModel(control); + this.updateControlQuery({ + control, + controlView, + postType, + shouldResetControlValues + }); + }); + }; + updateControlQuery = ({ + control, + controlView, + postType, + shouldResetControlValues + }) => { + control.set({ + autocomplete: { + object: 'tax', + query: { + taxonomy: postType + } + } + }); + if (controlView && shouldResetControlValues) { + controlView.setValue([]); + controlView.applySavedValue(); + } + }; +} +module.exports = loopBuilderModule; + +/***/ }), + +/***/ "../modules/motion-fx/assets/js/editor/editor.js": +/*!*******************************************************!*\ + !*** ../modules/motion-fx/assets/js/editor/editor.js ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.editor.utils.Module { + onElementorInit() { + elementor.on('navigator:init', this.onNavigatorInit.bind(this)); + } + onNavigatorInit() { + elementor.navigator.indicators.motionFX = { + icon: 'flash', + title: __('Motion Effects', 'elementor-pro'), + settingKeys: ['motion_fx_motion_fx_scrolling', 'motion_fx_motion_fx_mouse', 'background_motion_fx_motion_fx_scrolling', 'background_motion_fx_motion_fx_mouse'], + section: 'section_effects' + }; + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/notes/assets/js/notes-context-menu.js": +/*!********************************************************!*\ + !*** ../modules/notes/assets/js/notes-context-menu.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.notesContextMenu = exports["default"] = void 0; +class notesContextMenu { + constructor() { + const elTypes = ['widget', 'section', 'column', 'container']; + elTypes.forEach(type => { + elementor.hooks.addFilter(`elements/${type}/contextMenuGroups`, this.notesContextMenuAddGroup); + }); + } + + /** + * Enable the 'Notes' context menu item + * + * @since 3.8.0 + * + * @param {Array} groups + * @return {Array} The updated groups. + */ + notesContextMenuAddGroup(groups) { + const notesGroup = _.findWhere(groups, { + name: 'notes' + }), + notesGroupIndex = groups.indexOf(notesGroup), + notesActionItem = { + name: 'open_notes', + title: __('Notes', 'elementor-pro'), + shortcut: '⇧+C', + isEnabled: () => true, + callback: () => $e.route('notes') + }; + if (elementorPro.config.should_show_promotion) { + const iconLink = '' + ''; + notesActionItem.shortcut = jQuery(iconLink); + notesActionItem.isEnabled = () => false; + delete notesActionItem.callback; + } + + // Create the Notes group if it doesn't exist + if (-1 === notesGroupIndex) { + const deleteGroup = _.findWhere(groups, { + name: 'delete' + }), + deleteGroupIndex = groups.indexOf(deleteGroup), + newGroupPosition = -1 !== deleteGroupIndex ? deleteGroupIndex : groups.length; + groups.splice(newGroupPosition, 0, { + name: 'notes', + actions: [notesActionItem] + }); + return groups; + } + const openNotesAction = _.findWhere(notesGroup.actions, { + name: 'open_notes' + }), + openNotesActionIndex = notesGroup.actions.indexOf(openNotesAction); + groups[notesGroupIndex].actions[openNotesActionIndex] = notesActionItem; + return groups; + } +} +exports.notesContextMenu = notesContextMenu; +var _default = exports["default"] = notesContextMenu; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/commands/animate.js": +/*!************************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/commands/animate.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.Animate = void 0; +class Animate extends $e.modules.CommandBase { + /** + * Animate the Page Transition element. + * + * @return {void} + */ + apply() { + const pageTransition = elementor.$previewContents[0].querySelector('e-page-transition'); + if (!pageTransition) { + return; + } + pageTransition.animate(); + } +} +exports.Animate = Animate; +var _default = exports["default"] = Animate; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/commands/index.js": +/*!**********************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/commands/index.js ***! + \**********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "Animate", ({ + enumerable: true, + get: function () { + return _animate.Animate; + } +})); +var _animate = __webpack_require__(/*! ./animate */ "../modules/page-transitions/assets/js/editor/commands/animate.js"); + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/component.js": +/*!*****************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/component.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var commands = _interopRequireWildcard(__webpack_require__(/*! ./commands/ */ "../modules/page-transitions/assets/js/editor/commands/index.js")); +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/page-transitions/assets/js/editor/hooks/index.js")); +var _pageTransitionPreview = _interopRequireDefault(__webpack_require__(/*! ./hooks/routes/page-transition-preview */ "../modules/page-transitions/assets/js/editor/hooks/routes/page-transition-preview.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + /** + * Initialize the component. + * + * @return {void} + */ + constructor() { + super(); + this.routesHooks = {}; + this.initRouteHooks(); + } + + /** + * Add route hooks & listen to route changes. + * + * @return {void} + */ + initRouteHooks() { + // TODO: Remove when route hooks are available. + this.routesHooks.pageTransitionPreview = new _pageTransitionPreview.default(); + $e.routes.on('run:after', (component, route) => { + this.routesHooks.pageTransitionPreview.run(component, route); + }); + } + + /** + * Get the component namespace. + * + * @return {string} - Component namespace. + */ + getNamespace() { + return 'page-transitions'; + } + + /** + * Get the component hooks. + * + * @return {Object} - Component hooks. + */ + defaultHooks() { + return this.importHooks(hooks); + } + + /** + * Get the component commands. + * + * @return {Object} - Component commands. + */ + defaultCommands() { + return this.importCommands(commands); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/data/animate-page-transition.js": +/*!******************************************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/data/animate-page-transition.js ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.AnimatePageTransition = void 0; +/** + * Data hook that animates the Page Transition component when entrance / exit animations are changed. + */ +class AnimatePageTransition extends $e.modules.hookData.After { + // Page Transitions settings prefix. + prefix = 'settings_page_transitions_'; + + // Controls that the hook should listen to. + settings = ['entrance_animation', 'exit_animation']; + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'animate-page-transitions--document/elements/settings'; + } + getContainerType() { + return 'document'; + } + getConditions(args) { + // Execute only for specific settings. + return Object.keys(args.settings).some(key => { + key = key.replace(this.prefix, ''); + return this.settings.includes(key); + }); + } + apply() { + $e.run('page-transitions/animate'); + } +} +exports.AnimatePageTransition = AnimatePageTransition; +var _default = exports["default"] = AnimatePageTransition; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/data/index.js": +/*!************************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/data/index.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "AnimatePageTransition", ({ + enumerable: true, + get: function () { + return _animatePageTransition.AnimatePageTransition; + } +})); +Object.defineProperty(exports, "ReRenderPageTransition", ({ + enumerable: true, + get: function () { + return _reRenderPageTransition.ReRenderPageTransition; + } +})); +var _animatePageTransition = __webpack_require__(/*! ./animate-page-transition */ "../modules/page-transitions/assets/js/editor/hooks/data/animate-page-transition.js"); +var _reRenderPageTransition = __webpack_require__(/*! ./re-render-page-transition */ "../modules/page-transitions/assets/js/editor/hooks/data/re-render-page-transition.js"); + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/data/re-render-page-transition.js": +/*!********************************************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/data/re-render-page-transition.js ***! + \********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ReRenderPageTransition = void 0; +var _utils = __webpack_require__(/*! ../utils */ "../modules/page-transitions/assets/js/editor/hooks/utils.js"); +/** + * Data hook that passes the new settings from the panel as attributes to the Page Transition component, in order to re-render it. + */ +class ReRenderPageTransition extends $e.modules.hookData.After { + // Page Transitions settings prefix. + prefix = 'settings_page_transitions_'; + + // Controls that the hook should listen to. + settings = ['entrance_animation', 'preloader_type', 'preloader_icon', 'preloader_image', 'preloader_animation_type']; + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 're-render-page-transitions--document/elements/settings'; + } + getContainerType() { + return 'document'; + } + getConditions(args) { + // Execute only for specific settings. + return Object.keys(args.settings).some(key => { + key = key.replace(this.prefix, ''); + return this.settings.includes(key); + }); + } + apply(args) { + (0, _utils.renderPageTransition)(args.container); + } +} +exports.ReRenderPageTransition = ReRenderPageTransition; +var _default = exports["default"] = ReRenderPageTransition; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/index.js": +/*!*******************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data */ "../modules/page-transitions/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/routes/page-transition-preview.js": +/*!********************************************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/routes/page-transition-preview.js ***! + \********************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _utils = __webpack_require__(/*! ../utils */ "../modules/page-transitions/assets/js/editor/hooks/utils.js"); +/** + * A route hook that listens to route changes in the panel and change the preview mode for + * the Page Transitions feature when navigating to the `Site Settings -> Page Transitions` tab. + * + * TODO: Convert to `$e.modules.hookRoute.After` when available. + */ +class PageTransitionPreview { + /** + * Run the hook. + * + * @param {Object} component + * @param {string} route + * + * @return {void} + */ + run(component, route) { + if ('panel/global/settings-page-transitions' === route) { + (0, _utils.renderPageTransition)(elementor.documents.getCurrent().container); + this.togglePageTransitionPreview(true); + } else { + this.togglePageTransitionPreview(false); + } + } + + /** + * Toggle the Page Transition state to show or hide preview. + * + * @param {boolean} on + * + * @return {void} + */ + togglePageTransitionPreview(on = true) { + const className = 'e-page-transition--preview', + pageTransition = elementor.$previewContents[0].body.querySelector('e-page-transition'); + if (!pageTransition) { + return; + } + pageTransition.classList.toggle(className, on); + } +} +exports["default"] = PageTransitionPreview; + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/hooks/utils.js": +/*!*******************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/hooks/utils.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getPageTransitionSettings = getPageTransitionSettings; +exports.renderPageTransition = renderPageTransition; +const prefix = 'settings_page_transitions_'; + +/** + * Get only the Page Transitions controls' values from a Container. + * + * @param {Object} container + * + * @return {Object} - Controls' values. + */ +function getPageTransitionSettings(container) { + // Filter only the Page Transitions controls which doesn't change CSS values. + // (since they shouldn't affect the render) + const controls = Object.entries(container.settings.getActiveControls()).filter(([key, control]) => { + return key.startsWith(prefix) && !control.selectors; + }); + const settings = {}; + controls.forEach(([control]) => { + settings[control] = container.settings.get(control); + }); + return settings; +} + +/** + * Live render the Page Transition element, based on settings from the user. + * + * @param {Object} container - The container to get the settings from. + * + * @return {void} + */ +function renderPageTransition(container) { + let pageTransition = elementor.$previewContents[0].querySelector('e-page-transition'); + const hasEntranceAnimation = !!container.settings.get(`${prefix}entrance_animation`), + hasPreloader = !!container.settings.get(`${prefix}preloader_type`), + shouldRender = hasEntranceAnimation || hasPreloader; + + // Create the Page Transition element if it doesn't exist. + if (!pageTransition) { + pageTransition = document.createElement('e-page-transition'); + pageTransition.classList.add('e-page-transition--preview'); + elementor.$previewContents[0].body.append(pageTransition); + } + + // Disable the Page Transition if needed. + pageTransition.toggleAttribute('disabled', !shouldRender); + const settings = getPageTransitionSettings(container); + + // Iterate over the settings and set them as attributes. + Object.entries(settings).forEach(([key, value]) => { + key = key.replace(prefix, ''); + key = key.replaceAll('_', '-'); + if (!value) { + pageTransition.removeAttribute(key); + return; + } + if ('string' === typeof value) { + pageTransition.setAttribute(key, value); + return; + } + + // For object values (e.g. image control). + Object.entries(value).forEach(([subKey, subValue]) => { + let newKey = key; + + // Append the sub key only if it's not `value` (e.g. `url`), in order to avoid weird + // attributes like `preloader-icon-value`. + if (subKey !== 'value') { + newKey = `${key}-${subKey}`; + } + pageTransition.setAttribute(newKey, subValue); + }); + }); +} + +/***/ }), + +/***/ "../modules/page-transitions/assets/js/editor/module.js": +/*!**************************************************************!*\ + !*** ../modules/page-transitions/assets/js/editor/module.js ***! + \**************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/page-transitions/assets/js/editor/component.js")); +class _default extends elementorModules.editor.utils.Module { + /** + * Register the component & bind events on init. + * + * @return {void} + */ + onInit() { + $e.components.register(new _component.default()); + this.bindEvents(); + } + + /** + * Listen to Page Transition event. + * + * @return {void} + */ + bindEvents() { + // Make sure that `window.elementor` is initialized. + // TODO: Find a better solution. It's caused because of the dynamic import. + if (window.elementor) { + this.onAnimateButtonClick(); + return; + } + jQuery(window).on('elementor:init', () => this.onAnimateButtonClick()); + } + + /** + * Listen to `animate` button click event and animate the Page Transition. + * + * @return {void} + */ + onAnimateButtonClick() { + elementor.channels.editor.on('elementorPageTransitions:animate', () => { + $e.run('page-transitions/animate'); + }); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/payments/assets/js/editor/module.js": +/*!******************************************************!*\ + !*** ../modules/payments/assets/js/editor/module.js ***! + \******************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _stripe = _interopRequireDefault(__webpack_require__(/*! ./stripe */ "../modules/payments/assets/js/editor/stripe.js")); +class StripeModule extends elementorModules.editor.utils.Module { + onElementorInit() { + this.stripeButton = new _stripe.default('stripe-button'); + } +} +exports["default"] = StripeModule; + +/***/ }), + +/***/ "../modules/payments/assets/js/editor/stripe.js": +/*!******************************************************!*\ + !*** ../modules/payments/assets/js/editor/stripe.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +const ElementEditorModule = __webpack_require__(/*! elementor-pro/editor/element-editor-module */ "../assets/dev/js/editor/element-editor-module.js"); +module.exports = ElementEditorModule.extend({ + __construct() { + ElementEditorModule.prototype.__construct.apply(this, arguments); + }, + getName() { + return 'stripe-button'; + }, + onInit() { + elementor.channels.editor.on('editor:widget:stripe-button:section_stripe_account:activated', this.onSectionActive); + }, + onSectionActive() { + return elementorPro.ajax.addRequest('get_stripe_tax_rates', { + success: data => { + this.updateOptions('stripe_test_env_tax_rates_list', data.test_api_key); + this.updateOptions('stripe_live_env_tax_rates_list', data.live_api_key); + } + }, true); + } +}); + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/component.js": +/*!******************************************************!*\ + !*** ../modules/popup/assets/js/editor/component.js ***! + \******************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/popup/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class PopupComponent extends $e.modules.ComponentBase { + /** + * @type {null|Function} + */ + onPageSettingsCloseHandler = null; + getNamespace() { + return 'document/popup'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = PopupComponent; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/controls/display-settings.js": +/*!**********************************************************************!*\ + !*** ../modules/popup/assets/js/editor/controls/display-settings.js ***! + \**********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.editor.views.ControlsStack { + constructor(...args) { + super(...args); + this.template = _.noop; + this.activeTab = 'content'; + this.listenTo(this.model, 'change', this.onModelChange); + } + getNamespaceArray() { + return ['popup', 'display-settings']; + } + className() { + return super.className() + ' elementor-popup__display-settings'; + } + toggleGroup(groupName, $groupElement) { + $groupElement.toggleClass('elementor-active', !!this.model.get(groupName)); + } + onRenderTemplate() { + this.activateFirstSection(); + } + onRender() { + const name = this.getOption('name'); + let $groupWrapper; + this.children.each(child => { + const type = child.model.get('type'); + if ('heading' !== type) { + if ($groupWrapper) { + $groupWrapper.append(child.$el); + } + return; + } + const groupName = child.model.get('name').replace('_heading', ''); + $groupWrapper = jQuery('
    ', { + id: `elementor-popup__${name}-controls-group--${groupName}`, + class: 'elementor-popup__display-settings_controls_group' + }); + const $imageWrapper = jQuery('
    ', { + class: 'elementor-popup__display-settings_controls_group__icon' + }), + $image = jQuery('', { + src: elementorPro.config.urls.modules + `popup/assets/images/${name}/${groupName}.svg` + }); + $imageWrapper.html($image); + $groupWrapper.html($imageWrapper); + child.$el.before($groupWrapper); + $groupWrapper.append(child.$el); + this.toggleGroup(groupName, $groupWrapper); + }); + } + onModelChange() { + const changedControlName = Object.keys(this.model.changed)[0], + changedControlView = this.getControlViewByName(changedControlName); + if ('switcher' !== changedControlView.model.get('type')) { + return; + } + this.toggleGroup(changedControlName, changedControlView.$el.parent()); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/data/index.js": +/*!*************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/data/index.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "PopupSave", ({ + enumerable: true, + get: function () { + return _save.PopupSave; + } +})); +var _save = __webpack_require__(/*! ./save */ "../modules/popup/assets/js/editor/hooks/data/save.js"); + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/data/save.js": +/*!************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/data/save.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.PopupSave = void 0; +class PopupSave extends $e.modules.hookData.After { + getCommand() { + return 'document/save/save'; + } + getId() { + return 'elementor-pro-popup-save'; + } + getConditions() { + return 'popup' === elementor.config.document.type; + } + apply() { + const settings = {}; + jQuery.each(elementorPro.modules.popup.displaySettingsTypes, (type, data) => { + settings[type] = data.model.toJSON({ + remove: ['default'] + }); + }); + elementorPro.ajax.addRequest('popup_save_display_settings', { + data: { + settings + } + }); + } +} +exports.PopupSave = PopupSave; +var _default = exports["default"] = PopupSave; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/index.js": +/*!********************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/index.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data/ */ "../modules/popup/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); +var _ui = __webpack_require__(/*! ./ui/ */ "../modules/popup/assets/js/editor/hooks/ui/index.js"); +Object.keys(_ui).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _ui[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _ui[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-library-tab.js": +/*!***********************************************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-library-tab.js ***! + \***********************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.PopupRemoveLibraryTab = void 0; +class PopupRemoveLibraryTab extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/unload'; + } + getId() { + return 'elementor-pro-popup-remove-library-tab'; + } + getConditions(args) { + const { + document + } = args; + return 'popup' === document.config.type; + } + apply() { + $e.components.get('library').removeTab('templates/popups'); + } +} +exports.PopupRemoveLibraryTab = PopupRemoveLibraryTab; +var _default = exports["default"] = PopupRemoveLibraryTab; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-triggers.js": +/*!********************************************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-triggers.js ***! + \********************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.PopupRemoveTriggers = void 0; +class PopupRemoveTriggers extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/unload'; + } + getId() { + return 'elementor-pro-popup-remove-triggers'; + } + getConditions(args) { + const { + document + } = args; + return 'popup' === document.config.type; + } + apply() { + this.removePanelFooterSubmenuItems(); + this.removePublishTabs(); + } + removePanelFooterSubmenuItems() { + const displaySettingsTypes = elementorPro.modules.popup.displaySettingsTypes; + jQuery.each(displaySettingsTypes, type => { + elementor.getPanelView().footer.currentView.removeSubMenuItem('saver-options', { + name: type + }); + }); + } + removePublishTabs() { + const component = $e.components.get('theme-builder-publish'), + displaySettingsTypes = elementorPro.modules.popup.displaySettingsTypes; + jQuery.each(displaySettingsTypes, type => { + component.removeTab(type); + }); + } +} +exports.PopupRemoveTriggers = PopupRemoveTriggers; +var _default = exports["default"] = PopupRemoveTriggers; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-library-tab.js": +/*!*******************************************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-library-tab.js ***! + \*******************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.PopupAddLibraryTab = void 0; +class PopupAddLibraryTab extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/open'; + } + getId() { + return 'elementor-pro-popup-add-library-tab'; + } + getConditions(args) { + const document = elementor.documents.get(args.id); + return 'popup' === document.config.type; + } + apply() { + $e.components.get('library').addTab('templates/popups', { + title: __('Popups', 'elementor-pro'), + filter: { + source: 'remote', + type: 'popup' + } + }, 1); + } +} +exports.PopupAddLibraryTab = PopupAddLibraryTab; +var _default = exports["default"] = PopupAddLibraryTab; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-triggers.js": +/*!****************************************************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-triggers.js ***! + \****************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.PopupAddTriggers = void 0; +var _displaySettings = _interopRequireDefault(__webpack_require__(/*! modules/popup/assets/js/editor/controls/display-settings */ "../modules/popup/assets/js/editor/controls/display-settings.js")); +class PopupAddTriggers extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/open'; + } + getId() { + return 'elementor-pro-popup-add-triggers'; + } + getConditions(args) { + const document = elementor.documents.get(args.id); + return 'popup' === document.config.type; + } + apply() { + if (elementor.panel) { + this.addUI(); + } else { + // First open, the panel is not available yet. + elementor.once('preview:loaded', this.addUI.bind(this)); + } + } + addUI() { + // Since 'addUI' can be called each document load, if 'theme-builder-publish/triggers' exists, the UI already exist. + if ($e.routes.commands['theme-builder-publish/triggers']) { + return; + } + this.addPanelFooterSubmenuItems(); + this.addPublishTabs(); + } + addPublishTabs() { + const config = elementor.config.document.displaySettings, + component = $e.components.get('theme-builder-publish'), + module = elementorPro.modules.popup; + jQuery.each(module.displaySettingsTypes, (type, data) => { + // Init models for editor save. + data.model = new elementorModules.editor.elements.models.BaseSettings(config[type].settings, { + controls: config[type].controls + }); + component.addTab(type, { + View: _displaySettings.default, + viewOptions: { + name: type, + id: `elementor-popup-${type}__controls`, + model: data.model, + controls: data.model.controls + }, + name: type, + title: data.title, + description: data.publishScreenDescription, + image: elementorPro.config.urls.modules + `popup/assets/images/${type}-tab.svg` + }); + }); + } + addPanelFooterSubmenuItems() { + const component = $e.components.get('theme-builder-publish'), + displaySettingsTypes = elementorPro.modules.popup.displaySettingsTypes; + jQuery.each(displaySettingsTypes, (type, data) => { + elementor.getPanelView().footer.currentView.addSubMenuItem('saver-options', { + before: 'save-template', + name: type, + icon: data.icon, + title: data.title, + callback: () => $e.route(component.getTabRoute(type)) + }); + }); + } +} +exports.PopupAddTriggers = PopupAddTriggers; +var _default = exports["default"] = PopupAddTriggers; + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/hooks/ui/index.js": +/*!***********************************************************!*\ + !*** ../modules/popup/assets/js/editor/hooks/ui/index.js ***! + \***********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "PopupAddLibraryTab", ({ + enumerable: true, + get: function () { + return _addLibraryTab.PopupAddLibraryTab; + } +})); +Object.defineProperty(exports, "PopupAddTriggers", ({ + enumerable: true, + get: function () { + return _addTriggers.PopupAddTriggers; + } +})); +Object.defineProperty(exports, "PopupRemoveLibraryTab", ({ + enumerable: true, + get: function () { + return _removeLibraryTab.PopupRemoveLibraryTab; + } +})); +Object.defineProperty(exports, "PopupRemoveTriggers", ({ + enumerable: true, + get: function () { + return _removeTriggers.PopupRemoveTriggers; + } +})); +var _addLibraryTab = __webpack_require__(/*! ./editor/documents/open/add-library-tab */ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-library-tab.js"); +var _addTriggers = __webpack_require__(/*! ./editor/documents/open/add-triggers */ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/open/add-triggers.js"); +var _removeLibraryTab = __webpack_require__(/*! ./editor/documents/close/remove-library-tab */ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-library-tab.js"); +var _removeTriggers = __webpack_require__(/*! ./editor/documents/close/remove-triggers */ "../modules/popup/assets/js/editor/hooks/ui/editor/documents/close/remove-triggers.js"); + +/***/ }), + +/***/ "../modules/popup/assets/js/editor/module.js": +/*!***************************************************!*\ + !*** ../modules/popup/assets/js/editor/module.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/popup/assets/js/editor/component.js")); +class PopupModule extends elementorModules.editor.utils.Module { + constructor(...args) { + super(...args); + this.displaySettingsTypes = { + triggers: { + icon: 'eicon-click', + title: __('Triggers', 'elementor-pro'), + publishScreenDescription: __('What action the user needs to do for the popup to open.', 'elementor-pro') + }, + timing: { + icon: 'eicon-cog', + title: __('Advanced Rules', 'elementor-pro'), + publishScreenDescription: __('Requirements that have to be met for the popup to open.', 'elementor-pro') + } + }; + } + onElementorLoaded() { + this.component = $e.components.register(new _component.default({ + manager: this + })); + } +} +module.exports = PopupModule; + +/***/ }), + +/***/ "../modules/query-control/assets/js/editor.js": +/*!****************************************************!*\ + !*** ../modules/query-control/assets/js/editor.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + onElementorPreviewLoaded() { + elementor.addControlView('Query', __webpack_require__(/*! ./editor/query-control */ "../modules/query-control/assets/js/editor/query-control.js")); + __webpack_require__.e(/*! import() */ "modules_query-control_assets_js_editor_template-query-control_js").then(__webpack_require__.bind(__webpack_require__, /*! ./editor/template-query-control */ "../modules/query-control/assets/js/editor/template-query-control.js")).then(({ + default: TemplateQueryControl + }) => elementor.addControlView('template_query', TemplateQueryControl)); + } +}); + +/***/ }), + +/***/ "../modules/query-control/assets/js/editor/query-control.js": +/*!******************************************************************!*\ + !*** ../modules/query-control/assets/js/editor/query-control.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +module.exports = elementor.modules.controls.Select2.extend({ + cache: null, + isTitlesReceived: false, + getSelect2Placeholder() { + return { + id: '', + text: __('All', 'elementor-pro') + }; + }, + getControlValueByName(controlName) { + const name = this.model.get('group_prefix') + controlName; + return this.elementSettingsModel.attributes[name]; + }, + getQueryDataDeprecated() { + return { + filter_type: this.model.get('filter_type'), + object_type: this.model.get('object_type'), + include_type: this.model.get('include_type'), + query: this.model.get('query') + }; + }, + getQueryData() { + // Use a clone to keep model data unchanged: + const autocomplete = elementorCommon.helpers.cloneObject(this.model.get('autocomplete')); + if (_.isEmpty(autocomplete.query)) { + autocomplete.query = {}; + } + // Specific for Group_Control_Query + if ('cpt_tax' === autocomplete.object) { + autocomplete.object = 'tax'; + if (_.isEmpty(autocomplete.query) || _.isEmpty(autocomplete.query.post_type)) { + autocomplete.query.post_type = this.getControlValueByName('post_type'); + } + } + return { + autocomplete + }; + }, + getSelect2DefaultOptions() { + const self = this; + return jQuery.extend(elementor.modules.controls.Select2.prototype.getSelect2DefaultOptions.apply(this, arguments), { + ajax: { + transport(params, success, failure) { + const bcFormat = !_.isEmpty(self.model.get('filter_type')); + let data = {}, + action = 'panel_posts_control_filter_autocomplete'; + if (bcFormat) { + data = self.getQueryDataDeprecated(); + action = 'panel_posts_control_filter_autocomplete_deprecated'; + } else { + data = self.getQueryData(); + } + data.q = params.data.q; + return elementorPro.ajax.addRequest(action, { + data, + success, + error: failure + }); + }, + data(params) { + return { + q: params.term, + page: params.page + }; + }, + cache: true + }, + escapeMarkup(markup) { + return markup; + }, + minimumInputLength: 1 + }); + }, + getValueTitles() { + const self = this, + data = {}, + bcFormat = !_.isEmpty(this.model.get('filter_type')); + let ids = this.getControlValue(), + action = 'query_control_value_titles', + filterTypeName = 'autocomplete', + filterType = {}; + if (bcFormat) { + filterTypeName = 'filter_type'; + filterType = this.model.get(filterTypeName).object; + data.filter_type = filterType; + data.object_type = self.model.get('object_type'); + data.include_type = self.model.get('include_type'); + data.unique_id = '' + self.cid + filterType; + action = 'query_control_value_titles_deprecated'; + } else { + filterType = this.model.get(filterTypeName).object; + data.get_titles = self.getQueryData().autocomplete; + data.unique_id = '' + self.cid + filterType; + } + if (!ids || !filterType) { + return; + } + if (!_.isArray(ids)) { + ids = [ids]; + } + elementorCommon.ajax.loadObjects({ + action, + ids, + data, + before() { + self.addControlSpinner(); + }, + success(ajaxData) { + self.isTitlesReceived = true; + self.model.set('options', ajaxData); + self.render(); + } + }); + }, + addControlSpinner() { + this.ui.select.prop('disabled', true); + this.$el.find('.elementor-control-title').after('  '); + }, + onReady() { + if (!this.isTitlesReceived) { + this.getValueTitles(); + } + } +}); + +/***/ }), + +/***/ "../modules/screenshots/assets/js/editor/component.js": +/*!************************************************************!*\ + !*** ../modules/screenshots/assets/js/editor/component.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var dataHooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/data */ "../modules/screenshots/assets/js/editor/hooks/data/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class _default extends $e.modules.ComponentBase { + getNamespace() { + return 'screenshots'; + } + defaultHooks() { + return this.importHooks(dataHooks); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/screenshots/assets/js/editor/hooks/data/document/save/save/delete-screenshot.js": +/*!**************************************************************************************************!*\ + !*** ../modules/screenshots/assets/js/editor/hooks/data/document/save/save/delete-screenshot.js ***! + \**************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.DeleteScreenshot = void 0; +class DeleteScreenshot extends $e.modules.hookData.After { + getCommand() { + return 'document/save/save'; + } + getConditions(args) { + const { + status + } = args, + config = elementor.documents.getCurrent().config; + return 'publish' === status && config.support_site_editor; + } + getId() { + return 'document/save/save::delete-screenshot'; + } + apply() { + const postId = elementor.documents.getCurrent().id; + return elementorCommon.ajax.addRequest('screenshot_delete', { + unique_id: `delete_screenshot_${postId}`, + data: { + post_id: postId + } + }); + } +} +exports.DeleteScreenshot = DeleteScreenshot; +var _default = exports["default"] = DeleteScreenshot; + +/***/ }), + +/***/ "../modules/screenshots/assets/js/editor/hooks/data/index.js": +/*!*******************************************************************!*\ + !*** ../modules/screenshots/assets/js/editor/hooks/data/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "DeleteScreenshot", ({ + enumerable: true, + get: function () { + return _deleteScreenshot.DeleteScreenshot; + } +})); +var _deleteScreenshot = __webpack_require__(/*! ./document/save/save/delete-screenshot */ "../modules/screenshots/assets/js/editor/hooks/data/document/save/save/delete-screenshot.js"); + +/***/ }), + +/***/ "../modules/screenshots/assets/js/editor/module.js": +/*!*********************************************************!*\ + !*** ../modules/screenshots/assets/js/editor/module.js ***! + \*********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/screenshots/assets/js/editor/component.js")); +class Module extends elementorModules.editor.utils.Module { + onElementorInit() { + $e.components.register(new _component.default()); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/scroll-snap/assets/js/editor/component.js": +/*!************************************************************!*\ + !*** ../modules/scroll-snap/assets/js/editor/component.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ui */ "../modules/scroll-snap/assets/js/editor/hooks/ui/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class ScrollSnapComponent extends $e.modules.ComponentBase { + getNamespace() { + return 'scroll-snap'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = ScrollSnapComponent; + +/***/ }), + +/***/ "../modules/scroll-snap/assets/js/editor/hooks/ui/document/elements/settings/focus-preview.js": +/*!****************************************************************************************************!*\ + !*** ../modules/scroll-snap/assets/js/editor/hooks/ui/document/elements/settings/focus-preview.js ***! + \****************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.FocusPreview = void 0; +class FocusPreview extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'focus-preview--document/elements/settings'; + } + getConditions(args) { + return args.settings.scroll_snap_padding?.size !== ''; + } + apply() { + setTimeout(() => { + elementor.$preview[0].contentWindow.scrollBy(0, 0); + }, 100); + } +} +exports.FocusPreview = FocusPreview; +var _default = exports["default"] = FocusPreview; + +/***/ }), + +/***/ "../modules/scroll-snap/assets/js/editor/hooks/ui/index.js": +/*!*****************************************************************!*\ + !*** ../modules/scroll-snap/assets/js/editor/hooks/ui/index.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "FocusPreview", ({ + enumerable: true, + get: function () { + return _focusPreview.FocusPreview; + } +})); +var _focusPreview = __webpack_require__(/*! ./document/elements/settings/focus-preview */ "../modules/scroll-snap/assets/js/editor/hooks/ui/document/elements/settings/focus-preview.js"); + +/***/ }), + +/***/ "../modules/scroll-snap/assets/js/editor/module.js": +/*!*********************************************************!*\ + !*** ../modules/scroll-snap/assets/js/editor/module.js ***! + \*********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/scroll-snap/assets/js/editor/component.js")); +class Module extends elementorModules.editor.utils.Module { + /** + * Init + */ + onInit() { + super.onInit(); + $e.components.register(new _component.default()); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/share-buttons/assets/js/editor/editor.js": +/*!***********************************************************!*\ + !*** ../modules/share-buttons/assets/js/editor/editor.js ***! + \***********************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + config: elementorPro.config.shareButtonsNetworks, + networksClassDictionary: { + google: 'fab fa-google-plus', + pocket: 'fab fa-get-pocket', + email: 'fas fa-envelope', + print: 'fas fa-print' + }, + getNetworkClass(networkName) { + let networkClass = this.networksClassDictionary[networkName] || 'fab fa-' + networkName; + if (elementor.config.icons_update_needed) { + networkClass = 'fa ' + networkClass; + } + return networkClass; + }, + getNetworkTitle(buttonSettings) { + // BC for items that are already selected and have been removed from the options list. + return buttonSettings.text || this.getNetworkData(buttonSettings)?.title; + }, + getNetworkData(buttonSettings) { + return this.config[buttonSettings.button]; + }, + hasCounter(networkName, settings) { + return 'icon' !== settings.view && 'yes' === settings.show_counter && this.config[networkName].has_counter; + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/conditions/repeater-row.js": +/*!****************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/conditions/repeater-row.js ***! + \****************************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = elementor.modules.controls.RepeaterRow.extend({ + template: '#tmpl-elementor-theme-builder-conditions-repeater-row', + childViewContainer: '.elementor-theme-builder-conditions-repeater-row-controls', + conflictCheckedOnFirstRender: false, + id() { + return 'elementor-condition-id-' + this.model.get('_id'); + }, + onBeforeRender() { + var subNameModel = this.collection.findWhere({ + name: 'sub_name' + }), + subIdModel = this.collection.findWhere({ + name: 'sub_id' + }), + subConditionConfig = this.config.conditions[this.model.attributes.sub_name]; + subNameModel.attributes.groups = this.getOptions(); + if (subConditionConfig && subConditionConfig.controls) { + _(subConditionConfig.controls).each(function (control) { + subIdModel.set(control); + subIdModel.set('name', 'sub_id'); + }); + } + }, + initialize() { + elementor.modules.controls.RepeaterRow.prototype.initialize.apply(this, arguments); + this.config = elementor.config.document.theme_builder; + }, + updateOptions() { + if (this.model.changed.name) { + this.model.set({ + sub_name: '', + sub_id: '' + }); + } + if (this.model.changed.name || this.model.changed.sub_name) { + this.model.set('sub_id', '', { + silent: true + }); + var subIdModel = this.collection.findWhere({ + name: 'sub_id' + }); + subIdModel.set({ + type: 'select', + options: { + '': 'All' + } + }); + this.render(); + } + if (this.model.changed.type) { + this.setTypeAttribute(); + } + }, + getOptions() { + var self = this, + conditionConfig = self.config.conditions[this.model.get('name')]; + if (!conditionConfig) { + return; + } + var options = { + '': conditionConfig.all_label + }; + _(conditionConfig.sub_conditions).each(function (conditionId, conditionIndex) { + var subConditionConfig = self.config.conditions[conditionId], + group; + if (!subConditionConfig) { + return; + } + if (subConditionConfig.sub_conditions.length) { + group = { + label: subConditionConfig.label, + options: {} + }; + group.options[conditionId] = subConditionConfig.all_label; + _(subConditionConfig.sub_conditions).each(function (subConditionId) { + group.options[subConditionId] = self.config.conditions[subConditionId].label; + }); + + // Use a sting key - to keep order + options['key' + conditionIndex] = group; + } else { + options[conditionId] = subConditionConfig.label; + } + }); + return options; + }, + setTypeAttribute() { + var typeView = this.children.findByModel(this.collection.findWhere({ + name: 'type' + })); + typeView.$el.attr('data-elementor-condition-type', typeView.getControlValue()); + }, + // Moved from `modules/theme-builder/assets/js/editor/conditions/repeater.js`. + checkConflicts() { + var modelId = this.model.get('_id'), + rowId = 'elementor-condition-id-' + modelId, + errorMessageId = 'elementor-conditions-conflict-message-' + modelId, + $error = jQuery('#' + errorMessageId); + + // On render - the row isn't exist, so don't cache it. + jQuery('#' + rowId).removeClass('elementor-error'); + $error.remove(); + elementorPro.ajax.addRequest('theme_builder_conditions_check_conflicts', { + unique_id: rowId, + data: { + condition: this.model.toJSON() + }, + success(data) { + if (!_.isEmpty(data)) { + jQuery('#' + rowId).addClass('elementor-error').after('
    ' + data + '
    '); + } + } + }); + }, + onRender() { + var nameModel = this.collection.findWhere({ + name: 'name' + }), + subNameModel = this.collection.findWhere({ + name: 'sub_name' + }), + subIdModel = this.collection.findWhere({ + name: 'sub_id' + }), + nameView = this.children.findByModel(nameModel), + subNameView = this.children.findByModel(subNameModel), + subIdView = this.children.findByModel(subIdModel), + conditionConfig = this.config.conditions[this.model.attributes.name], + subConditionConfig = this.config.conditions[this.model.attributes.sub_name], + typeConfig = this.config.types[this.config.settings.template_type]; + if (typeConfig.condition_type === nameView.getControlValue() && 'general' !== nameView.getControlValue() && !_.isEmpty(conditionConfig.sub_conditions)) { + nameView.$el.hide(); + } + if (!conditionConfig || _.isEmpty(conditionConfig.sub_conditions) && _.isEmpty(conditionConfig.controls) || !nameView.getControlValue() || 'general' === nameView.getControlValue()) { + subNameView.$el.hide(); + } + if (!subConditionConfig || _.isEmpty(subConditionConfig.controls) || !subNameView.getControlValue()) { + subIdView.$el.hide(); + } + + // Avoid set a `single` for a-l-l singular types. (conflicted with 404 & custom cpt like Shops and Events plugins). + if ('singular' === typeConfig.condition_type) { + if ('' === subNameView.getControlValue()) { + subNameView.setValue('post'); + } + } + this.setTypeAttribute(); + if (!this.conflictCheckedOnFirstRender) { + this.checkConflicts(); + this.conflictCheckedOnFirstRender = true; + } + }, + onModelChange() { + this.updateOptions(); + this.checkConflicts(); + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/conditions/repeater.js": +/*!************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/conditions/repeater.js ***! + \************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _repeaterRow = _interopRequireDefault(__webpack_require__(/*! ./repeater-row */ "../modules/theme-builder/assets/js/editor/conditions/repeater-row.js")); +module.exports = elementor.modules.controls.Repeater.extend({ + childView: _repeaterRow.default, + updateActiveRow() {}, + initialize() { + elementor.modules.controls.Repeater.prototype.initialize.apply(this, arguments); + this.config = elementor.config.document.theme_builder; + this.updateConditionsOptions(this.config.settings.template_type); + }, + updateConditionsOptions(templateType) { + var self = this, + conditionType = self.config.types[templateType].condition_type, + options = {}; + _([conditionType]).each(function (conditionId, conditionIndex) { + var conditionConfig = self.config.conditions[conditionId], + group = { + label: conditionConfig.label, + options: {} + }; + group.options[conditionId] = conditionConfig.all_label; + _(conditionConfig.sub_conditions).each(function (subConditionId) { + group.options[subConditionId] = self.config.conditions[subConditionId].label; + }); + options[conditionIndex] = group; + }); + var fields = this.model.get('fields'); + fields[1].default = conditionType; + if ('general' === conditionType) { + fields[1].groups = options; + } else { + fields[2].groups = options; + } + }, + onRender() { + this.ui.btnAddRow.text(__('Add condition', 'elementor-pro')); + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/conditions/view.js": +/*!********************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/conditions/view.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +var inlineControlsStack = __webpack_require__(/*! elementor-pro/editor/inline-controls-stack.js */ "../assets/dev/js/editor/inline-controls-stack.js"); +module.exports = inlineControlsStack.extend({ + id: 'elementor-theme-builder-conditions-view', + template: '#tmpl-elementor-theme-builder-conditions-view', + childViewContainer: '#elementor-theme-builder-conditions-controls', + childViewOptions() { + return { + elementSettingsModel: this.model + }; + } +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/index.js": +/*!************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/index.js ***! + \************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ThemeBuilderSaveAndReload", ({ + enumerable: true, + get: function () { + return _saveAndReload.ThemeBuilderSaveAndReload; + } +})); +Object.defineProperty(exports, "ThemeBuilderUpdatePreviewOptions", ({ + enumerable: true, + get: function () { + return _updatePreviewOptions.ThemeBuilderUpdatePreviewOptions; + } +})); +var _saveAndReload = __webpack_require__(/*! ./save-and-reload */ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/save-and-reload.js"); +var _updatePreviewOptions = __webpack_require__(/*! ./update-preview-options */ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/update-preview-options.js"); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/save-and-reload.js": +/*!**********************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/save-and-reload.js ***! + \**********************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderSaveAndReload = void 0; +/** + * Hook fired when template: 'single' page layout changed. + */ +class ThemeBuilderSaveAndReload extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-theme-builder-save-and-reload'; + } + getContainerType() { + return 'document'; + } + getConditions(args) { + return args.settings && args.settings.page_template; + } + apply() { + $e.run('document/save/auto', { + force: true, + onSuccess: () => { + elementor.reloadPreview(); + elementor.once('preview:loaded', () => { + $e.route('panel/page-settings/settings'); + }); + } + }); + } +} +exports.ThemeBuilderSaveAndReload = ThemeBuilderSaveAndReload; +var _default = exports["default"] = ThemeBuilderSaveAndReload; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/update-preview-options.js": +/*!*****************************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/update-preview-options.js ***! + \*****************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderUpdatePreviewOptions = void 0; +class ThemeBuilderUpdatePreviewOptions extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-theme-builder-update-preview-options'; + } + getContainerType() { + return 'document'; + } + getConditions(args) { + return args.settings && args.settings.preview_type; + } + apply(args) { + const { + containers = [args.container] + } = args, + { + themeBuilder + } = elementorPro.modules; + $e.run('document/elements/settings', { + containers, + settings: { + preview_id: '', + preview_search_term: '' + } + }); + if ($e.routes.is('panel/page-settings/settings')) { + themeBuilder.updatePreviewIdOptions(true); + } + } +} +exports.ThemeBuilderUpdatePreviewOptions = ThemeBuilderUpdatePreviewOptions; +var _default = exports["default"] = ThemeBuilderUpdatePreviewOptions; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/document/save/save-conditions.js": +/*!*********************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/document/save/save-conditions.js ***! + \*********************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderSaveConditions = void 0; +class ThemeBuilderSaveConditions extends $e.modules.hookData.After { + getCommand() { + return 'document/save/save'; + } + getId() { + return 'elementor-pro-theme-builder-save-conditions'; + } + getConditions() { + return !!elementor.config.document.theme_builder; + } + apply() { + const { + conditionsModel + } = elementorPro.modules.themeBuilder; + elementorPro.ajax.addRequest('theme_builder_save_conditions', { + data: conditionsModel.toJSON({ + remove: ['default'] + }), + success: () => { + elementor.config.document.theme_builder.settings.conditions = conditionsModel.get('conditions'); + } + }); + } +} +exports.ThemeBuilderSaveConditions = ThemeBuilderSaveConditions; +var _default = exports["default"] = ThemeBuilderSaveConditions; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/document/save/show-conditions.js": +/*!*********************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/document/save/show-conditions.js ***! + \*********************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderShowConditions = void 0; +class ThemeBuilderShowConditions extends $e.modules.hookData.Dependency { + getCommand() { + return 'document/save/default'; + } + getId() { + return 'elementor-pro-theme-builder-show-conditions'; + } + getConditions(args) { + const { + force = false + } = args; + + // If force save, do not show conditions. + if (force) { + return false; + } + let showConditions = false; + const themeBuilder = elementor.config.document.theme_builder; + if (themeBuilder) { + const hasConditions = themeBuilder.settings.conditions.length, + hasLocation = themeBuilder.settings.location, + isDraft = 'draft' === elementor.settings.page.model.get('post_status'); + if (hasLocation && (!hasConditions || isDraft)) { + showConditions = true; + } + } + return showConditions; + } + apply() { + $e.route('theme-builder-publish/conditions'); + return false; // HookBreak. + } +} +exports.ThemeBuilderShowConditions = ThemeBuilderShowConditions; +var _default = exports["default"] = ThemeBuilderShowConditions; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/editor/documents/preview/preview-break.js": +/*!******************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/editor/documents/preview/preview-break.js ***! + \******************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderPreviewBreak = void 0; +class ThemeBuilderPreviewBreak extends $e.modules.hookData.Dependency { + getCommand() { + return 'editor/documents/preview'; + } + getId() { + return 'elementor-pro-theme-builder-preview-break'; + } + getConditions(args) { + // If preview is forced, do not break it. + if (args.force) { + return false; + } + return !!elementor.documents.get(args.id).config.theme_builder; + } + apply() { + return false; // HookBreak. + } +} +exports.ThemeBuilderPreviewBreak = ThemeBuilderPreviewBreak; +var _default = exports["default"] = ThemeBuilderPreviewBreak; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/data/index.js": +/*!*********************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/data/index.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _exportNames = { + ThemeBuilderSaveConditions: true, + ThemeBuilderShowConditions: true, + ThemeBuilderPreviewBreak: true +}; +Object.defineProperty(exports, "ThemeBuilderPreviewBreak", ({ + enumerable: true, + get: function () { + return _previewBreak.ThemeBuilderPreviewBreak; + } +})); +Object.defineProperty(exports, "ThemeBuilderSaveConditions", ({ + enumerable: true, + get: function () { + return _saveConditions.ThemeBuilderSaveConditions; + } +})); +Object.defineProperty(exports, "ThemeBuilderShowConditions", ({ + enumerable: true, + get: function () { + return _showConditions.ThemeBuilderShowConditions; + } +})); +var _settings = __webpack_require__(/*! ./document/elements/settings */ "../modules/theme-builder/assets/js/editor/hooks/data/document/elements/settings/index.js"); +Object.keys(_settings).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _settings[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _settings[key]; + } + }); +}); +var _saveConditions = __webpack_require__(/*! ./document/save/save-conditions */ "../modules/theme-builder/assets/js/editor/hooks/data/document/save/save-conditions.js"); +var _showConditions = __webpack_require__(/*! ./document/save/show-conditions */ "../modules/theme-builder/assets/js/editor/hooks/data/document/save/show-conditions.js"); +var _previewBreak = __webpack_require__(/*! ./editor/documents/preview/preview-break */ "../modules/theme-builder/assets/js/editor/hooks/data/editor/documents/preview/preview-break.js"); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/index.js": +/*!****************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/index.js ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data/ */ "../modules/theme-builder/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); +var _ui = __webpack_require__(/*! ./ui/ */ "../modules/theme-builder/assets/js/editor/hooks/ui/index.js"); +Object.keys(_ui).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _ui[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _ui[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/document/elements/settings/toggle-menu-conditions.js": +/*!**********************************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/ui/editor/document/elements/settings/toggle-menu-conditions.js ***! + \**********************************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderToggleMenuConditions = void 0; +class ThemeBuilderToggleMenuConditions extends $e.modules.hookUI.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'elementor-pro-theme-builder-toggle-menu-conditions'; + } + getContainerType() { + return 'document'; + } + getConditions(args) { + return args.settings && args.settings.location; + } + apply() { + const { + themeBuilder + } = elementorPro.modules; + themeBuilder.ui.menuConditions.toggle(!!elementor.config.document.theme_builder.settings.location); + } +} +exports.ThemeBuilderToggleMenuConditions = ThemeBuilderToggleMenuConditions; +var _default = exports["default"] = ThemeBuilderToggleMenuConditions; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-editor-ui.js": +/*!*****************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-editor-ui.js ***! + \*****************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderRemoveEditorUI = void 0; +class ThemeBuilderRemoveEditorUI extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/unload'; + } + getId() { + return 'elementor-pro-theme-builder-remove-editor-ui'; + } + getConditions(args) { + const { + document + } = args; + return document.config.theme_builder; + } + apply() { + this.removePanelFooterSubmenuItems(); + this.removePublishTabs(); + } + removePanelFooterSubmenuItems() { + const footerView = elementor.getPanelView().footer.currentView, + behavior = footerView._behaviors[Object.keys(footerView.behaviors()).indexOf('saver')]; + elementor.getPanelView().footer.currentView.removeSubMenuItem('saver-options', { + name: 'conditions' + }); + behavior.ui.buttonPreview.tipsy('enable').removeClass('elementor-panel-footer-theme-builder-buttons-wrapper elementor-toggle-state'); + } + removePublishTabs() { + const component = $e.components.get('theme-builder-publish'); + component.removeTab('conditions'); + } +} +exports.ThemeBuilderRemoveEditorUI = ThemeBuilderRemoveEditorUI; +var _default = exports["default"] = ThemeBuilderRemoveEditorUI; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/open/add-editor-ui.js": +/*!*************************************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/open/add-editor-ui.js ***! + \*************************************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ThemeBuilderAddEditorUI = void 0; +var _view = _interopRequireDefault(__webpack_require__(/*! ../../../../../conditions/view */ "../modules/theme-builder/assets/js/editor/conditions/view.js")); +class ThemeBuilderAddEditorUI extends $e.modules.hookUI.After { + getCommand() { + return 'editor/documents/open'; + } + getId() { + return 'elementor-pro-theme-builder-add-editor-ui'; + } + getConditions(args) { + return elementor.documents.get(args.id).config.theme_builder; + } + apply() { + if (elementor.panel) { + this.addUI(); + } else { + // First open, the panel is not available yet. + elementor.once('preview:loaded', this.addUI.bind(this)); + } + } + addUI() { + this.addRepeaterControlView(); + this.addPanelFooterSubmenuItems(); + this.addPublishTabs(); + } + addRepeaterControlView() { + elementor.addControlView('Conditions_repeater', __webpack_require__(/*! ../../../../../conditions/repeater */ "../modules/theme-builder/assets/js/editor/conditions/repeater.js")); + } + addPublishTabs() { + const component = $e.components.get('theme-builder-publish'), + themeBuilderModuleConfig = elementor.config.document.theme_builder, + settings = themeBuilderModuleConfig.settings; + component.manager.conditionsModel = new elementorModules.editor.elements.models.BaseSettings(settings, { + controls: themeBuilderModuleConfig.template_conditions.controls + }); + component.addTab('conditions', { + title: __('Conditions', 'elementor-pro'), + View: _view.default, + viewOptions: { + model: component.manager.conditionsModel, + controls: component.manager.conditionsModel.controls + }, + name: 'conditions', + description: __('Apply current template to these pages.', 'elementor-pro'), + image: elementorPro.config.urls.modules + 'theme-builder/assets/images/conditions-tab.svg' + }); + } + addPanelFooterSubmenuItems() { + const footerView = elementor.getPanelView().footer.currentView, + behavior = footerView._behaviors[Object.keys(footerView.behaviors()).indexOf('saver')]; + footerView.ui.menuConditions = footerView.addSubMenuItem('saver-options', { + before: 'save-template', + name: 'conditions', + icon: 'eicon-flow', + title: __('Display Conditions', 'elementor-pro'), + callback: () => $e.route('theme-builder-publish/conditions') + }); + footerView.ui.menuConditions.toggle(!!elementor.config.document.theme_builder.settings.location); + behavior.ui.buttonPreview.tipsy('disable').html(jQuery('#tmpl-elementor-theme-builder-button-preview').html()).addClass('elementor-panel-footer-theme-builder-buttons-wrapper elementor-toggle-state'); + } +} +exports.ThemeBuilderAddEditorUI = ThemeBuilderAddEditorUI; +var _default = exports["default"] = ThemeBuilderAddEditorUI; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/ui/index.js": +/*!*******************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/ui/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ThemeBuilderAddEditorUI", ({ + enumerable: true, + get: function () { + return _addEditorUi.ThemeBuilderAddEditorUI; + } +})); +Object.defineProperty(exports, "ThemeBuilderFooterSaverAfterSave", ({ + enumerable: true, + get: function () { + return _after.ThemeBuilderFooterSaverAfterSave; + } +})); +Object.defineProperty(exports, "ThemeBuilderRemoveEditorUI", ({ + enumerable: true, + get: function () { + return _removeEditorUi.ThemeBuilderRemoveEditorUI; + } +})); +Object.defineProperty(exports, "ThemeBuilderToggleMenuConditions", ({ + enumerable: true, + get: function () { + return _toggleMenuConditions.ThemeBuilderToggleMenuConditions; + } +})); +var _addEditorUi = __webpack_require__(/*! ./editor/documents/open/add-editor-ui */ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/open/add-editor-ui.js"); +var _removeEditorUi = __webpack_require__(/*! ./editor/documents/close/remove-editor-ui */ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/documents/close/remove-editor-ui.js"); +var _toggleMenuConditions = __webpack_require__(/*! ./editor/document/elements/settings/toggle-menu-conditions */ "../modules/theme-builder/assets/js/editor/hooks/ui/editor/document/elements/settings/toggle-menu-conditions.js"); +var _after = __webpack_require__(/*! ./save/after */ "../modules/theme-builder/assets/js/editor/hooks/ui/save/after.js"); + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/hooks/ui/save/after.js": +/*!************************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/hooks/ui/save/after.js ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ThemeBuilderFooterSaverAfterSave = void 0; +class ThemeBuilderFooterSaverAfterSave extends $e.modules.hookUI.After { + getCommand() { + return 'document/save/save'; + } + getId() { + return 'theme-builder-footer-saver-after-save'; + } + getConditions() { + return elementor.config.document.support_site_editor; + } + apply(args, result) { + const { + status + } = args; + if (result.statusChanged) { + this.onPageStatusChange(status); + } + } + onPageStatusChange(newStatus) { + if ('publish' !== newStatus) { + return; + } + const options = { + classes: 'e-theme-builder-save-toaster', + message: elementor.config.document.panel.messages.publish_notification, + buttons: [{ + name: 'open_site_editor', + text: '' + __('Open Site Editor', 'elementor-pro') + '', + callback() { + $e.run('app/open'); + } + }, { + name: 'view_live_site', + text: '' + __('View Live Site', 'elementor-pro') + '', + callback() { + open(elementor.config.document.urls.permalink); + } + }] + }; + elementor.notifications.showToast(options); + } +} +exports.ThemeBuilderFooterSaverAfterSave = ThemeBuilderFooterSaverAfterSave; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/module.js": +/*!***********************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/module.js ***! + \***********************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./publish/component */ "../modules/theme-builder/assets/js/editor/publish/component.js")); +class ThemeBuilderModule extends elementorModules.editor.utils.Module { + __construct(...args) { + super.__construct(...args); + Object.defineProperty(elementorPro.config, 'theme_builder', { + get() { + elementorDevTools.deprecation.deprecated('theme_builder', '2.9.0', 'elementor.config.document.theme_builder'); + return elementor.config.document.theme_builder; + } + }); + } + onElementorLoaded() { + this.component = $e.components.register(new _component.default({ + manager: this + })); + elementor.on('document:loaded', this.onDocumentLoaded.bind(this)); + elementor.on('document:unload', this.onDocumentUnloaded.bind(this)); + this.onApplyPreview = this.onApplyPreview.bind(this); + this.onSectionPreviewSettingsActive = this.onSectionPreviewSettingsActive.bind(this); + elementor.channels.editor.on('elementorProSiteLogo:change', this.openSiteIdentity); + } + onDocumentLoaded(document) { + if (!document.config.theme_builder) { + return; + } + elementor.getPanelView().on('set:page:page_settings', this.updatePreviewIdOptions); + elementor.channels.editor.on('elementorThemeBuilder:ApplyPreview', this.onApplyPreview); + elementor.channels.editor.on('page_settings:preview_settings:activated', this.onSectionPreviewSettingsActive); + } + onDocumentUnloaded(document) { + if (!document.config.theme_builder) { + return; + } + elementor.getPanelView().off('set:page:page_settings', this.updatePreviewIdOptions); + elementor.channels.editor.off('elementorThemeBuilder:ApplyPreview', this.onApplyPreview); + elementor.channels.editor.off('page_settings:preview_settings:activated', this.onSectionPreviewSettingsActive); + } + saveAndReload() { + $e.run('document/save/auto', { + force: true, + onSuccess: () => { + elementor.dynamicTags.cleanCache(); + const isInitialDocument = elementor.config.initial_document.id === elementor.documents.getCurrentId(); + if (isInitialDocument) { + // Page templates (e.g. single) with header/footer requires a full reload in order + // to change the main query also for them. + elementor.reloadPreview(); + } else { + $e.internal('editor/documents/attach-preview'); + } + } + }); + } + onApplyPreview() { + this.saveAndReload(); + } + onSectionPreviewSettingsActive() { + this.updatePreviewIdOptions(true); + } + updatePreviewIdOptions = render => { + let previewType = elementor.settings.page.model.get('preview_type'); + if (!previewType) { + return; + } + previewType = previewType.split('/'); + const currentView = elementor.getPanelView().getCurrentPageView(), + controlModel = currentView.collection.findWhere({ + name: 'preview_id' + }); + const templateType = previewType[0], + sourceType = previewType[1]; + if ('author' === previewType[1]) { + controlModel.set({ + autocomplete: { + object: 'author' + } + }); + } else if (this.isTemplateTypeTaxonomyLoop(templateType)) { + controlModel.set({ + autocomplete: { + object: 'tax', + query: { + taxonomy: sourceType + } + } + }); + } else if ('single' === templateType) { + controlModel.set({ + autocomplete: { + object: 'post', + query: { + post_type: sourceType + } + } + }); + } else { + controlModel.set({ + autocomplete: { + object: '' + } + }); + } + if (true === render) { + // Can be model. + const controlView = currentView.children.findByModel(controlModel); + controlView.render(); + controlView.$el.toggle(!!controlModel.get('autocomplete').object); + } + }; + isTemplateTypeTaxonomyLoop(templateType) { + return ['post_taxonomy', 'product_taxonomy'].includes(templateType); + } + async openSiteIdentity() { + await $e.run('panel/global/open'); + $e.route('panel/global/settings-site-identity'); + } +} +exports["default"] = ThemeBuilderModule; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/publish/component.js": +/*!**********************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/publish/component.js ***! + \**********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _content = _interopRequireDefault(__webpack_require__(/*! ./content */ "../modules/theme-builder/assets/js/editor/publish/content.js")); +var _layout = _interopRequireDefault(__webpack_require__(/*! ./layout */ "../modules/theme-builder/assets/js/editor/publish/layout.js")); +var hooks = _interopRequireWildcard(__webpack_require__(/*! ../hooks */ "../modules/theme-builder/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentModalBase { + getNamespace() { + // TODO: should be 'theme-builder/publish'. + return 'theme-builder-publish'; + } + getModalLayout() { + return _layout.default; + } + defaultCommands() { + return { + next: () => { + const tabs = Object.keys(this.tabs), + next = tabs[this.currentTabIndex + 1]; + if (next) { + $e.route(this.getTabRoute(next)); + } + }, + save: () => { + $e.run('document/save/default', { + force: true + }); + this.layout.hideModal(); + }, + 'preview-settings': () => { + // TODO: This is function is not part of this component. + const panel = elementor.getPanelView(); + $e.route('panel/page-settings/settings'); + panel.getCurrentPageView().activateSection('preview_settings')._renderChildren(); + } + }; + } + defaultHooks() { + return this.importHooks(hooks); + } + getTabsWrapperSelector() { + return '#elementor-publish__tabs'; + } + renderTab(tab) { + const tabs = this.getTabs(), + keys = Object.keys(tabs), + tabArgs = tabs[tab]; + this.currentTabIndex = keys.indexOf(tab); + const isLastTab = !keys[this.currentTabIndex + 1]; + this.layout.modalContent.currentView.screen.show(new tabArgs.View(tabArgs.viewOptions)); + this.layout.modal.getElements('next').toggle(!isLastTab); + this.layout.modal.getElements('publish').toggleClass('e-primary', isLastTab); + } + activateTab(tab) { + $e.routes.saveState(this.getNamespace()); + super.activateTab(tab); + } + open() { + super.open(); + if (!this.layoutContent) { + this.layout.showLogo(); + this.layout.modalContent.show(new _content.default({ + component: this + })); + this.layoutContent = true; + } + return true; + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/publish/content.js": +/*!********************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/publish/content.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends Marionette.LayoutView { + id() { + return 'elementor-publish'; + } + getTemplate() { + return Marionette.TemplateCache.get('#tmpl-elementor-component-publish'); + } + regions() { + return { + screen: '#elementor-publish__screen' + }; + } + templateHelpers() { + return { + tabs: this.getOption('component').getTabs() + }; + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/theme-builder/assets/js/editor/publish/layout.js": +/*!*******************************************************************!*\ + !*** ../modules/theme-builder/assets/js/editor/publish/layout.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +class _default extends elementorModules.common.views.modal.Layout { + getModalOptions() { + return { + id: 'elementor-publish__modal', + hide: { + onButtonClick: false + } + }; + } + getLogoOptions() { + return { + title: __('Publish Settings', 'elementor-pro') + }; + } + initModal() { + super.initModal(); + this.modal.addButton({ + name: 'publish', + text: __('Save & Close', 'elementor-pro'), + callback: () => $e.run('theme-builder-publish/save') + }); + this.modal.getElements('publish').addClass('e-btn-txt'); + this.modal.addButton({ + name: 'next', + text: __('Next', 'elementor-pro'), + callback: () => $e.run('theme-builder-publish/next') + }); + const $publishButton = this.modal.getElements('publish'); + this.modal.getElements('next').addClass('e-primary').add($publishButton).addClass('elementor-button').removeClass('dialog-button'); + } +} +exports["default"] = _default; + +/***/ }), + +/***/ "../modules/theme-elements/assets/js/editor/comments-skin.js": +/*!*******************************************************************!*\ + !*** ../modules/theme-elements/assets/js/editor/comments-skin.js ***! + \*******************************************************************/ +/***/ ((module) => { + +"use strict"; + + +module.exports = function () { + var self = this; + self.onPanelShow = function (panel, model) { + var settingsModel = model.get('settings'); + + // If no skins - set the skin to `theme_comments`. + if (!settingsModel.controls._skin.default) { + settingsModel.set('_skin', 'theme_comments'); + } + }; + self.init = function () { + elementor.hooks.addAction('panel/open_editor/widget/post-comments', self.onPanelShow); + }; + self.init(); +}; + +/***/ }), + +/***/ "../modules/theme-elements/assets/js/editor/editor.js": +/*!************************************************************!*\ + !*** ../modules/theme-elements/assets/js/editor/editor.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +module.exports = elementorModules.editor.utils.Module.extend({ + onElementorPreviewLoaded() { + var CommentsSkin = __webpack_require__(/*! ./comments-skin */ "../modules/theme-elements/assets/js/editor/comments-skin.js"); + this.commentsSkin = new CommentsSkin(); + } +}); + +/***/ }), + +/***/ "../modules/video-playlist/assets/js/editor/component.js": +/*!***************************************************************!*\ + !*** ../modules/video-playlist/assets/js/editor/component.js ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ui */ "../modules/video-playlist/assets/js/editor/hooks/ui/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class VideoPlaylistComponent extends $e.modules.ComponentBase { + getNamespace() { + return 'video-playlist'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = VideoPlaylistComponent; + +/***/ }), + +/***/ "../modules/video-playlist/assets/js/editor/hooks/ui/document/elements/settings/active-tab.js": +/*!****************************************************************************************************!*\ + !*** ../modules/video-playlist/assets/js/editor/hooks/ui/document/elements/settings/active-tab.js ***! + \****************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = exports.ActiveTab = void 0; +/** + * Hook fired when template: 'single' page layout changed. + */ +class ActiveTab extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'active-tab--document/elements/settings'; + } + getContainerType() { + return 'repeater'; + } + getConditions(args) { + return args.settings.inner_tab_content_1 || args.settings.inner_tab_content_2; + } + apply(args) { + if (args.settings.inner_tab_content_1) { + args.container.view.model.get('editSettings').set('innerActiveIndex', 0); + } else if (args.settings.inner_tab_content_2) { + args.container.view.model.get('editSettings').set('innerActiveIndex', 1); + } + } +} +exports.ActiveTab = ActiveTab; +var _default = exports["default"] = ActiveTab; + +/***/ }), + +/***/ "../modules/video-playlist/assets/js/editor/hooks/ui/index.js": +/*!********************************************************************!*\ + !*** ../modules/video-playlist/assets/js/editor/hooks/ui/index.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "ActiveTab", ({ + enumerable: true, + get: function () { + return _activeTab.ActiveTab; + } +})); +var _activeTab = __webpack_require__(/*! ./document/elements/settings/active-tab */ "../modules/video-playlist/assets/js/editor/hooks/ui/document/elements/settings/active-tab.js"); + +/***/ }), + +/***/ "../modules/video-playlist/assets/js/editor/module.js": +/*!************************************************************!*\ + !*** ../modules/video-playlist/assets/js/editor/module.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/video-playlist/assets/js/editor/component.js")); +class Module extends elementorModules.editor.utils.Module { + /** + * Init + */ + onInit() { + super.onInit(); + $e.components.register(new _component.default()); + } + onElementorLoaded() { + elementor.channels.editor.on('elementorPlaylistWidget:setVideoData', e => { + $e.run('document/elements/settings', { + container: e.container, + settings: { + thumbnail: { + url: e.currentItem.thumbnail ? e.currentItem.thumbnail.url : '' + }, + title: e.currentItem.video_title ? e.currentItem.video_title : '', + duration: e.currentItem.duration ? e.currentItem.duration : '' + }, + options: { + external: true + } + }); + }); + } +} +exports["default"] = Module; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/component.js": +/*!************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/component.js ***! + \************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var hooks = _interopRequireWildcard(__webpack_require__(/*! ./hooks/ */ "../modules/woocommerce/assets/js/editor/hooks/index.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +class Component extends $e.modules.ComponentBase { + getNamespace() { + return 'woocommerce'; + } + defaultHooks() { + return this.importHooks(hooks); + } +} +exports["default"] = Component; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hints/store-tracking.js": +/*!***********************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hints/store-tracking.js ***! + \***********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +module.exports = elementorModules.editor.utils.Module.extend({ + eventName: 'send_app_wc_widgets_notice', + suffix: '', + control: null, + onSectionActive(sectionName, editor) { + const editedElement = editor.getOption('editedElementView'); + const widgetType = editedElement.model.get('widgetType'); + const sectionWidgetMap = { + section_product: ['wc-add-to-cart'], + section_content: ['woocommerce-cart', 'woocommerce-checkout-page'], + section_layout: ['woocommerce-product-add-to-cart'] + }; + if (!sectionWidgetMap[sectionName]?.includes(widgetType)) { + return; + } + this.control = null; + + // Check if control exists + if (!this.hasPromoControl()) { + return; + } + + // Check if the user has dismissed the hint + if (elementor.config.user.dismissed_editor_notices.includes('send_app_wc_widgets_notice')) { + this.getPromoControl().remove(); + return; + } + this.registerEvents(); + }, + registerEvents() { + // Handle dismiss and action buttons + const dismissBtn = this.getPromoControl().$el.find('.elementor-control-notice-dismiss'); + const onDismissBtnClick = event => { + dismissBtn.off('click', onDismissBtnClick); // Remove the event listener + event.preventDefault(); + this.dismiss(); + this.getPromoControl().remove(); + }; + dismissBtn.on('click', onDismissBtnClick); + + // Handle action button + const actionBtn = this.getPromoControl().$el.find('.e-btn-1'); + const onActionBtn = event => { + actionBtn.off('click', onActionBtn); // Remove the event listener + event.preventDefault(); + this.onAction(event); + this.getPromoControl().remove(); + }; + actionBtn.on('click', onActionBtn); + }, + getPromoControl() { + if (!this.control && !!this.getEditorControlModel('send_app_promo' + this.suffix)) { + this.control = this.getEditorControlView('send_app_promo' + this.suffix); + } + return this.control; + }, + hasPromoControl() { + return !!this.getPromoControl(); + }, + ajaxRequest(name, data) { + elementorCommon.ajax.addRequest(name, { + data + }); + }, + dismiss() { + this.ajaxRequest('dismissed_editor_notices', { + dismissId: this.eventName + }); + + // Prevent opening the same hint again in current editor session. + this.ensureNoPromoControlInSession(); + }, + ensureNoPromoControlInSession() { + // Prevent opening the same hint again in current editor session. + elementor.config.user.dismissed_editor_notices.push(this.eventName); + }, + onAction(event) { + const { + action_url: actionURL = null + } = JSON.parse(event.target.closest('button').dataset.settings); + if (actionURL) { + window.open(actionURL, '_blank'); + } + this.ajaxRequest('elementor_send_app_campaign', { + source: 'snd-wc-install' + }); + this.ensureNoPromoControlInSession(); + }, + onElementorInit() { + elementor.channels.editor.on('section:activated', (sectionName, editor) => this.onSectionActive(sectionName, editor)); + } +}); + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/data/create-widget-activate-settings-modal.js": +/*!***************************************************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/data/create-widget-activate-settings-modal.js ***! + \***************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.WoocommerceCreateWidgetActivateSettingsModal = void 0; +class WoocommerceCreateWidgetActivateSettingsModal extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/create'; + } + getId() { + return 'elementor-pro-woocommerce-create-widget-activate-settings-modal'; + } + getContainerType() { + return 'column'; + } + getConditions(args, container) { + return Object.prototype.hasOwnProperty.call(elementorPro.modules.woocommerce.pageSettingsWidgets, container.model.get('widgetType')); + } + apply(args, container) { + elementorPro.modules.woocommerce.onCreateWidget(container); + } +} +exports.WoocommerceCreateWidgetActivateSettingsModal = WoocommerceCreateWidgetActivateSettingsModal; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/data/delete-widget-deactivate-settings-modal.js": +/*!*****************************************************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/data/delete-widget-deactivate-settings-modal.js ***! + \*****************************************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.WoocommerceDeleteWidgetDeactivateSettingsModal = void 0; +class WoocommerceDeleteWidgetDeactivateSettingsModal extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/delete'; + } + getId() { + return 'elementor-pro-woocommerce-delete-widget-deactivate-settings-modal'; + } + getContainerType() { + return 'widget'; + } + getConditions(args, container) { + return Object.prototype.hasOwnProperty.call(elementorPro.modules.woocommerce.pageSettingsWidgets, container.model.get('widgetType')); + } + apply(args, container) { + elementorPro.modules.woocommerce.onDeleteWidget(container); + } +} +exports.WoocommerceDeleteWidgetDeactivateSettingsModal = WoocommerceDeleteWidgetDeactivateSettingsModal; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/data/index.js": +/*!*******************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/data/index.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "WoocommerceCreateWidgetActivateSettingsModal", ({ + enumerable: true, + get: function () { + return _createWidgetActivateSettingsModal.WoocommerceCreateWidgetActivateSettingsModal; + } +})); +Object.defineProperty(exports, "WoocommerceDeleteWidgetDeactivateSettingsModal", ({ + enumerable: true, + get: function () { + return _deleteWidgetDeactivateSettingsModal.WoocommerceDeleteWidgetDeactivateSettingsModal; + } +})); +Object.defineProperty(exports, "WoocommerceNotices", ({ + enumerable: true, + get: function () { + return _notices.WoocommerceNotices; + } +})); +Object.defineProperty(exports, "WoocommerceSaveShowModal", ({ + enumerable: true, + get: function () { + return _saveShowModal.WoocommerceSaveShowModal; + } +})); +var _saveShowModal = __webpack_require__(/*! ./save-show-modal */ "../modules/woocommerce/assets/js/editor/hooks/data/save-show-modal.js"); +var _createWidgetActivateSettingsModal = __webpack_require__(/*! ./create-widget-activate-settings-modal */ "../modules/woocommerce/assets/js/editor/hooks/data/create-widget-activate-settings-modal.js"); +var _deleteWidgetDeactivateSettingsModal = __webpack_require__(/*! ./delete-widget-deactivate-settings-modal */ "../modules/woocommerce/assets/js/editor/hooks/data/delete-widget-deactivate-settings-modal.js"); +var _notices = __webpack_require__(/*! ./notices */ "../modules/woocommerce/assets/js/editor/hooks/data/notices.js"); + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/data/notices.js": +/*!*********************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/data/notices.js ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.WoocommerceNotices = void 0; +class WoocommerceNotices extends $e.modules.hookData.After { + getCommand() { + return 'document/elements/settings'; + } + getId() { + return 'woocommerce-notices'; + } + getConditions(args) { + return 'kit' === elementor.documents.getCurrent().config.type && Array.isArray(args.settings.woocommerce_notices_elements); + } + apply(args) { + const { + woocommerce + } = elementorPro.modules; + woocommerce.renderMockNotices(args.settings.woocommerce_notices_elements); + } +} +exports.WoocommerceNotices = WoocommerceNotices; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/data/save-show-modal.js": +/*!*****************************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/data/save-show-modal.js ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.WoocommerceSaveShowModal = void 0; +class WoocommerceSaveShowModal extends $e.modules.hookData.After { + getCommand() { + return 'document/save/save'; + } + getId() { + return 'elementor-pro-woocommerce-save-show-modal'; + } + getConditions(args) { + return args.status && -1 !== ['private', 'publish'].indexOf(args.status); + } + apply() { + elementorPro.modules.woocommerce.onUpdateDocument(); + } +} +exports.WoocommerceSaveShowModal = WoocommerceSaveShowModal; + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/hooks/index.js": +/*!**************************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/hooks/index.js ***! + \**************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +var _data = __webpack_require__(/*! ./data/ */ "../modules/woocommerce/assets/js/editor/hooks/data/index.js"); +Object.keys(_data).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _data[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _data[key]; + } + }); +}); + +/***/ }), + +/***/ "../modules/woocommerce/assets/js/editor/module.js": +/*!*********************************************************!*\ + !*** ../modules/woocommerce/assets/js/editor/module.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +__webpack_require__(/*! core-js/modules/es.array.push.js */ "../node_modules/core-js/modules/es.array.push.js"); +var _component = _interopRequireDefault(__webpack_require__(/*! ./component */ "../modules/woocommerce/assets/js/editor/component.js")); +var _storeTracking = _interopRequireDefault(__webpack_require__(/*! ./hints/store-tracking */ "../modules/woocommerce/assets/js/editor/hints/store-tracking.js")); +class WoocommerceModule extends elementorModules.editor.utils.Module { + constructor(...args) { + super(...args); + this.pageSettingsWidgets = { + 'woocommerce-checkout-page': { + headerMessage: __('Want to save this as your checkout page?', 'elementor-pro'), + message: __('Changes you make here will override your existing WooCommerce settings.', 'elementor-pro'), + confirmMessage: __('You\'ve updated your checkout page.', 'elementor-pro'), + cancelMessage: __('

    Set up a checkout page


    Without a checkout page, visitors can\'t complete transactions on your site. To set one up, go to Site Settings.', 'elementor-pro'), + failedMessage: __('

    Sorry, something went wrong.


    To define a checkout page for your site, head over to Site Settings.', 'elementor-pro'), + optionName: 'woocommerce_checkout_page_id', + woocommercePageName: 'checkout' + }, + 'woocommerce-cart': { + headerMessage: __('Want to save this as your cart page?', 'elementor-pro'), + message: __('Changes you make here will override your existing WooCommerce settings.', 'elementor-pro'), + confirmMessage: __('You\'ve updated your cart page.', 'elementor-pro'), + cancelMessage: __('

    Set up a cart page


    The cart page shows an order summary. To set one up, go to Site Settings.', 'elementor-pro'), + failedMessage: __('

    Sorry, something went wrong.


    To define a cart page for your site, head over to Site Settings.', 'elementor-pro'), + optionName: 'woocommerce_cart_page_id', + woocommercePageName: 'cart' + }, + 'woocommerce-my-account': { + headerMessage: __('Want to save this as your my account page?', 'elementor-pro'), + message: __('Changes you make here will override your existing WooCommerce settings.', 'elementor-pro'), + confirmMessage: __('You\'ve updated your my account page.', 'elementor-pro'), + cancelMessage: __('

    Set up a My Account page


    Without it, customers can\'t update their billing details, review past orders, etc. To set up My Account, go to Site Settings.', 'elementor-pro'), + failedMessage: __('

    Sorry, something went wrong.


    To define a my account page for your site, head over to Site Settings.', 'elementor-pro'), + optionName: 'woocommerce_myaccount_page_id', + woocommercePageName: 'myaccount' + }, + 'woocommerce-purchase-summary': { + headerMessage: __('Want to save this as your purchase summary page?', 'elementor-pro'), + message: __('Changes you make here will override your WooCommerce default purchase summary page.', 'elementor-pro'), + confirmMessage: __('You\'ve updated your summary page.', 'elementor-pro'), + cancelMessage: __('

    Set up a purchase summary page


    This page shows payment and order details. To set one up, go to Site Settings.', 'elementor-pro'), + failedMessage: __('

    Sorry, something went wrong.


    To define a purchase summary page for your site, head over to Site Settings.', 'elementor-pro'), + optionName: 'elementor_woocommerce_purchase_summary_page_id', + woocommercePageName: 'summary' + } + }; + this.createdPageSettingsWidgets = []; + this.hints = { + storeTracking: new _storeTracking.default() + }; + } + addWooCommerceClassToLoopWrapper(LoopGridHandler) { + LoopGridHandler.$element.addClass('woocommerce'); + } + onElementorInit() { + elementor.hooks.addAction('editor/widgets/loop-grid/on-init', this.addWooCommerceClassToLoopWrapper); + } + onElementorFrontendInit() { + elementorFrontend.elements.$body.on('added_to_cart', (e, data) => { + // We do not want the page to reload in the Editor after we triggered the 'added_to_cart' event. + if (this.didManuallyTriggerAddToCartEvent(data)) { + return false; + } + }); + if ('loop-item' === elementor.documents.currentDocument.config.type && 'product' === elementor.documents.currentDocument.config.settings.settings.source) { + // Add the 'woocommerce' class to the Loop document wrapper only when editing a Product Loop Template in the + // theme builder. + elementor.on('document:loaded', () => { + elementor.$previewContents[0].querySelector('.e-loop-item').classList.add('woocommerce'); + }); + } + } + didManuallyTriggerAddToCartEvent(data = null) { + return data?.e_manually_triggered; + } + onElementorLoaded() { + this.component = $e.components.register(new _component.default({ + manager: this + })); + // WooCommerce Notice Settings. + const noticeSections = ['section_woocommerce_notices', 'woocommerce_message_notices', 'woocommerce_info_notices', 'woocommerce_error_notices']; + for (const section of noticeSections) { + elementor.channels.editor.on('kit_settings:' + section + ':activated', () => { + this.renderMockNotices(elementor.documents.getCurrent().container.settings.get('woocommerce_notices_elements')); + }); + } + + // Custom Empty Cart Template. + elementor.channels.editor.on('editor:widget:woocommerce-cart:section_additional_options:activated', () => { + this.onTemplateIdChange('additional_template_select'); + }); + + // Custom My Account Dashboard Template + elementor.channels.editor.on('editor:widget:woocommerce-my-account:section_additional_options:activated', () => { + this.onTemplateIdChange('customize_dashboard_select'); + }); + } + renderMockNotices(noticeElements) { + const noticesWrapper = elementor.$previewContents.find('.woocommerce-notices-wrapper'); + if (noticeElements.length <= 0) { + noticesWrapper.remove(); + return; + } + let noticesClass = ''; + for (const notice of noticeElements) { + const className = notice.replace('_', '-'); + noticesClass += 'e-' + className + '-notice '; + } + elementorFrontend.elements.$body.addClass(noticesClass.trim()); + noticesWrapper.addClass('elementor-loading'); + // Wait for the Ajax call to finish before the select2 can be changed again. + jQuery('.elementor-select2').attr('disabled', 'disabled'); + elementorPro.ajax.addRequest('woocommerce_mock_notices', { + data: { + notice_elements: noticeElements + }, + success(data) { + noticesWrapper.remove(); + elementor.$previewContents.find('.elementor-editor-preview').prepend(data); + noticesWrapper.removeClass('elementor-loading'); + // Enable the select2 again. + jQuery('.elementor-select2').removeAttr('disabled'); + } + }); + } + onTemplateIdChange(sectionActive) { + const editor = elementor.getPanelView().getCurrentPageView(), + model = editor.getOption('editedElementView').getEditModel(), + settingsModel = model.get('settings'), + templateID = settingsModel.get(sectionActive), + $editButton = editor.$el.find('.elementor-edit-template'); + if (!templateID) { + $editButton.addClass('e-control-tool-disabled').hide(); + } else { + const editUrl = ElementorConfig.home_url + '?p=' + templateID + '&elementor'; + $editButton.prop('href', editUrl).removeClass('e-control-tool-disabled').show(); + } + } + onCreateWidget(container) { + const widgetType = container.model.get('widgetType'); + if (undefined === this.createdPageSettingsWidgets[widgetType]) { + this.createdPageSettingsWidgets[widgetType] = 0; + } + this.createdPageSettingsWidgets[widgetType]++; + } + onDeleteWidget(container) { + const widgetType = container.model.get('widgetType'); + this.createdPageSettingsWidgets[widgetType]--; + if (!this.createdPageSettingsWidgets[widgetType]) { + delete this.createdPageSettingsWidgets[widgetType]; + } + } + onUpdateDocument() { + // On page Save trigger the 'added_to_cart' event so that the persistent cart cache can refresh so that the 'Preview' can be immediately updated without having to go and make a change in the Cart first. + elementorFrontend.elements.$body.trigger('added_to_cart', [{ + e_manually_triggered: true + }]); + const saveWoocommercePageSettingKeys = Object.keys(this.createdPageSettingsWidgets), + lastWidgetCreated = saveWoocommercePageSettingKeys[saveWoocommercePageSettingKeys.length - 1], + postId = elementor.documents.getCurrent().id; + if (1 !== saveWoocommercePageSettingKeys.length) { + return; + } + const lastWidgetCreatedOptions = this.pageSettingsWidgets[lastWidgetCreated]; + + // Bail if this page is already set as the corresponding WC page. + if (postId === elementorPro.config.woocommerce.woocommercePages[lastWidgetCreatedOptions.woocommercePageName]) { + return; + } + elementorCommon.dialogsManager.createWidget('confirm', { + id: 'elementor-woocommerce-save-pages', + className: 'e-global__confirm-add', + headerMessage: lastWidgetCreatedOptions.headerMessage, + message: lastWidgetCreatedOptions.message, + position: { + my: 'center center', + at: 'center center' + }, + strings: { + confirm: __('Save', 'elementor-pro'), + cancel: __('No thanks', 'elementor-pro') + }, + onConfirm: () => this.onConfirmModal(lastWidgetCreatedOptions), + onCancel: () => this.onCancelModal(lastWidgetCreatedOptions) + }).show(); + this.createdPageSettingsWidgets = []; + } + onConfirmModal(lastWidgetCreatedOptions) { + elementorPro.ajax.addRequest('woocommerce_update_page_option', { + data: { + option_name: lastWidgetCreatedOptions.optionName + }, + success: () => { + elementor.notifications.showToast({ + message: lastWidgetCreatedOptions.confirmMessage + }); + }, + error: () => this.showPagesSettingsToast(lastWidgetCreatedOptions.failedMessage) + }); + } + onCancelModal(lastWidgetCreatedOptions) { + this.showPagesSettingsToast(lastWidgetCreatedOptions.cancelMessage); + } + showPagesSettingsToast(message) { + const buttons = []; + elementor.notifications.initToast(); + buttons.push({ + name: 'take_me_there', + text: __('Take me there', 'elementor-pro'), + callback: () => this.openSiteSettingsTab('settings-woocommerce') + }); + elementor.notifications.showToast({ + message, + buttons + }); + } + + // TODO: Add this as a reusable core function - to be able to open any settings tab. + openSiteSettingsTab(tabId = '', sectionId = '') { + const isWPPreviewMode = elementorCommon.elements.$body.hasClass('elementor-editor-preview'); + if (isWPPreviewMode) { + elementor.exitPreviewMode(); + } + const isInSettingsPanelActive = 'panel/global/menu' === elementor.documents.currentDocument.config.panel.default_route; + if (isInSettingsPanelActive) { + $e.run('panel/global/close'); + return; + } + $e.run('editor/documents/switch', { + id: elementor.config.kit_id, + mode: 'autosave' + }).then(() => { + if (tabId) { + $e.route('panel/global/' + tabId); + } + }) + // TODO: Replace with a standard routing solution once one is available + .then(() => { + if (sectionId) { + const sectionElement = jQuery('.elementor-control-' + sectionId); + if (sectionElement.length) { + sectionElement.trigger('click'); + } + } + }); + } +} +module.exports = WoocommerceModule; + +/***/ }), + +/***/ "react": +/*!************************!*\ + !*** external "React" ***! + \************************/ +/***/ ((module) => { + +"use strict"; +module.exports = React; + +/***/ }), + +/***/ "@wordpress/i18n": +/*!**************************!*\ + !*** external "wp.i18n" ***! + \**************************/ +/***/ ((module) => { + +"use strict"; +module.exports = wp.i18n; + +/***/ }), + +/***/ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js": +/*!***********************************************************************!*\ + !*** ../node_modules/@babel/runtime/helpers/interopRequireDefault.js ***! + \***********************************************************************/ +/***/ ((module) => { + +function _interopRequireDefault(e) { + return e && e.__esModule ? e : { + "default": e + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ "../node_modules/core-js/internals/a-callable.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/a-callable.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var tryToString = __webpack_require__(/*! ../internals/try-to-string */ "../node_modules/core-js/internals/try-to-string.js"); + +var $TypeError = TypeError; + +// `Assert: IsCallable(argument) is true` +module.exports = function (argument) { + if (isCallable(argument)) return argument; + throw new $TypeError(tryToString(argument) + ' is not a function'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/an-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/an-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $String = String; +var $TypeError = TypeError; + +// `Assert: Type(argument) is Object` +module.exports = function (argument) { + if (isObject(argument)) return argument; + throw new $TypeError($String(argument) + ' is not an object'); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-includes.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/array-includes.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toAbsoluteIndex = __webpack_require__(/*! ../internals/to-absolute-index */ "../node_modules/core-js/internals/to-absolute-index.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); + +// `Array.prototype.{ indexOf, includes }` methods implementation +var createMethod = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = lengthOfArrayLike(O); + if (length === 0) return !IS_INCLUDES && -1; + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare -- NaN check + if (IS_INCLUDES && el !== el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare -- NaN check + if (value !== value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) { + if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +module.exports = { + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod(false) +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/array-set-length.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/array-set-length.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var isArray = __webpack_require__(/*! ../internals/is-array */ "../node_modules/core-js/internals/is-array.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Safari < 13 does not throw an error in this case +var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () { + // makes no sense without proper strict mode support + if (this !== undefined) return true; + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).length = 1; + } catch (error) { + return error instanceof TypeError; + } +}(); + +module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { + if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) { + throw new $TypeError('Cannot set read only .length'); + } return O.length = length; +} : function (O, length) { + return O.length = length; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/classof-raw.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/classof-raw.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var toString = uncurryThis({}.toString); +var stringSlice = uncurryThis(''.slice); + +module.exports = function (it) { + return stringSlice(toString(it), 8, -1); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/copy-constructor-properties.js": +/*!************************************************************************!*\ + !*** ../node_modules/core-js/internals/copy-constructor-properties.js ***! + \************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var ownKeys = __webpack_require__(/*! ../internals/own-keys */ "../node_modules/core-js/internals/own-keys.js"); +var getOwnPropertyDescriptorModule = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); + +module.exports = function (target, source, exceptions) { + var keys = ownKeys(source); + var defineProperty = definePropertyModule.f; + var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) { + defineProperty(target, key, getOwnPropertyDescriptor(source, key)); + } + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-non-enumerable-property.js": +/*!***************************************************************************!*\ + !*** ../node_modules/core-js/internals/create-non-enumerable-property.js ***! + \***************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); + +module.exports = DESCRIPTORS ? function (object, key, value) { + return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/create-property-descriptor.js": +/*!***********************************************************************!*\ + !*** ../node_modules/core-js/internals/create-property-descriptor.js ***! + \***********************************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-built-in.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/define-built-in.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var definePropertyModule = __webpack_require__(/*! ../internals/object-define-property */ "../node_modules/core-js/internals/object-define-property.js"); +var makeBuiltIn = __webpack_require__(/*! ../internals/make-built-in */ "../node_modules/core-js/internals/make-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +module.exports = function (O, key, value, options) { + if (!options) options = {}; + var simple = options.enumerable; + var name = options.name !== undefined ? options.name : key; + if (isCallable(value)) makeBuiltIn(value, name, options); + if (options.global) { + if (simple) O[key] = value; + else defineGlobalProperty(key, value); + } else { + try { + if (!options.unsafe) delete O[key]; + else if (O[key]) simple = true; + } catch (error) { /* empty */ } + if (simple) O[key] = value; + else definePropertyModule.f(O, key, { + value: value, + enumerable: false, + configurable: !options.nonConfigurable, + writable: !options.nonWritable + }); + } return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/define-global-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/define-global-property.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; + +module.exports = function (key, value) { + try { + defineProperty(globalThis, key, { value: value, configurable: true, writable: true }); + } catch (error) { + globalThis[key] = value; + } return value; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/descriptors.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/descriptors.js ***! + \********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// Detect IE8's incomplete defineProperty implementation +module.exports = !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/document-create-element.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/document-create-element.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var document = globalThis.document; +// typeof document.createElement is 'object' in old IE +var EXISTS = isObject(document) && isObject(document.createElement); + +module.exports = function (it) { + return EXISTS ? document.createElement(it) : {}; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/does-not-exceed-safe-integer.js ***! + \*************************************************************************/ +/***/ ((module) => { + +"use strict"; + +var $TypeError = TypeError; +var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 + +module.exports = function (it) { + if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded'); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/enum-bug-keys.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/enum-bug-keys.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +// IE8- don't enum bug keys +module.exports = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' +]; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-user-agent.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-user-agent.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var navigator = globalThis.navigator; +var userAgent = navigator && navigator.userAgent; + +module.exports = userAgent ? String(userAgent) : ''; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/environment-v8-version.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/environment-v8-version.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var userAgent = __webpack_require__(/*! ../internals/environment-user-agent */ "../node_modules/core-js/internals/environment-user-agent.js"); + +var process = globalThis.process; +var Deno = globalThis.Deno; +var versions = process && process.versions || Deno && Deno.version; +var v8 = versions && versions.v8; +var match, version; + +if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} + +// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` +// so check `userAgent` even if `.v8` exists, but 0 +if (!version && userAgent) { + match = userAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent.match(/Chrome\/(\d+)/); + if (match) version = +match[1]; + } +} + +module.exports = version; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/export.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/export.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var getOwnPropertyDescriptor = (__webpack_require__(/*! ../internals/object-get-own-property-descriptor */ "../node_modules/core-js/internals/object-get-own-property-descriptor.js").f); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var defineBuiltIn = __webpack_require__(/*! ../internals/define-built-in */ "../node_modules/core-js/internals/define-built-in.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); +var copyConstructorProperties = __webpack_require__(/*! ../internals/copy-constructor-properties */ "../node_modules/core-js/internals/copy-constructor-properties.js"); +var isForced = __webpack_require__(/*! ../internals/is-forced */ "../node_modules/core-js/internals/is-forced.js"); + +/* + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.dontCallGetSet - prevent calling a getter on target + options.name - the .name of the function if it does not match the key +*/ +module.exports = function (options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED, target, key, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = globalThis; + } else if (STATIC) { + target = globalThis[TARGET] || defineGlobalProperty(TARGET, {}); + } else { + target = globalThis[TARGET] && globalThis[TARGET].prototype; + } + if (target) for (key in source) { + sourceProperty = source[key]; + if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; + FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); + // contained in target + if (!FORCED && targetProperty !== undefined) { + if (typeof sourceProperty == typeof targetProperty) continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + // add a flag to not completely full polyfills + if (options.sham || (targetProperty && targetProperty.sham)) { + createNonEnumerableProperty(sourceProperty, 'sham', true); + } + defineBuiltIn(target, key, sourceProperty, options); + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/fails.js": +/*!**************************************************!*\ + !*** ../node_modules/core-js/internals/fails.js ***! + \**************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = function (exec) { + try { + return !!exec(); + } catch (error) { + return true; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-bind-native.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/function-bind-native.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +module.exports = !fails(function () { + // eslint-disable-next-line es/no-function-prototype-bind -- safe + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test != 'function' || test.hasOwnProperty('prototype'); +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-call.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-call.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var call = Function.prototype.call; + +module.exports = NATIVE_BIND ? call.bind(call) : function () { + return call.apply(call, arguments); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-name.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/function-name.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); + +var FunctionPrototype = Function.prototype; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor; + +var EXISTS = hasOwn(FunctionPrototype, 'name'); +// additional protection from minified / mangled / dropped function names +var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; +var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable)); + +module.exports = { + EXISTS: EXISTS, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/function-uncurry-this.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/function-uncurry-this.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(/*! ../internals/function-bind-native */ "../node_modules/core-js/internals/function-bind-native.js"); + +var FunctionPrototype = Function.prototype; +var call = FunctionPrototype.call; +var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call); + +module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) { + return function () { + return call.apply(fn, arguments); + }; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-built-in.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/get-built-in.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var aFunction = function (argument) { + return isCallable(argument) ? argument : undefined; +}; + +module.exports = function (namespace, method) { + return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/get-method.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/get-method.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var aCallable = __webpack_require__(/*! ../internals/a-callable */ "../node_modules/core-js/internals/a-callable.js"); +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +// `GetMethod` abstract operation +// https://tc39.es/ecma262/#sec-getmethod +module.exports = function (V, P) { + var func = V[P]; + return isNullOrUndefined(func) ? undefined : aCallable(func); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/global-this.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/global-this.js ***! + \********************************************************/ +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + +var check = function (it) { + return it && it.Math === Math && it; +}; + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +module.exports = + // eslint-disable-next-line es/no-global-this -- safe + check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == 'object' && self) || + check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) || + check(typeof this == 'object' && this) || + // eslint-disable-next-line no-new-func -- fallback + (function () { return this; })() || Function('return this')(); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/has-own-property.js": +/*!*************************************************************!*\ + !*** ../node_modules/core-js/internals/has-own-property.js ***! + \*************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); + +var hasOwnProperty = uncurryThis({}.hasOwnProperty); + +// `HasOwnProperty` abstract operation +// https://tc39.es/ecma262/#sec-hasownproperty +// eslint-disable-next-line es/no-object-hasown -- safe +module.exports = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty(toObject(it), key); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/hidden-keys.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/hidden-keys.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = {}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ie8-dom-define.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/ie8-dom-define.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var createElement = __webpack_require__(/*! ../internals/document-create-element */ "../node_modules/core-js/internals/document-create-element.js"); + +// Thanks to IE8 for its funny defineProperty +module.exports = !DESCRIPTORS && !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(createElement('div'), 'a', { + get: function () { return 7; } + }).a !== 7; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/indexed-object.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/indexed-object.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +var $Object = Object; +var split = uncurryThis(''.split); + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +module.exports = fails(function () { + // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 + // eslint-disable-next-line no-prototype-builtins -- safe + return !$Object('z').propertyIsEnumerable(0); +}) ? function (it) { + return classof(it) === 'String' ? split(it, '') : $Object(it); +} : $Object; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/inspect-source.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/inspect-source.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +var functionToString = uncurryThis(Function.toString); + +// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper +if (!isCallable(store.inspectSource)) { + store.inspectSource = function (it) { + return functionToString(it); + }; +} + +module.exports = store.inspectSource; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/internal-state.js": +/*!***********************************************************!*\ + !*** ../node_modules/core-js/internals/internal-state.js ***! + \***********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var NATIVE_WEAK_MAP = __webpack_require__(/*! ../internals/weak-map-basic-detection */ "../node_modules/core-js/internals/weak-map-basic-detection.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var createNonEnumerableProperty = __webpack_require__(/*! ../internals/create-non-enumerable-property */ "../node_modules/core-js/internals/create-non-enumerable-property.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var shared = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); +var sharedKey = __webpack_require__(/*! ../internals/shared-key */ "../node_modules/core-js/internals/shared-key.js"); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; +var TypeError = globalThis.TypeError; +var WeakMap = globalThis.WeakMap; +var set, get, has; + +var enforce = function (it) { + return has(it) ? get(it) : set(it, {}); +}; + +var getterFor = function (TYPE) { + return function (it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw new TypeError('Incompatible receiver, ' + TYPE + ' required'); + } return state; + }; +}; + +if (NATIVE_WEAK_MAP || shared.state) { + var store = shared.state || (shared.state = new WeakMap()); + /* eslint-disable no-self-assign -- prototype methods protection */ + store.get = store.get; + store.has = store.has; + store.set = store.set; + /* eslint-enable no-self-assign -- prototype methods protection */ + set = function (it, metadata) { + if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + store.set(it, metadata); + return metadata; + }; + get = function (it) { + return store.get(it) || {}; + }; + has = function (it) { + return store.has(it); + }; +} else { + var STATE = sharedKey('state'); + hiddenKeys[STATE] = true; + set = function (it, metadata) { + if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty(it, STATE, metadata); + return metadata; + }; + get = function (it) { + return hasOwn(it, STATE) ? it[STATE] : {}; + }; + has = function (it) { + return hasOwn(it, STATE); + }; +} + +module.exports = { + set: set, + get: get, + has: has, + enforce: enforce, + getterFor: getterFor +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-array.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/is-array.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var classof = __webpack_require__(/*! ../internals/classof-raw */ "../node_modules/core-js/internals/classof-raw.js"); + +// `IsArray` abstract operation +// https://tc39.es/ecma262/#sec-isarray +// eslint-disable-next-line es/no-array-isarray -- safe +module.exports = Array.isArray || function isArray(argument) { + return classof(argument) === 'Array'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-callable.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/internals/is-callable.js ***! + \********************************************************/ +/***/ ((module) => { + +"use strict"; + +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot +var documentAll = typeof document == 'object' && document.all; + +// `IsCallable` abstract operation +// https://tc39.es/ecma262/#sec-iscallable +// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing +module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) { + return typeof argument == 'function' || argument === documentAll; +} : function (argument) { + return typeof argument == 'function'; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-forced.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-forced.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var replacement = /#|\.prototype\./; + +var isForced = function (feature, detection) { + var value = data[normalize(feature)]; + return value === POLYFILL ? true + : value === NATIVE ? false + : isCallable(detection) ? fails(detection) + : !!detection; +}; + +var normalize = isForced.normalize = function (string) { + return String(string).replace(replacement, '.').toLowerCase(); +}; + +var data = isForced.data = {}; +var NATIVE = isForced.NATIVE = 'N'; +var POLYFILL = isForced.POLYFILL = 'P'; + +module.exports = isForced; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-null-or-undefined.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/is-null-or-undefined.js ***! + \*****************************************************************/ +/***/ ((module) => { + +"use strict"; + +// we can't use just `it == null` since of `document.all` special case +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec +module.exports = function (it) { + return it === null || it === undefined; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +module.exports = function (it) { + return typeof it == 'object' ? it !== null : isCallable(it); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-pure.js": +/*!****************************************************!*\ + !*** ../node_modules/core-js/internals/is-pure.js ***! + \****************************************************/ +/***/ ((module) => { + +"use strict"; + +module.exports = false; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/is-symbol.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/is-symbol.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isPrototypeOf = __webpack_require__(/*! ../internals/object-is-prototype-of */ "../node_modules/core-js/internals/object-is-prototype-of.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var $Object = Object; + +module.exports = USE_SYMBOL_AS_UID ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + var $Symbol = getBuiltIn('Symbol'); + return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/length-of-array-like.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/length-of-array-like.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toLength = __webpack_require__(/*! ../internals/to-length */ "../node_modules/core-js/internals/to-length.js"); + +// `LengthOfArrayLike` abstract operation +// https://tc39.es/ecma262/#sec-lengthofarraylike +module.exports = function (obj) { + return toLength(obj.length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/make-built-in.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/make-built-in.js ***! + \**********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(/*! ../internals/function-name */ "../node_modules/core-js/internals/function-name.js").CONFIGURABLE); +var inspectSource = __webpack_require__(/*! ../internals/inspect-source */ "../node_modules/core-js/internals/inspect-source.js"); +var InternalStateModule = __webpack_require__(/*! ../internals/internal-state */ "../node_modules/core-js/internals/internal-state.js"); + +var enforceInternalState = InternalStateModule.enforce; +var getInternalState = InternalStateModule.get; +var $String = String; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; +var stringSlice = uncurryThis(''.slice); +var replace = uncurryThis(''.replace); +var join = uncurryThis([].join); + +var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () { + return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; +}); + +var TEMPLATE = String(String).split('String'); + +var makeBuiltIn = module.exports = function (value, name, options) { + if (stringSlice($String(name), 0, 7) === 'Symbol(') { + name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']'; + } + if (options && options.getter) name = 'get ' + name; + if (options && options.setter) name = 'set ' + name; + if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) { + if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true }); + else value.name = name; + } + if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { + defineProperty(value, 'length', { value: options.arity }); + } + try { + if (options && hasOwn(options, 'constructor') && options.constructor) { + if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false }); + // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable + } else if (value.prototype) value.prototype = undefined; + } catch (error) { /* empty */ } + var state = enforceInternalState(value); + if (!hasOwn(state, 'source')) { + state.source = join(TEMPLATE, typeof name == 'string' ? name : ''); + } return value; +}; + +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +// eslint-disable-next-line no-extend-native -- required +Function.prototype.toString = makeBuiltIn(function toString() { + return isCallable(this) && getInternalState(this).source || inspectSource(this); +}, 'toString'); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/math-trunc.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/math-trunc.js ***! + \*******************************************************/ +/***/ ((module) => { + +"use strict"; + +var ceil = Math.ceil; +var floor = Math.floor; + +// `Math.trunc` method +// https://tc39.es/ecma262/#sec-math.trunc +// eslint-disable-next-line es/no-math-trunc -- safe +module.exports = Math.trunc || function trunc(x) { + var n = +x; + return (n > 0 ? floor : ceil)(n); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-define-property.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-define-property.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); +var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(/*! ../internals/v8-prototype-define-bug */ "../node_modules/core-js/internals/v8-prototype-define-bug.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var $defineProperty = Object.defineProperty; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var ENUMERABLE = 'enumerable'; +var CONFIGURABLE = 'configurable'; +var WRITABLE = 'writable'; + +// `Object.defineProperty` method +// https://tc39.es/ecma262/#sec-object.defineproperty +exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor(O, P); + if (current && current[WRITABLE]) { + O[P] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } return $defineProperty(O, P, Attributes); +} : $defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return $defineProperty(O, P, Attributes); + } catch (error) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-descriptor.js": +/*!*******************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-descriptor.js ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var propertyIsEnumerableModule = __webpack_require__(/*! ../internals/object-property-is-enumerable */ "../node_modules/core-js/internals/object-property-is-enumerable.js"); +var createPropertyDescriptor = __webpack_require__(/*! ../internals/create-property-descriptor */ "../node_modules/core-js/internals/create-property-descriptor.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var toPropertyKey = __webpack_require__(/*! ../internals/to-property-key */ "../node_modules/core-js/internals/to-property-key.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var IE8_DOM_DEFINE = __webpack_require__(/*! ../internals/ie8-dom-define */ "../node_modules/core-js/internals/ie8-dom-define.js"); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// `Object.getOwnPropertyDescriptor` method +// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor +exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject(O); + P = toPropertyKey(P); + if (IE8_DOM_DEFINE) try { + return $getOwnPropertyDescriptor(O, P); + } catch (error) { /* empty */ } + if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-names.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-names.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + +var internalObjectKeys = __webpack_require__(/*! ../internals/object-keys-internal */ "../node_modules/core-js/internals/object-keys-internal.js"); +var enumBugKeys = __webpack_require__(/*! ../internals/enum-bug-keys */ "../node_modules/core-js/internals/enum-bug-keys.js"); + +var hiddenKeys = enumBugKeys.concat('length', 'prototype'); + +// `Object.getOwnPropertyNames` method +// https://tc39.es/ecma262/#sec-object.getownpropertynames +// eslint-disable-next-line es/no-object-getownpropertynames -- safe +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return internalObjectKeys(O, hiddenKeys); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-get-own-property-symbols.js": +/*!****************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-get-own-property-symbols.js ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe +exports.f = Object.getOwnPropertySymbols; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-is-prototype-of.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/object-is-prototype-of.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +module.exports = uncurryThis({}.isPrototypeOf); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-keys-internal.js": +/*!*****************************************************************!*\ + !*** ../node_modules/core-js/internals/object-keys-internal.js ***! + \*****************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var toIndexedObject = __webpack_require__(/*! ../internals/to-indexed-object */ "../node_modules/core-js/internals/to-indexed-object.js"); +var indexOf = (__webpack_require__(/*! ../internals/array-includes */ "../node_modules/core-js/internals/array-includes.js").indexOf); +var hiddenKeys = __webpack_require__(/*! ../internals/hidden-keys */ "../node_modules/core-js/internals/hidden-keys.js"); + +var push = uncurryThis([].push); + +module.exports = function (object, names) { + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key; + for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key); + // Don't enum bug & hidden keys + while (names.length > i) if (hasOwn(O, key = names[i++])) { + ~indexOf(result, key) || push(result, key); + } + return result; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/object-property-is-enumerable.js": +/*!**************************************************************************!*\ + !*** ../node_modules/core-js/internals/object-property-is-enumerable.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +var $propertyIsEnumerable = {}.propertyIsEnumerable; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Nashorn ~ JDK8 bug +var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1); + +// `Object.prototype.propertyIsEnumerable` method implementation +// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable +exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) { + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; +} : $propertyIsEnumerable; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/ordinary-to-primitive.js": +/*!******************************************************************!*\ + !*** ../node_modules/core-js/internals/ordinary-to-primitive.js ***! + \******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); + +var $TypeError = TypeError; + +// `OrdinaryToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-ordinarytoprimitive +module.exports = function (input, pref) { + var fn, val; + if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val; + if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + throw new $TypeError("Can't convert object to primitive value"); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/own-keys.js": +/*!*****************************************************!*\ + !*** ../node_modules/core-js/internals/own-keys.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var getBuiltIn = __webpack_require__(/*! ../internals/get-built-in */ "../node_modules/core-js/internals/get-built-in.js"); +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); +var getOwnPropertyNamesModule = __webpack_require__(/*! ../internals/object-get-own-property-names */ "../node_modules/core-js/internals/object-get-own-property-names.js"); +var getOwnPropertySymbolsModule = __webpack_require__(/*! ../internals/object-get-own-property-symbols */ "../node_modules/core-js/internals/object-get-own-property-symbols.js"); +var anObject = __webpack_require__(/*! ../internals/an-object */ "../node_modules/core-js/internals/an-object.js"); + +var concat = uncurryThis([].concat); + +// all object keys, includes non-enumerable and symbols +module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { + var keys = getOwnPropertyNamesModule.f(anObject(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/require-object-coercible.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/require-object-coercible.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var isNullOrUndefined = __webpack_require__(/*! ../internals/is-null-or-undefined */ "../node_modules/core-js/internals/is-null-or-undefined.js"); + +var $TypeError = TypeError; + +// `RequireObjectCoercible` abstract operation +// https://tc39.es/ecma262/#sec-requireobjectcoercible +module.exports = function (it) { + if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it); + return it; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-key.js": +/*!*******************************************************!*\ + !*** ../node_modules/core-js/internals/shared-key.js ***! + \*******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); + +var keys = shared('keys'); + +module.exports = function (key) { + return keys[key] || (keys[key] = uid(key)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared-store.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/shared-store.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var IS_PURE = __webpack_require__(/*! ../internals/is-pure */ "../node_modules/core-js/internals/is-pure.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var defineGlobalProperty = __webpack_require__(/*! ../internals/define-global-property */ "../node_modules/core-js/internals/define-global-property.js"); + +var SHARED = '__core-js_shared__'; +var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {}); + +(store.versions || (store.versions = [])).push({ + version: '3.38.1', + mode: IS_PURE ? 'pure' : 'global', + copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)', + license: 'https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE', + source: 'https://github.com/zloirock/core-js' +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/shared.js": +/*!***************************************************!*\ + !*** ../node_modules/core-js/internals/shared.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var store = __webpack_require__(/*! ../internals/shared-store */ "../node_modules/core-js/internals/shared-store.js"); + +module.exports = function (key, value) { + return store[key] || (store[key] = value || {}); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/symbol-constructor-detection.js": +/*!*************************************************************************!*\ + !*** ../node_modules/core-js/internals/symbol-constructor-detection.js ***! + \*************************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var V8_VERSION = __webpack_require__(/*! ../internals/environment-v8-version */ "../node_modules/core-js/internals/environment-v8-version.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); + +var $String = globalThis.String; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing +module.exports = !!Object.getOwnPropertySymbols && !fails(function () { + var symbol = Symbol('symbol detection'); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will, + // of course, fail. + return !$String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION && V8_VERSION < 41; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-absolute-index.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-absolute-index.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var max = Math.max; +var min = Math.min; + +// Helper for a popular repeating case of the spec: +// Let integer be ? ToInteger(index). +// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). +module.exports = function (index, length) { + var integer = toIntegerOrInfinity(index); + return integer < 0 ? max(integer + length, 0) : min(integer, length); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-indexed-object.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/to-indexed-object.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +// toObject with fallback for non-array-like ES3 strings +var IndexedObject = __webpack_require__(/*! ../internals/indexed-object */ "../node_modules/core-js/internals/indexed-object.js"); +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +module.exports = function (it) { + return IndexedObject(requireObjectCoercible(it)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-integer-or-infinity.js": +/*!*******************************************************************!*\ + !*** ../node_modules/core-js/internals/to-integer-or-infinity.js ***! + \*******************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var trunc = __webpack_require__(/*! ../internals/math-trunc */ "../node_modules/core-js/internals/math-trunc.js"); + +// `ToIntegerOrInfinity` abstract operation +// https://tc39.es/ecma262/#sec-tointegerorinfinity +module.exports = function (argument) { + var number = +argument; + // eslint-disable-next-line no-self-compare -- NaN check + return number !== number || number === 0 ? 0 : trunc(number); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-length.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-length.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(/*! ../internals/to-integer-or-infinity */ "../node_modules/core-js/internals/to-integer-or-infinity.js"); + +var min = Math.min; + +// `ToLength` abstract operation +// https://tc39.es/ecma262/#sec-tolength +module.exports = function (argument) { + var len = toIntegerOrInfinity(argument); + return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-object.js": +/*!******************************************************!*\ + !*** ../node_modules/core-js/internals/to-object.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var requireObjectCoercible = __webpack_require__(/*! ../internals/require-object-coercible */ "../node_modules/core-js/internals/require-object-coercible.js"); + +var $Object = Object; + +// `ToObject` abstract operation +// https://tc39.es/ecma262/#sec-toobject +module.exports = function (argument) { + return $Object(requireObjectCoercible(argument)); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-primitive.js": +/*!*********************************************************!*\ + !*** ../node_modules/core-js/internals/to-primitive.js ***! + \*********************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var call = __webpack_require__(/*! ../internals/function-call */ "../node_modules/core-js/internals/function-call.js"); +var isObject = __webpack_require__(/*! ../internals/is-object */ "../node_modules/core-js/internals/is-object.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); +var getMethod = __webpack_require__(/*! ../internals/get-method */ "../node_modules/core-js/internals/get-method.js"); +var ordinaryToPrimitive = __webpack_require__(/*! ../internals/ordinary-to-primitive */ "../node_modules/core-js/internals/ordinary-to-primitive.js"); +var wellKnownSymbol = __webpack_require__(/*! ../internals/well-known-symbol */ "../node_modules/core-js/internals/well-known-symbol.js"); + +var $TypeError = TypeError; +var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); + +// `ToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-toprimitive +module.exports = function (input, pref) { + if (!isObject(input) || isSymbol(input)) return input; + var exoticToPrim = getMethod(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = call(exoticToPrim, input, pref); + if (!isObject(result) || isSymbol(result)) return result; + throw new $TypeError("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/to-property-key.js": +/*!************************************************************!*\ + !*** ../node_modules/core-js/internals/to-property-key.js ***! + \************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ "../node_modules/core-js/internals/to-primitive.js"); +var isSymbol = __webpack_require__(/*! ../internals/is-symbol */ "../node_modules/core-js/internals/is-symbol.js"); + +// `ToPropertyKey` abstract operation +// https://tc39.es/ecma262/#sec-topropertykey +module.exports = function (argument) { + var key = toPrimitive(argument, 'string'); + return isSymbol(key) ? key : key + ''; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/try-to-string.js": +/*!**********************************************************!*\ + !*** ../node_modules/core-js/internals/try-to-string.js ***! + \**********************************************************/ +/***/ ((module) => { + +"use strict"; + +var $String = String; + +module.exports = function (argument) { + try { + return $String(argument); + } catch (error) { + return 'Object'; + } +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/uid.js": +/*!************************************************!*\ + !*** ../node_modules/core-js/internals/uid.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var uncurryThis = __webpack_require__(/*! ../internals/function-uncurry-this */ "../node_modules/core-js/internals/function-uncurry-this.js"); + +var id = 0; +var postfix = Math.random(); +var toString = uncurryThis(1.0.toString); + +module.exports = function (key) { + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); +}; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/use-symbol-as-uid.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/use-symbol-as-uid.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); + +module.exports = NATIVE_SYMBOL + && !Symbol.sham + && typeof Symbol.iterator == 'symbol'; + + +/***/ }), + +/***/ "../node_modules/core-js/internals/v8-prototype-define-bug.js": +/*!********************************************************************!*\ + !*** ../node_modules/core-js/internals/v8-prototype-define-bug.js ***! + \********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ "../node_modules/core-js/internals/descriptors.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +// V8 ~ Chrome 36- +// https://bugs.chromium.org/p/v8/issues/detail?id=3334 +module.exports = DESCRIPTORS && fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype !== 42; +}); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/weak-map-basic-detection.js": +/*!*********************************************************************!*\ + !*** ../node_modules/core-js/internals/weak-map-basic-detection.js ***! + \*********************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var isCallable = __webpack_require__(/*! ../internals/is-callable */ "../node_modules/core-js/internals/is-callable.js"); + +var WeakMap = globalThis.WeakMap; + +module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap)); + + +/***/ }), + +/***/ "../node_modules/core-js/internals/well-known-symbol.js": +/*!**************************************************************!*\ + !*** ../node_modules/core-js/internals/well-known-symbol.js ***! + \**************************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var globalThis = __webpack_require__(/*! ../internals/global-this */ "../node_modules/core-js/internals/global-this.js"); +var shared = __webpack_require__(/*! ../internals/shared */ "../node_modules/core-js/internals/shared.js"); +var hasOwn = __webpack_require__(/*! ../internals/has-own-property */ "../node_modules/core-js/internals/has-own-property.js"); +var uid = __webpack_require__(/*! ../internals/uid */ "../node_modules/core-js/internals/uid.js"); +var NATIVE_SYMBOL = __webpack_require__(/*! ../internals/symbol-constructor-detection */ "../node_modules/core-js/internals/symbol-constructor-detection.js"); +var USE_SYMBOL_AS_UID = __webpack_require__(/*! ../internals/use-symbol-as-uid */ "../node_modules/core-js/internals/use-symbol-as-uid.js"); + +var Symbol = globalThis.Symbol; +var WellKnownSymbolsStore = shared('wks'); +var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid; + +module.exports = function (name) { + if (!hasOwn(WellKnownSymbolsStore, name)) { + WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name) + ? Symbol[name] + : createWellKnownSymbol('Symbol.' + name); + } return WellKnownSymbolsStore[name]; +}; + + +/***/ }), + +/***/ "../node_modules/core-js/modules/es.array.push.js": +/*!********************************************************!*\ + !*** ../node_modules/core-js/modules/es.array.push.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + +var $ = __webpack_require__(/*! ../internals/export */ "../node_modules/core-js/internals/export.js"); +var toObject = __webpack_require__(/*! ../internals/to-object */ "../node_modules/core-js/internals/to-object.js"); +var lengthOfArrayLike = __webpack_require__(/*! ../internals/length-of-array-like */ "../node_modules/core-js/internals/length-of-array-like.js"); +var setArrayLength = __webpack_require__(/*! ../internals/array-set-length */ "../node_modules/core-js/internals/array-set-length.js"); +var doesNotExceedSafeInteger = __webpack_require__(/*! ../internals/does-not-exceed-safe-integer */ "../node_modules/core-js/internals/does-not-exceed-safe-integer.js"); +var fails = __webpack_require__(/*! ../internals/fails */ "../node_modules/core-js/internals/fails.js"); + +var INCORRECT_TO_LENGTH = fails(function () { + return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; +}); + +// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError +// https://bugs.chromium.org/p/v8/issues/detail?id=12681 +var properErrorOnNonWritableLength = function () { + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).push(); + } catch (error) { + return error instanceof TypeError; + } +}; + +var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); + +// `Array.prototype.push` method +// https://tc39.es/ecma262/#sec-array.prototype.push +$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + push: function push(item) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var argCount = arguments.length; + doesNotExceedSafeInteger(len + argCount); + for (var i = 0; i < argCount; i++) { + O[len] = arguments[i]; + len++; + } + setArrayLength(O, len); + return len; + } +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames not based on template +/******/ if (chunkId === "mega-menu-editor") return "" + chunkId + ".be91c0f96af4174d83d0.bundle.js"; +/******/ if (chunkId === "nested-carousel-editor") return "" + chunkId + ".0df35e0e1a284d4bd18b.bundle.js"; +/******/ if (chunkId === "loop-filter-editor") return "" + chunkId + ".46a4c013b80a381a50c9.bundle.js"; +/******/ if (chunkId === "off-canvas-editor") return "" + chunkId + ".d30e3b4fb19101e5ff36.bundle.js"; +/******/ if (chunkId === "modules_query-control_assets_js_editor_template-query-control_js") return "36c2990924ec9596ffad.bundle.js"; +/******/ // return url for filenames based on template +/******/ return undefined; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/load script */ +/******/ (() => { +/******/ var inProgress = {}; +/******/ var dataWebpackPrefix = "elementor-pro:"; +/******/ // loadScript function to load a script via script tag +/******/ __webpack_require__.l = (url, done, key, chunkId) => { +/******/ if(inProgress[url]) { inProgress[url].push(done); return; } +/******/ var script, needAttach; +/******/ if(key !== undefined) { +/******/ var scripts = document.getElementsByTagName("script"); +/******/ for(var i = 0; i < scripts.length; i++) { +/******/ var s = scripts[i]; +/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } +/******/ } +/******/ } +/******/ if(!script) { +/******/ needAttach = true; +/******/ script = document.createElement('script'); +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); +/******/ +/******/ script.src = url; +/******/ } +/******/ inProgress[url] = [done]; +/******/ var onScriptComplete = (prev, event) => { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var doneFns = inProgress[url]; +/******/ delete inProgress[url]; +/******/ script.parentNode && script.parentNode.removeChild(script); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); +/******/ if(prev) return prev(event); +/******/ } +/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); +/******/ script.onerror = onScriptComplete.bind(null, script.onerror); +/******/ script.onload = onScriptComplete.bind(null, script.onload); +/******/ needAttach && document.head.appendChild(script); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ var scriptUrl; +/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + ""; +/******/ var document = __webpack_require__.g.document; +/******/ if (!scriptUrl && document) { +/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') +/******/ scriptUrl = document.currentScript.src; +/******/ if (!scriptUrl) { +/******/ var scripts = document.getElementsByTagName("script"); +/******/ if(scripts.length) { +/******/ var i = scripts.length - 1; +/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src; +/******/ } +/******/ } +/******/ } +/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration +/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic. +/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser"); +/******/ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"); +/******/ __webpack_require__.p = scriptUrl; +/******/ })(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "editor": 0 +/******/ }; +/******/ +/******/ __webpack_require__.f.j = (chunkId, promises) => { +/******/ // JSONP chunk loading for javascript +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ if(true) { // all chunks have JS +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ var loadingEnded = (event) => { +/******/ if(__webpack_require__.o(installedChunks, chunkId)) { +/******/ installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; +/******/ if(installedChunkData) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ installedChunkData[1](error); +/******/ } +/******/ } +/******/ }; +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); +/******/ } +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ +/******/ // no on chunks loaded +/******/ +/******/ // install a JSONP callback for chunk loading +/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { +/******/ var [chunkIds, moreModules, runtime] = data; +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ var chunkLoadingGlobal = self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []; +/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); +/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!*****************************************!*\ + !*** ../assets/dev/js/editor/editor.js ***! + \*****************************************/ +/* provided dependency */ var __ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n")["__"]; + + +var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); +var _editor = _interopRequireDefault(__webpack_require__(/*! ../../../../modules/custom-css/assets/js/editor/editor */ "../modules/custom-css/assets/js/editor/editor.js")); +var _editor2 = _interopRequireDefault(__webpack_require__(/*! ../../../../modules/motion-fx/assets/js/editor/editor */ "../modules/motion-fx/assets/js/editor/editor.js")); +var _module = _interopRequireDefault(__webpack_require__(/*! modules/popup/assets/js/editor/module */ "../modules/popup/assets/js/editor/module.js")); +var _module2 = _interopRequireDefault(__webpack_require__(/*! modules/global-widget/assets/js/editor/module */ "../modules/global-widget/assets/js/editor/module.js")); +var _module3 = _interopRequireDefault(__webpack_require__(/*! modules/theme-builder/assets/js/editor/module */ "../modules/theme-builder/assets/js/editor/module.js")); +var _module4 = _interopRequireDefault(__webpack_require__(/*! modules/forms/assets/js/editor/module */ "../modules/forms/assets/js/editor/module.js")); +var _module5 = _interopRequireDefault(__webpack_require__(/*! modules/screenshots/assets/js/editor/module */ "../modules/screenshots/assets/js/editor/module.js")); +var _editor3 = _interopRequireDefault(__webpack_require__(/*! ../../../../core/app/modules/site-editor/assets/js/editor */ "../core/app/modules/site-editor/assets/js/editor.js")); +var _module6 = _interopRequireDefault(__webpack_require__(/*! modules/video-playlist/assets/js/editor/module */ "../modules/video-playlist/assets/js/editor/module.js")); +var _module7 = _interopRequireDefault(__webpack_require__(/*! modules/woocommerce/assets/js/editor/module */ "../modules/woocommerce/assets/js/editor/module.js")); +var _module8 = _interopRequireDefault(__webpack_require__(/*! modules/scroll-snap/assets/js/editor/module */ "../modules/scroll-snap/assets/js/editor/module.js")); +var _module9 = _interopRequireDefault(__webpack_require__(/*! modules/payments/assets/js/editor/module */ "../modules/payments/assets/js/editor/module.js")); +var _module10 = _interopRequireDefault(__webpack_require__(/*! modules/loop-builder/assets/js/editor/module */ "../modules/loop-builder/assets/js/editor/module.js")); +var _tiers = __webpack_require__(/*! ./tiers */ "../assets/dev/js/editor/tiers.js"); +var _notesContextMenu = _interopRequireDefault(__webpack_require__(/*! modules/notes/assets/js/notes-context-menu */ "../modules/notes/assets/js/notes-context-menu.js")); +var _module11 = _interopRequireDefault(__webpack_require__(/*! modules/page-transitions/assets/js/editor/module */ "../modules/page-transitions/assets/js/editor/module.js")); +var ElementorPro = Marionette.Application.extend({ + config: {}, + modules: {}, + initModules() { + var QueryControl = __webpack_require__(/*! modules/query-control/assets/js/editor */ "../modules/query-control/assets/js/editor.js"), + Library = __webpack_require__(/*! modules/library/assets/js/editor */ "../modules/library/assets/js/editor.js"), + FlipBox = __webpack_require__(/*! modules/flip-box/assets/js/editor/editor */ "../modules/flip-box/assets/js/editor/editor.js"), + ShareButtons = __webpack_require__(/*! modules/share-buttons/assets/js/editor/editor */ "../modules/share-buttons/assets/js/editor/editor.js"), + AssetsManager = __webpack_require__(/*! modules/assets-manager/assets/js/editor/editor */ "../modules/assets-manager/assets/js/editor/editor.js"), + ThemeElements = __webpack_require__(/*! modules/theme-elements/assets/js/editor/editor */ "../modules/theme-elements/assets/js/editor/editor.js"); + this.modules = { + queryControl: new QueryControl(), + forms: new _module4.default(), + library: new Library(), + customCSS: new _editor.default(), + globalWidget: new _module2.default(), + flipBox: new FlipBox(), + motionFX: new _editor2.default(), + shareButtons: new ShareButtons(), + assetsManager: new AssetsManager(), + themeElements: new ThemeElements(), + themeBuilder: new _module3.default(), + siteEditor: new _editor3.default(), + screenshots: new _module5.default(), + woocommerce: new _module7.default(), + stripe: new _module9.default(), + loopBuilder: new _module10.default(), + pageTransitions: new _module11.default(), + // Popup is depended on Theme Builder. + popup: new _module.default(), + videoPlaylistModule: new _module6.default(), + ScrollSnapModule: new _module8.default() + }; + if (elementorCommon.config.experimentalFeatures['mega-menu']) { + elementorCommon.elements.$window.on('elementor/nested-element-type-loaded', async () => { + // The module should be loaded only when `nestedElements` is available. + this.modules.megaMenu = new (await __webpack_require__.e(/*! import() | mega-menu-editor */ "mega-menu-editor").then(__webpack_require__.bind(__webpack_require__, /*! modules/mega-menu/assets/js/editor/module */ "../modules/mega-menu/assets/js/editor/module.js"))).default(); + }); + } + if (elementorCommon.config.experimentalFeatures['nested-elements']) { + elementorCommon.elements.$window.on('elementor/nested-element-type-loaded', async () => { + // The module should be loaded only when `nestedElements` is available. + this.modules.nestedCarousel = new (await __webpack_require__.e(/*! import() | nested-carousel-editor */ "nested-carousel-editor").then(__webpack_require__.bind(__webpack_require__, /*! modules/nested-carousel/assets/js/editor/module */ "../modules/nested-carousel/assets/js/editor/module.js"))).default(); + }); + } + __webpack_require__.e(/*! import() | loop-filter-editor */ "loop-filter-editor").then(__webpack_require__.bind(__webpack_require__, /*! modules/loop-filter/assets/js/editor/module */ "../modules/loop-filter/assets/js/editor/module.js")).then(({ + default: LoopFilter + }) => { + this.modules.loopFilter = new LoopFilter(); + }); + if (elementorCommon.config.experimentalFeatures['nested-elements']) { + elementorCommon.elements.$window.on('elementor/nested-element-type-loaded', async () => { + // The module should be loaded only when `nestedElements` is available. + this.modules.offCanvas = new (await __webpack_require__.e(/*! import() | off-canvas-editor */ "off-canvas-editor").then(__webpack_require__.bind(__webpack_require__, /*! modules/off-canvas/assets/js/editor/module */ "../modules/off-canvas/assets/js/editor/module.js"))).default(); + }); + } + }, + ajax: { + prepareArgs(args) { + args[0] = 'pro_' + args[0]; + return args; + }, + send() { + return elementorCommon.ajax.send.apply(elementorCommon.ajax, this.prepareArgs(arguments)); + }, + addRequest() { + return elementorCommon.ajax.addRequest.apply(elementorCommon.ajax, this.prepareArgs(arguments)); + } + }, + translate(stringKey, templateArgs) { + return elementorCommon.translate(stringKey, null, templateArgs, this.config.i18n); + }, + onStart() { + this.config = elementorProEditorConfig; + this.initModules(); + jQuery(window).on('elementor:init', () => this.onElementorInit()).on('elementor/connect/success/editor-pro-activate', this.onActivateSuccess); + }, + onElementorInit() { + elementor.on('preview:loaded', () => this.onElementorPreviewLoaded()); + elementorPro.libraryRemoveGetProButtons(); + elementorCommon.debug.addURLToWatch('elementor-pro/assets'); + if (elementorPro.config.should_show_promotion) { + new _notesContextMenu.default(); + } + }, + onElementorPreviewLoaded() { + elementor.$preview[0].contentWindow.elementorPro = this; + }, + libraryRemoveGetProButtons() { + elementor.hooks.addFilter('elementor/editor/template-library/template/action-button', (viewID, templateData) => { + if (!templateData.accessTier || !elementor.config?.library_connect?.current_access_tier) { + // BC support. + return this.getProButtonViewIdBC(viewID, templateData); + } + const isProTemplate = templateData.accessTier !== elementor.config.library_connect.base_access_tier; + if (isProTemplate && !elementorPro.config.isActive) { + return '#tmpl-elementor-pro-template-library-activate-license-button'; + } + const canInsert = (0, _tiers.isTierAtLeast)(elementor.config.library_connect.current_access_tier, templateData.accessTier); + return canInsert ? '#tmpl-elementor-template-library-insert-button' : viewID; + }); + }, + getProButtonViewIdBC(viewID, templateData) { + // When the template should be at least "pro" and the license is not active. + if (templateData.accessLevel > 0 && !elementorPro.config.isActive) { + return '#tmpl-elementor-pro-template-library-activate-license-button'; + } + + // When the template access levels is greater than the current license access level it should + // return the "core" view template which is by default "go pro" or "go expert" button. + if (templateData.accessLevel > elementor.config.library_connect.current_access_level) { + return viewID; + } + + // When the current license can insert the template. + return '#tmpl-elementor-template-library-insert-button'; + }, + onActivateSuccess() { + // Hide notice. + elementor.noticeBar.onCloseClick(); + + // Mark site connect for insert templates connect screen. + elementor.config.library_connect.is_connected = true; + + // Mark pro is active - for `this.libraryRemoveGetProButtons`. + elementorPro.config.isActive = true; + elementor.notifications.showToast({ + message: __('Connected Successfully', 'elementor-pro') + }); + } +}); +window.elementorPro = new ElementorPro(); +elementorPro.start(); +})(); + +/******/ })() +; +//# sourceMappingURL=editor.js.map \ No newline at end of file diff --git a/assets/js/editor.min.js b/assets/js/editor.min.js new file mode 100644 index 00000000..69f77039 --- /dev/null +++ b/assets/js/editor.min.js @@ -0,0 +1,2 @@ +/*! pro-elements - v3.33.0 - 11-11-2025 */ +(()=>{var e,t,o={7842:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({elementType:null,__construct(e){this.elementType=e,this.addEditorListener()},updateOptions(e,t){const o=this.getEditorControlView(e);o&&(this.getEditorControlModel(e).set("options",t),o.render())},addEditorListener(){var e=this;if(e.onElementChange){var t="change";"global"!==e.elementType&&(t+=":"+e.elementType),elementor.channels.editor.on(t,(function(t,o){e.onElementChange(t.model.get("name"),t,o)}))}},addControlSpinner(e){const t=this.getEditorControlView(e).$el;if(t.find(".elementor-control-spinner").length)return;t.find(":input").attr("disabled",!0),t.find(".elementor-control-title").after(' ')},removeControlSpinner(e){const t=this.getEditorControlView(e).$el;t.find(":input").attr("disabled",!1),t.find(".elementor-control-spinner").remove()},addControlError(e,t,o=".elementor-control-content"){const r=this.getEditorControlView(e).$el;r.find(".e-control-error").length&&r.find(".e-control-error").remove(),r.find(o).first().after(`${t}`)},removeControlError(e){this.getEditorControlView(e).$el.find(".e-control-error").remove()},resetControlIndicators(e){this.removeControlSpinner(e),this.removeControlError(e)},addSectionListener(e,t){const o=this;elementor.channels.editor.on("section:activated",(function(r,n){var i=n.getOption("editedElementView").getEditModel(),s=i.get("elType"),a=arguments;"widget"===s&&(s=i.get("widgetType")),o.elementType===s&&e===r&&setTimeout((function(){t.apply(o,a)}),10)}))}})},5184:e=>{"use strict";e.exports=elementorModules.editor.views.ControlsStack.extend({activeTab:"content",activeSection:"settings",initialize(){this.collection=new Backbone.Collection(_.values(this.options.controls))},filter(e){if("section"===e.get("type"))return!0;var t=e.get("section");return!t||t===this.activeSection},childViewOptions(){return{elementSettingsModel:this.model}}})},1570:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isTierAtLeast=t.TIERS_PRIORITY=void 0;const o=t.TIERS_PRIORITY=Object.freeze(["free","essential","essential-oct2023","advanced","expert","agency"]);t.isTierAtLeast=(e,t)=>{const r=o.indexOf(e),n=o.indexOf(t);return-1!==r&&-1!==n&&r>=n}},2098:(e,t,o)=>{"use strict";var r=o(2470).__;Object.defineProperty(t,"__esModule",{value:!0}),t.SAVE_CONTEXT=t.EDIT_CONTEXT=void 0,t.createElement=createElement,t.default=function addDocumentHandle({element:e,id:t,title:o=r("Template","elementor-pro")},l=s,d=null,u=null){if(s===l){if(!t||!e)throw Error("`id` and `element` are required.");if(function isCurrentlyEditing(e){return e.classList.contains(i)}(e)||function hasHandle(e){return!!e.querySelector(`:scope > .${n}`)}(e))return}const c=function createHandleElement({title:e,onClick:t},o,i=null){const l=["header","footer"].includes(i?.dataset.elementorType)?"%s":r("Edit %s","elementor-pro"),d=createElement({tag:"div",classNames:[`${n}__inner`],children:[createElement({tag:"i",classNames:[getHandleIcon(o)]}),createElement({tag:"div",classNames:[`${s===o?n:a}__title`],children:[document.createTextNode(s===o?l.replace("%s",e):r("Save %s","elementor-pro").replace("%s",e))]})]}),u=[n];s!==o&&u.push(a);const c=createElement({tag:"div",classNames:u,children:[d]});return c.addEventListener("click",t),c}({title:o,onClick:()=>async function onDocumentClick(e,t,o=null,r=null){s===t?(window.top.$e.internal("panel/state-loading"),await window.top.$e.run("editor/documents/switch",{id:parseInt(e),onClose:o,selector:r}),window.top.$e.internal("panel/state-ready")):(elementorCommon.api.internal("panel/state-loading"),elementorCommon.api.run("editor/documents/switch",{id:elementor.config.initial_document.id,mode:"save",shouldScroll:!1,selector:r}).finally((()=>elementorCommon.api.internal("panel/state-ready"))))}(t,l,d,u)},l,e);e.prepend(c),s===l&&(e.dataset.editableElementorDocument=t)},o(5724);const n="elementor-document-handle",i="elementor-edit-mode",s=t.EDIT_CONTEXT="edit",a="elementor-document-save-back-handle",l=t.SAVE_CONTEXT="save";function getHandleIcon(e){let t="eicon-edit";return l===e&&(t=elementorFrontend.config.is_rtl?"eicon-arrow-right":"eicon-arrow-left"),t}function createElement({tag:e,classNames:t=[],children:o=[]}){const r=document.createElement(e);return r.classList.add(...t),o.forEach((e=>r.appendChild(e))),r}},7952:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.ConditionsConfig=void 0;class ConditionsConfig extends $e.modules.CommandData{static signature="site-editor/conditions-config";static getEndpointFormat(){return"site-editor/conditions-config/{id}"}}t.ConditionsConfig=ConditionsConfig;t.default=ConditionsConfig},5559:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ConditionsConfig",{enumerable:!0,get:function(){return n.ConditionsConfig}}),Object.defineProperty(t,"Templates",{enumerable:!0,get:function(){return r.Templates}}),Object.defineProperty(t,"TemplatesConditions",{enumerable:!0,get:function(){return i.TemplatesConditions}}),Object.defineProperty(t,"TemplatesConditionsConflicts",{enumerable:!0,get:function(){return s.TemplatesConditionsConflicts}});var r=o(7636),n=o(7952),i=o(9591),s=o(7821)},7821:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditionsConflicts=void 0;class TemplatesConditionsConflicts extends $e.modules.CommandData{static signature="site-editor/templates-conditions-conflicts";static getEndpointFormat(){return`${TemplatesConditionsConflicts.signature}/{id}`}}t.TemplatesConditionsConflicts=TemplatesConditionsConflicts;t.default=TemplatesConditionsConflicts},9591:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.TemplatesConditions=void 0;class TemplatesConditions extends $e.modules.CommandData{static signature="site-editor/templates-conditions";static getEndpointFormat(){return"site-editor/templates-conditions/{id}"}}t.TemplatesConditions=TemplatesConditions;t.default=TemplatesConditions},7636:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Templates=void 0;class Templates extends $e.modules.CommandData{static signature="site-editor/templates";static getEndpointFormat(){return"site-editor/templates/{id}"}}t.Templates=Templates;t.default=Templates},2239:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var o=_getRequireWildcardCache(t);if(o&&o.has(e))return o.get(e);var r={__proto__:null},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var s=n?Object.getOwnPropertyDescriptor(e,i):null;s&&(s.get||s.set)?Object.defineProperty(r,i,s):r[i]=e[i]}return r.default=e,o&&o.set(e,r),r}(o(5559));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,o=new WeakMap;return(_getRequireWildcardCache=function(e){return e?o:t})(e)}class Component extends $e.modules.ComponentBase{static namespace="site-editor";getNamespace(){return this.constructor.namespace}defaultData(){return this.importCommands(r)}}t.default=Component},2146:(e,t,o)=>{"use strict";var r=o(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(o(2239)),i=o(5559);class Module extends elementorModules.editor.utils.Module{onElementorInit(){elementor.documents.getCurrent().config.support_site_editor&&($e.components.register(new n.default),$e.data.deleteCache($e.components.get(n.default.namespace),i.Templates.signature))}}t.default=Module},2100:(e,t,o)=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({onElementorInit(){var e=o(5334);this.assets={font:new e}}})},5334:(e,t,o)=>{"use strict";o(5724),e.exports=elementorModules.Module.extend({_enqueuedFonts:[],_enqueuedTypekit:!1,onFontChange(e,t){"custom"!==e&&"typekit"!==e&&"variable"!==e||-1===this._enqueuedFonts.indexOf(t)&&("typekit"===e&&this._enqueuedTypekit||this.getCustomFont(e,t))},getCustomFont(e,t){elementorPro.ajax.addRequest("assets_manager_panel_action_data",{unique_id:"font_"+e+t,data:{service:"font",type:e,font:t},success(e){e.font_face&&elementor.$previewContents.find("style").last().after('"),e.font_url&&elementor.$previewContents.find("link").last().after('')}}),this._enqueuedFonts.push(t),"typekit"===e&&(this._enqueuedTypekit=!0)},onInit(){elementor.channels.editor.on("font:insertion",this.onFontChange.bind(this))}})},6714:(e,t,o)=>{"use strict";var r=o(2470).__;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class _default extends elementorModules.editor.utils.Module{addCustomCss(e,t){if(!t)return;const o=t.model,r=o.get("settings").get("custom_css");let n=".elementor-element.elementor-element-"+o.get("id");return"document"===o.get("elType")&&(n=elementor.config.document.settings.cssWrapperSelector),r&&(e+=r.replace(/selector/g,n)),e}onElementorInit(){elementor.hooks.addFilter("editor/style/styleText",this.addCustomCss),elementor.on("navigator:init",this.onNavigatorInit.bind(this))}onNavigatorInit(){elementor.navigator.indicators.customCSS={icon:"code-bold",settingKeys:["custom_css"],title:r("Custom CSS","elementor-pro"),section:"section_custom_css"}}}t.default=_default},564:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({onElementorInit(){elementor.channels.editor.on("section:activated",this.onSectionActivated)},onSectionActivated(e,t){var o=t.getOption("editedElementView");if("flip-box"===o.model.get("widgetType")){var r=-1!==["section_side_b_content","section_style_b"].indexOf(e);o.$el.toggleClass("elementor-flip-box--flipped",r);var n=o.$el.find(".elementor-flip-box__back");r&&n.css("transition","none"),r||setTimeout((function(){n.css("transition","")}),10)}}})},1646:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var o=_getRequireWildcardCache(t);if(o&&o.has(e))return o.get(e);var r={__proto__:null},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if("default"!==i&&{}.hasOwnProperty.call(e,i)){var s=n?Object.getOwnPropertyDescriptor(e,i):null;s&&(s.get||s.set)?Object.defineProperty(r,i,s):r[i]=e[i]}return r.default=e,o&&o.set(e,r),r}(o(6570));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,o=new WeakMap;return(_getRequireWildcardCache=function(e){return e?o:t})(e)}class Component extends $e.modules.ComponentBase{getNamespace(){return"forms"}defaultHooks(){return this.importHooks(r)}}t.default=Component},8619:(e,t,o)=>{"use strict";var r=o(2470).__;e.exports=elementor.modules.controls.Repeater.extend({onBeforeRender(){this.$el.hide()},updateMap(e){var t=this,o={};t.collection.each((function(e){o[e.get("remote_id")]=e.get("local_id")})),t.collection.reset(),_.each(e,(function(e){var r={remote_id:e.remote_id,remote_label:e.remote_label,remote_type:e.remote_type?e.remote_type:"",remote_required:!!e.remote_required&&e.remote_required,local_id:o[e.remote_id]?o[e.remote_id]:""};t.collection.add(r)})),t.render()},onRender(){elementor.modules.controls.Base.prototype.onRender.apply(this,arguments);var e=this;e.children.each((function(t){var o=t.children.last(),n={"":"- "+r("None","elementor-pro")+" -"},i=t.model.get("remote_label");t.model.get("remote_required")&&(i+='*'),_.each(e.elementSettingsModel.get("form_fields").models,(function(e,o){var r=t.model.get("remote_type");"text"!==r&&r!==e.get("field_type")||(n[e.get("custom_id")]=e.get("field_label")||"Field #"+(o+1))})),o.model.set("label",i),o.model.set("options",n),o.render(),t.$el.find(".elementor-repeater-row-tools").hide(),t.$el.find(".elementor-repeater-row-controls").removeClass("elementor-repeater-row-controls").find(".elementor-control").css({paddingBottom:0})})),e.$el.find(".elementor-button-wrapper").remove(),e.children.length&&e.$el.show()}})},3253:(e,t,o)=>{"use strict";var r=o(6784)(o(2988));e.exports=class extends elementor.modules.controls.Repeater{className(){let e=super.className();return e+=" elementor-control-type-repeater",e}getChildView(){return r.default}initialize(...e){super.initialize(...e);const t=this.container.settings.get("form_fields");this.listenTo(t,"change",(e=>this.onFormFieldChange(e))).listenTo(t,"remove",(e=>this.onFormFieldRemove(e)))}getFirstChild(){return this.children.findByModel(this.collection.models[0])}lockFirstStep(){const e=this.getFirstChild();if("step"!==e.model.get("field_type"))return;11)return;const o=this.getFirstChild();if(1===t.length)return o.toggleTools(!0),void o.toggleFieldTypeControl(!0);o.toggleSort(!0)}onAddChild(e){super.onAddChild(e),"step"===e.model.get("field_type")&&(this.lockFirstStep(),e.toggleStepField(!0))}}},2988:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;class _default extends elementor.modules.controls.RepeaterRow{toggleFieldTypeControl(e){const t=this.collection.findWhere({name:"field_type"});this.children.findByModel(t).$el.toggle(e)}toggleStepField(e){this.$el.toggleClass("elementor-repeater-row--form-step",e)}toggleTools(e){this.ui.removeButton.add(this.ui.duplicateButton).toggle(e)}}t.default=_default},140:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({renderField(e,t,o,r){var n=_.escape(t.css_classes),i="",s="",a="";return t.required&&(i="required"),t.acceptance_text&&(s='"),t.checked_by_default&&(a=' checked="checked"'),'
    "+s+"
    "},onInit(){elementor.hooks.addFilter("elementor_pro/forms/content_template/field/acceptance",this.renderField,10,4)}})},431:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({renderField(e,t,o,r){var n=_.escape(t.css_classes),i="",s="",a="",l="";return t.required&&(i="required"),t.min_date&&(s=' min="'+t.min_date+'"'),t.max_date&&(a=' max="'+t.max_date+'"'),t.placeholder&&(l=' placeholder="'+t.placeholder+'"'),"yes"===t.use_native_date&&(n+=" elementor-use-native"),'"},onInit(){elementor.hooks.addFilter("elementor_pro/forms/content_template/field/date",this.renderField,10,4)}})},9738:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({renderField(e,t,o,r){var n=_.escape(t.css_classes),i="",s="";return t.required&&(i="required"),t.placeholder&&(s=' placeholder="'+t.placeholder+'"'),n="elementor-field-textual "+n,''},onInit(){elementor.hooks.addFilter("elementor_pro/forms/content_template/field/tel",this.renderField,10,4)}})},326:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({renderField(e,t,o,r){var n=_.escape(t.css_classes),i="",s="";return t.required&&(i="required"),t.placeholder&&(s=' placeholder="'+t.placeholder+'"'),"yes"===t.use_native_time&&(n+=" elementor-use-native"),'"},onInit(){elementor.hooks.addFilter("elementor_pro/forms/content_template/field/time",this.renderField,10,4)}})},7038:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({renderField(e,t,o,r){var n=_.escape(t.css_classes),i="",s="",a="form_field_";return t.required&&(i="required"),t.allow_multiple_upload&&(s=' multiple="multiple"',a+="[]"),'"},onInit(){elementor.hooks.addFilter("elementor_pro/forms/content_template/field/upload",this.renderField,10,4)}})},8636:(e,t,o)=>{"use strict";o(5724),e.exports=elementorModules.editor.utils.Module.extend({eventName:"site_mailer_forms_email_notice",suffix:"",control:null,onSectionActive(e){["section_email","section_email_2"].includes(e)&&(this.suffix="section_email_2"===e?"_2":"",this.control=null,this.hasPromoControl()&&(elementor.config.user.dismissed_editor_notices.includes("site_mailer_forms_email_notice")?this.getPromoControl().remove():this.registerEvents()))},registerEvents(){const e=this.getPromoControl().$el.find(".elementor-control-notice-dismiss"),onDismissBtnClick=t=>{e.off("click",onDismissBtnClick),t.preventDefault(),this.dismiss(),this.getPromoControl().remove()};e.on("click",onDismissBtnClick);const t=this.getPromoControl().$el.find(".e-btn-1"),onActionBtn=e=>{t.off("click",onActionBtn),e.preventDefault(),this.onAction(e),this.getPromoControl().remove()};t.on("click",onActionBtn)},getPromoControl(){return this.control||(this.control=this.getEditorControlView("site_mailer_promo"+this.suffix)),this.control},hasPromoControl(){return!!this.getPromoControl()},ajaxRequest(e,t){elementorCommon.ajax.addRequest(e,{data:t})},dismiss(){this.ajaxRequest("dismissed_editor_notices",{dismissId:this.eventName}),this.ensureNoPromoControlInSession()},ensureNoPromoControlInSession(){elementor.config.user.dismissed_editor_notices.push(this.eventName)},onAction(e){const{action_url:t=null}=JSON.parse(e.target.closest("button").dataset.settings);t&&window.open(t,"_blank"),this.ajaxRequest("elementor_site_mailer_campaign",{source:"sm-form-install"}),this.ensureNoPromoControlInSession()},onInit(){elementor.channels.editor.on("section:activated",(e=>this.onSectionActive(e)))}})},7601:(e,t,o)=>{"use strict";o(5724),e.exports=elementorModules.editor.utils.Module.extend({eventName:"send_app_forms_actions_notice",suffix:"",control:null,onSectionActive(e){this.isCurrentSection(e)&&(this.control=null,this.hasPromoControl()&&(this.isNoticeDismissed("send_app_forms_actions_notice")?this.getPromoControl().remove():this.registerEvents()))},isCurrentSection:e=>["section_integration"].includes(e),isNoticeDismissed:e=>elementor.config.user.dismissed_editor_notices.includes(e),registerEvents(){const e=this.getPromoControl().$el.find(".elementor-control-notice-dismiss"),onDismissBtnClick=t=>{e.off("click",onDismissBtnClick),t.preventDefault(),this.dismiss(),this.getPromoControl().remove()};e.on("click",onDismissBtnClick);const t=this.getPromoControl().$el.find(".e-btn-1"),onActionBtn=e=>{t.off("click",onActionBtn),e.preventDefault(),this.onAction(e),this.getPromoControl().remove()};t.on("click",onActionBtn)},getPromoControl(){return this.control||this.getEditorControlModel("send_app_promo"+this.suffix)&&(this.control=this.getEditorControlView("send_app_promo"+this.suffix)),this.control},hasPromoControl(){return!!this.getPromoControl()},ajaxRequest(e,t){elementorCommon.ajax.addRequest(e,{data:t})},dismiss(){this.ajaxRequest("dismissed_editor_notices",{dismissId:this.eventName}),this.ensureNoPromoControlInSession()},ensureNoPromoControlInSession(){elementor.config.user.dismissed_editor_notices.push(this.eventName)},onAction(e){const{action_url:t=null}=JSON.parse(e.currentTarget.dataset.settings);t&&window.open(t,"_blank"),this.ajaxRequest("elementor_send_app_campaign",{source:"snd-form-install"}),this.ensureNoPromoControlInSession()},onInit(){elementor.channels.editor.on("section:activated",(e=>this.onSectionActive(e)))}})},981:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.FormFieldsSanitizeCustomId=void 0;class FormFieldsSanitizeCustomId extends $e.modules.hookData.Dependency{ID_SANITIZE_FILTER=/[^\w]/g;getCommand(){return"document/elements/settings"}getId(){return"elementor-pro-forms-fields-sanitize-custom-id"}getContainerType(){return"repeater"}getConditions(e){return void 0!==e.settings.custom_id}apply(e){const{containers:t=[e.container],settings:o}=e,{custom_id:r}=o;return!r.match(this.ID_SANITIZE_FILTER)||(t.forEach((e=>{const t=e.panel.getControlView("form_fields").children.findByModel(e.settings).children.find((e=>"custom_id"===e.model.get("name")));t.render(),t.$el.find("input").trigger("focus")})),!1)}}t.FormFieldsSanitizeCustomId=FormFieldsSanitizeCustomId;t.default=FormFieldsSanitizeCustomId},752:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.FormFieldsSetCustomId=void 0;class FormFieldsSetCustomId extends $e.modules.hookData.After{getCommand(){return"document/repeater/insert"}getId(){return"elementor-pro-forms-fields-set-custom-id"}getContainerType(){return"widget"}getConditions(e){return"form_fields"===e.name}apply(e,t){const{containers:o=[e.container]}=e,r=$e.commands.isCurrentFirstTrace("document/repeater/duplicate");return o.forEach((e=>{const o=e.repeaters.form_fields.children.find((e=>!!e&&t.get("_id")===e.id));!r&&o.settings.get("custom_id")||$e.run("document/elements/settings",{container:o,settings:{custom_id:"field_"+o.id},options:{external:!0}})})),!0}}t.FormFieldsSetCustomId=FormFieldsSetCustomId;t.default=FormFieldsSetCustomId},9642:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.FormFieldsAddFirstStep=void 0;class FormFieldsAddFirstStep extends $e.modules.hookData.After{getCommand(){return"document/elements/settings"}getId(){return"elementor-pro-forms-fields-first-step"}getContainerType(){return"repeater"}getConditions(e){const{containers:t=[e.container]}=e;return"form"===t[0].parent.parent.model.get("widgetType")&&"step"===e.settings.field_type}apply(e){const{containers:t=[e.container]}=e;return t.forEach((e=>{"step"!==e.parent.children[0].settings.get("field_type")&&$e.run("document/repeater/insert",{container:e.parent.parent,name:"form_fields",model:{field_type:"step"},options:{at:0,external:!0}})})),!0}}t.FormFieldsAddFirstStep=FormFieldsAddFirstStep;t.default=FormFieldsAddFirstStep},4727:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.FormSanitizeId=void 0;class FormSanitizeId extends $e.modules.hookData.Dependency{ID_SANITIZE_FILTER=/[^\w]/g;getCommand(){return"document/elements/settings"}getId(){return"elementor-pro-forms-sanitize-id"}getContainerType(){return"widget"}getConditions(e){return void 0!==e.settings.form_id}apply(e){const{container:t,settings:o}=e,{form_id:r}=o;if(r.match(this.ID_SANITIZE_FILTER)){const e=t.panel.getControlView("form_id");return e.render(),e.$el.find("input").trigger("focus"),!1}return!0}}t.FormSanitizeId=FormSanitizeId;t.default=FormSanitizeId},735:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"FormFieldsAddFirstStep",{enumerable:!0,get:function(){return i.FormFieldsAddFirstStep}}),Object.defineProperty(t,"FormFieldsSanitizeCustomId",{enumerable:!0,get:function(){return r.FormFieldsSanitizeCustomId}}),Object.defineProperty(t,"FormFieldsSetCustomId",{enumerable:!0,get:function(){return n.FormFieldsSetCustomId}}),Object.defineProperty(t,"FormSanitizeId",{enumerable:!0,get:function(){return s.FormSanitizeId}});var r=o(981),n=o(752),i=o(9642),s=o(4727)},6570:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=o(735);Object.keys(r).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===r[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}}))}));var n=o(473);Object.keys(n).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===n[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return n[e]}}))}))},573:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.FormFieldsUpdateShortCode=void 0;class FormFieldsUpdateShortCode extends $e.modules.hookUI.After{getCommand(){return"document/elements/settings"}getId(){return"elementor-pro-forms-fields-update-shortcode"}getContainerType(){return"repeater"}getConditions(e){return!(!$e.routes.isPartOf("panel/editor")||void 0===e.settings.custom_id)}apply(e){const{containers:t=[e.container]}=e;t.forEach((e=>{e.panel.getControlView("form_fields").children.find((t=>e.id===t.model.get("_id"))).children.find((e=>"shortcode"===e.model.get("name"))).render()}))}}t.FormFieldsUpdateShortCode=FormFieldsUpdateShortCode;t.default=FormFieldsUpdateShortCode},473:(e,t,o)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"FormFieldsUpdateShortCode",{enumerable:!0,get:function(){return r.FormFieldsUpdateShortCode}});var r=o(573)},4857:(e,t,o)=>{"use strict";var r=o(2470).__;o(5724);var n=o(6236);e.exports=n.extend({fields:{},getName:()=>"activecampaign",onElementChange(e){switch(e){case"activecampaign_api_credentials_source":case"activecampaign_api_key":case"activecampaign_api_url":this.onApiUpdate();break;case"activecampaign_list":this.onListUpdate()}},onApiUpdate(){const e=this,t=e.getEditorControlView("activecampaign_api_key"),o=e.getEditorControlView("activecampaign_api_url"),r=e.getEditorControlView("activecampaign_api_credentials_source");if("default"!==r.getControlValue()&&(""===t.getControlValue()||""===o.getControlValue()))return e.updateOptions("activecampaign_list",[]),void e.getEditorControlView("activecampaign_list").setValue("");e.addControlSpinner("activecampaign_list");const n=this.getCacheKey({controls:[r.getControlValue(),o.getControlValue(),t.getControlValue()]});e.getActiveCampaignCache("lists","activecampaign_list",n).done((function(t){e.updateOptions("activecampaign_list",t.lists),e.fields=t.fields}))},onListUpdate(){this.updateFieldsMapping()},updateFieldsMapping(){if(this.getEditorControlView("activecampaign_list").getControlValue()){var e=[{remote_label:r("Email","elementor-pro"),remote_type:"email",remote_id:"email",remote_required:!0},{remote_label:r("First Name","elementor-pro"),remote_type:"text",remote_id:"first_name",remote_required:!1},{remote_label:r("Last Name","elementor-pro"),remote_type:"text",remote_id:"last_name",remote_required:!1},{remote_label:r("Phone","elementor-pro"),remote_type:"text",remote_id:"phone",remote_required:!1},{remote_label:r("Organization name","elementor-pro"),remote_type:"text",remote_id:"orgname",remote_required:!1}];for(var t in this.fields)Object.prototype.hasOwnProperty.call(this.fields,t)&&e.push(this.fields[t]);this.getEditorControlView("activecampaign_fields_map").updateMap(e)}},getActiveCampaignCache(e,t,o,r){if(_.has(this.cache[e],o)){var n={};return n[e]=this.cache[e][o],jQuery.Deferred().resolve(n)}return r=_.extend({},r,{service:"activecampaign",activecampaign_action:t,api_key:this.getEditorControlView("activecampaign_api_key").getControlValue(),api_url:this.getEditorControlView("activecampaign_api_url").getControlValue(),api_cred:this.getEditorControlView("activecampaign_api_credentials_source").getControlValue()}),this.fetchCache(e,o,r)}})},6236:(e,t,o)=>{"use strict";var r=o(7842);e.exports=r.extend({__construct(){this.cache={},r.prototype.__construct.apply(this,arguments)},getName:()=>"",getCacheKey(e){return JSON.stringify({service:this.getName(),data:e})},fetchCache(e,t,o,r=!1){return elementorPro.ajax.addRequest("forms_panel_action_data",{unique_id:"integrations_"+this.getName(),data:o,success:o=>{this.cache[e]=_.extend({},this.cache[e]),this.cache[e][t]=o[e]}},r)},onInit(){this.addSectionListener("section_"+this.getName(),this.onSectionActive)},onSectionActive(){this.onApiUpdate()},onApiUpdate(){}})},2432:(e,t,o)=>{"use strict";var r=o(2470).__,n=o(6236);e.exports=n.extend({getName:()=>"convertkit",onElementChange(e){switch(e){case"convertkit_api_key_source":case"convertkit_custom_api_key":this.onApiUpdate();break;case"convertkit_form":this.onListUpdate()}},onApiUpdate(){var e=this,t=e.getEditorControlView("convertkit_api_key_source"),o=e.getEditorControlView("convertkit_custom_api_key");if("default"!==t.getControlValue()&&""===o.getControlValue())return e.updateOptions("convertkit_form",[]),void e.getEditorControlView("convertkit_form").setValue("");e.addControlSpinner("convertkit_form");const r=this.getCacheKey({type:"data",controls:[t.getControlValue(),o.getControlValue()]});e.getConvertKitCache("data","convertkit_get_forms",r).done((function(t){e.updateOptions("convertkit_form",t.data.forms),e.updateOptions("convertkit_tags",t.data.tags)}))},onListUpdate(){this.updateFieldsMapping()},updateFieldsMapping(){if(this.getEditorControlView("convertkit_form").getControlValue()){var e=[{remote_label:r("Email","elementor-pro"),remote_type:"email",remote_id:"email",remote_required:!0},{remote_label:r("First Name","elementor-pro"),remote_type:"text",remote_id:"first_name",remote_required:!1}];this.getEditorControlView("convertkit_fields_map").updateMap(e)}},getConvertKitCache(e,t,o,r){if(_.has(this.cache[e],o)){var n={};return n[e]=this.cache[e][o],jQuery.Deferred().resolve(n)}return r=_.extend({},r,{service:"convertkit",convertkit_action:t,api_key:this.getEditorControlView("convertkit_api_key_source").getControlValue(),custom_api_key:this.getEditorControlView("convertkit_custom_api_key").getControlValue()}),this.fetchCache(e,o,r)}})},8058:(e,t,o)=>{"use strict";var r=o(2470).__,n=o(6236);e.exports=n.extend({getName:()=>"drip",onElementChange(e){switch(e){case"drip_api_token_source":case"drip_custom_api_token":this.onApiUpdate();break;case"drip_account":this.onDripAccountsUpdate()}},onApiUpdate(){var e=this,t=e.getEditorControlView("drip_api_token_source"),o=e.getEditorControlView("drip_custom_api_token");if("default"!==t.getControlValue()&&""===o.getControlValue())return e.updateOptions("drip_account",[]),void e.getEditorControlView("drip_account").setValue("");e.addControlSpinner("drip_account"),this.getCacheKey({type:"accounts",controls:[t.getControlValue(),o.getControlValue()]}),e.getDripCache("accounts","accounts",t.getControlValue()).done((function(t){e.updateOptions("drip_account",t.accounts)}))},onDripAccountsUpdate(){this.updateFieldsMapping()},updateFieldsMapping(){if(this.getEditorControlView("drip_account").getControlValue()){var e={remote_label:r("Email","elementor-pro"),remote_type:"email",remote_id:"email",remote_required:!0};this.getEditorControlView("drip_fields_map").updateMap([e])}},getDripCache(e,t,o,r){if(_.has(this.cache[e],o)){var n={};return n[e]=this.cache[e][o],jQuery.Deferred().resolve(n)}return r=_.extend({},r,{service:"drip",drip_action:t,api_token:this.getEditorControlView("drip_api_token_source").getControlValue(),custom_api_token:this.getEditorControlView("drip_custom_api_token").getControlValue()}),this.fetchCache(e,o,r)}})},5218:(e,t,o)=>{"use strict";var r=o(6236);e.exports=r.extend({getName:()=>"getresponse",onElementChange(e){switch(e){case"getresponse_custom_api_key":case"getresponse_api_key_source":this.onApiUpdate();break;case"getresponse_list":this.onGetResonseListUpdate()}},onApiUpdate(){var e=this,t=e.getEditorControlView("getresponse_api_key_source"),o=e.getEditorControlView("getresponse_custom_api_key");if("default"!==t.getControlValue()&&""===o.getControlValue())return e.updateOptions("getresponse_list",[]),void e.getEditorControlView("getresponse_list").setValue("");e.addControlSpinner("getresponse_list");const r=this.getCacheKey({type:"lists",controls:[t.getControlValue(),o.getControlValue()]});e.getCache("lists","lists",r).done((function(t){e.updateOptions("getresponse_list",t.lists)}))},onGetResonseListUpdate(){this.updatGetResonseList()},updatGetResonseList(){var e=this,t=e.getEditorControlView("getresponse_list");if(!t.getControlValue())return;e.addControlSpinner("getresponse_fields_map");const o=this.getCacheKey({type:"fields",controls:[t.getControlValue()]});e.getCache("fields","get_fields",o,{getresponse_list:t.getControlValue()}).done((function(t){e.getEditorControlView("getresponse_fields_map").updateMap(t.fields)}))},getCache(e,t,o,r){if(_.has(this.cache[e],o)){var n={};return n[e]=this.cache[e][o],jQuery.Deferred().resolve(n)}return r=_.extend({},r,{service:"getresponse",getresponse_action:t,api_key:this.getEditorControlView("getresponse_api_key_source").getControlValue(),custom_api_key:this.getEditorControlView("getresponse_custom_api_key").getControlValue()}),this.fetchCache(e,o,r)},onSectionActive(){r.prototype.onSectionActive.apply(this,arguments),this.updatGetResonseList()}})},5715:(e,t,o)=>{"use strict";var r=o(6236);e.exports=r.extend({getName:()=>"mailchimp",onElementChange(e){switch(e){case"mailchimp_api_key_source":case"mailchimp_api_key":this.onApiUpdate();break;case"mailchimp_list":this.onMailchimpListUpdate()}},onApiUpdate(){var e=this,t=e.getEditorControlView("mailchimp_api_key"),o=e.getEditorControlView("mailchimp_api_key_source");if("default"!==o.getControlValue()&&""===t.getControlValue())return e.updateOptions("mailchimp_list",[]),void e.getEditorControlView("mailchimp_list").setValue("");e.resetControlIndicators("mailchimp_list"),e.addControlSpinner("mailchimp_list");const r=this.getCacheKey({type:"lists",controls:[t.getControlValue(),o.getControlValue()]});e.getMailchimpCache("lists","lists",r).done((function(t){e.updateOptions("mailchimp_list",t.lists),e.updatMailchimpList()})).fail((function(t){e.addControlError("mailchimp_list",t)})).always((function(){e.removeControlSpinner("mailchimp_list")}))},onMailchimpListUpdate(){this.updateOptions("mailchimp_groups",[]),this.getEditorControlView("mailchimp_groups").setValue(""),this.updatMailchimpList()},updatMailchimpList(){var e=this,t=e.getEditorControlView("mailchimp_list");if(!t.getControlValue())return;e.resetControlIndicators("mailchimp_groups"),e.addControlSpinner("mailchimp_groups"),this.getCacheKey({type:"list_details",controls:[t.getControlValue()]}),e.getMailchimpCache("list_details","list_details",t.getControlValue(),{mailchimp_list:t.getControlValue()}).done((function(t){e.updateOptions("mailchimp_groups",t.list_details.groups),e.getEditorControlView("mailchimp_fields_map").updateMap(t.list_details.fields)})).fail((function(t){e.addControlError("mailchimp_groups",t)})).always((function(){e.removeControlSpinner("mailchimp_groups")}));const o={type:"fields",action:"fields",cacheKey:t.getControlValue(),args:{mailchimp_list:t.getControlValue()},immediately:!0};e.getMailchimpCache(...Object.values(o)).done((function(t){e.getEditorControlView("mailchimp_fields_map").updateMap(t.fields)}))},getMailchimpCache(e,t,o,r,n=!1){if(_.has(this.cache[e],o)){var i={};return i[e]=this.cache[e][o],jQuery.Deferred().resolve(i)}return r=_.extend({},r,{service:"mailchimp",mailchimp_action:t,api_key:this.getEditorControlView("mailchimp_api_key").getControlValue(),use_global_api_key:this.getEditorControlView("mailchimp_api_key_source").getControlValue()}),this.fetchCache(e,o,r,n)},onSectionActive(){r.prototype.onSectionActive.apply(this,arguments),this.onApiUpdate()}})},705:(e,t,o)=>{"use strict";var r=o(2470).__;o(5724);const n=o(6236);e.exports=n.extend({fields:{},getName:()=>"mailerlite",onElementChange(e){switch(e){case"mailerlite_api_key_source":case"mailerlite_custom_api_key":this.onMailerliteApiKeyUpdate();break;case"mailerlite_group":this.updateFieldsMapping()}},onMailerliteApiKeyUpdate(){var e=this,t=e.getEditorControlView("mailerlite_custom_api_key"),o=e.getEditorControlView("mailerlite_api_key_source");if("default"!==o.getControlValue()&&""===t.getControlValue())return e.updateOptions("mailerlite_group",[]),void e.getEditorControlView("mailerlite_group").setValue("");e.addControlSpinner("mailerlite_group");const r=this.getCacheKey({type:"groups",controls:[t.getControlValue(),o.getControlValue()]});e.getMailerliteCache("groups","groups",r).done((function(t){e.updateOptions("mailerlite_group",t.groups),e.fields=t.fields}))},updateFieldsMapping(){if(!this.getEditorControlView("mailerlite_group").getControlValue())return;const e=[{remote_label:r("Email","elementor-pro"),remote_type:"email",remote_id:"email",remote_required:!0},{remote_label:r("Name","elementor-pro"),remote_type:"text",remote_id:"name",remote_required:!1},{remote_label:r("Last Name","elementor-pro"),remote_type:"text",remote_id:"last_name",remote_required:!1},{remote_label:r("Company","elementor-pro"),remote_type:"text",remote_id:"company",remote_required:!1},{remote_label:r("Phone","elementor-pro"),remote_type:"text",remote_id:"phone",remote_required:!1},{remote_label:r("Country","elementor-pro"),remote_type:"text",remote_id:"country",remote_required:!1},{remote_label:r("State","elementor-pro"),remote_type:"text",remote_id:"state",remote_required:!1},{remote_label:r("City","elementor-pro"),remote_type:"text",remote_id:"city",remote_required:!1},{remote_label:r("Zip","elementor-pro"),remote_type:"text",remote_id:"zip",remote_required:!1}];for(const t in this.fields)Object.prototype.hasOwnProperty.call(this.fields,t)&&e.push(this.fields[t]);this.getEditorControlView("mailerlite_fields_map").updateMap(e)},getMailerliteCache(e,t,o,r){if(_.has(this.cache[e],o)){const t={};return t[e]=this.cache[e][o],jQuery.Deferred().resolve(t)}return r=_.extend({},r,{service:"mailerlite",mailerlite_action:t,custom_api_key:this.getEditorControlView("mailerlite_custom_api_key").getControlValue(),api_key:this.getEditorControlView("mailerlite_api_key_source").getControlValue()}),this.fetchCache(e,o,r)},onSectionActive(){n.prototype.onSectionActive.apply(this,arguments),this.onMailerliteApiKeyUpdate()}})},5341:(e,t,o)=>{"use strict";var r=o(6784);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(o(1646));class FormsModule extends elementorModules.editor.utils.Module{onElementorInit(){const e=o(9022),t=o(1452),r=o(705),n=o(5715),i=o(8058),s=o(4857),a=o(5218),l=o(2432),d=o(8636),u=o(7601);this.replyToField=new e,this.mailchimp=new n("form"),this.recaptcha=new t("form"),this.drip=new i("form"),this.activecampaign=new s("form"),this.getresponse=new a("form"),this.convertkit=new l("form"),this.mailerlite=new r("form");const c=o(326),m=o(431),p=o(140),g=o(7038),f=o(9738);this.Fields={time:new c("form"),date:new m("form"),tel:new f("form"),acceptance:new p("form"),upload:new g("form")},elementor.addControlView("Fields_map",o(8619)),elementor.addControlView("form-fields-repeater",o(3253)),this.hints={emailDeliverability:new d,submissionAnalysis:new u}}onElementorInitComponents(){$e.components.register(new n.default({manager:this}))}}t.default=FormsModule},1452:e=>{"use strict";e.exports=elementorModules.editor.utils.Module.extend({enqueueRecaptchaJs(e,t){elementorFrontend.elements.$body.find('[src="'+e+'"]').length||elementorFrontend.elements.$body.append(' diff --git a/core/integrations/actions/action-base.php b/core/integrations/actions/action-base.php new file mode 100644 index 00000000..d236bd1b --- /dev/null +++ b/core/integrations/actions/action-base.php @@ -0,0 +1,47 @@ +validate( $payload ); + $this->apply( $payload ); + } +} diff --git a/core/integrations/actions/email/email-address.php b/core/integrations/actions/email/email-address.php new file mode 100644 index 00000000..8be400a8 --- /dev/null +++ b/core/integrations/actions/email/email-address.php @@ -0,0 +1,50 @@ +address = (string) $address; + $this->name = (string) $name; + } + + /** + * Format an email to be ready for header (e.g. `Recipient Name ` or `user@email.com`) + * + * @return string + */ + public function format() { + if ( ! empty( $this->name ) ) { + return sprintf( '%s <%s>', $this->name, $this->address ); + } + + return sprintf( '%s', $this->address ); + } +} diff --git a/core/integrations/actions/email/email-message.php b/core/integrations/actions/email/email-message.php new file mode 100644 index 00000000..ecad0f80 --- /dev/null +++ b/core/integrations/actions/email/email-message.php @@ -0,0 +1,239 @@ +from( get_bloginfo( 'admin_email' ), get_bloginfo( 'name' ) ); + } + + /** + * Set the email sender. + * + * @param string $email + * @param string|null $name + * + * @return $this + */ + public function from( $email, $name = null ) { + $this->from = new Email_Address( $email, $name ); + + return $this; + } + + /** + * Set the email recipient. + * + * @param string $email + * @param string|null $name + * + * @return $this + */ + public function to( $email, $name = null ) { + $this->to = new Email_Address( $email, $name ); + + return $this; + } + + /** + * Add a reply to. + * + * @param string $email + * @param string|null $name + * + * @return $this + */ + public function reply_to( $email, $name = null ) { + $this->reply_to[] = new Email_Address( $email, $name ); + + return $this; + } + + /** + * Add a CC. + * + * @param string $email + * @param string|null $name + * + * @return $this + */ + public function cc( $email, $name = null ) { + $this->cc[] = new Email_Address( $email, $name ); + + return $this; + } + + /** + * Add a BCC. + * + * @param string $email + * @param string|null $name + * + * @return $this + */ + public function bcc( $email, $name = null ) { + $this->bcc[] = new Email_Address( $email, $name ); + + return $this; + } + + /** + * Set the email subject. + * + * @param string $subject + * + * @return $this + */ + public function subject( $subject ) { + $this->subject = (string) $subject; + + return $this; + } + + /** + * Set the email content type. + * + * @param string $content_type + * + * @return $this + */ + public function content_type( $content_type ) { + $this->content_type = (string) $content_type; + + return $this; + } + + /** + * Set the email body using plain text. + * + * @param string $body + * @param string $content_type + * + * @return $this + */ + public function body( $body, $content_type = 'text/html' ) { + $this->body = (string) $body; + + return $this->content_type( $content_type ); + } + + /** + * Set the email body using a view. + * + * @param string $path - View path, + * @param array $data - Data that will be passes to the view. + * + * @return $this + * @throws \Exception + */ + public function view( $path, $data = [] ) { + if ( ! is_file( $path ) ) { + throw new \Exception( "`{$path}` is not a valid view." ); + } + + ob_start(); + + // Inspired from Laravel's view mechanism: + // [1] https://github.dev/illuminate/filesystem/blob/b179f9ea3b3195d1f4b5ae2aee67e42eac6ceb5e/Filesystem.php#L98 + // [2] https://github.dev/illuminate/view/blob/6dd315634a44450c5e443fa8735d4a526833fad3/Engines/PhpEngine.php#L48 + call_user_func( function( $__view_path, $__view_data ) { + extract( $__view_data, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract + + unset( $__view_data ); + + // `$__view_data` keys are available in the file as variables. + require $__view_path; + }, $path, $data ); + + $this->body = ob_get_clean(); + + return $this->content_type( 'text/html' ); + } + + /** + * Add an attachment. + * + * @param string $path - Attachment path on the server. + * + * @return $this + */ + public function attach( $path ) { + $this->attachments[] = (string) $path; + + return $this; + } +} diff --git a/core/integrations/actions/email/email.php b/core/integrations/actions/email/email.php new file mode 100644 index 00000000..d834a967 --- /dev/null +++ b/core/integrations/actions/email/email.php @@ -0,0 +1,128 @@ +content_type ), + sprintf( 'From: %s', $payload->from->format() ), + ]; + + foreach ( $payload->reply_to as $recipient ) { + $headers[] = sprintf( 'Reply-To: %s', $recipient->format() ); + } + + // Set CC headers. + $cc_headers = []; + + foreach ( $payload->cc as $recipient ) { + $cc_headers[] = sprintf( 'Cc: %s', $recipient->format() ); + } + + // Send email. + $this->send_mail( + $payload->to->format(), + $payload->subject, + $payload->body, + implode( PHP_EOL, array_merge( $headers, $cc_headers ) ), + $payload->attachments + ); + + // Send BCC emails. + foreach ( $payload->bcc as $bcc ) { + $this->send_mail( + $bcc->format(), + $payload->subject, + $payload->body, + implode( PHP_EOL, $headers ), + $payload->attachments + ); + } + } + + /** + * @alias `$this->run()` + * + * @param Email_Message $payload + * + * @return void + *@throws \Exception + * + */ + public function send( Email_Message $payload ) { + $this->run( $payload ); + } + + /** + * Validate the email message DTO. + * + * @param Email_Message $payload + * + * @throws \ElementorPro\Core\Integrations\Exceptions\Action_Validation_Failed_Exception + * + * @return void + */ + public function validate( $payload ) { + $required_fields = [ + 'from', + 'to', + 'subject', + 'body', + 'content_type', + ]; + + foreach ( $required_fields as $field ) { + if ( empty( $payload->{$field} ) ) { + throw new Action_Validation_Failed_Exception( + static::class, + "`Email_Message::\${$field}` is required." + ); + } + } + } + + /** + * Calls `wp_mail()`. Used for testing. + * + * @param mixed ...$args + * + * @return void + */ + protected function send_mail( ...$args ) { + add_action( 'wp_mail_failed', [ $this, 'on_wp_mail_error' ] ); + + wp_mail( ...$args ); + + remove_action( 'wp_mail_failed', [ $this, 'on_wp_mail_error' ] ); + } + + /** + * Throw exception on `wp_mail()` error. + * + * @param \WP_Error $error + * + * @throws \ElementorPro\Core\Integrations\Exceptions\Action_Failed_Exception + * + * @return void + */ + public function on_wp_mail_error( \WP_Error $error ) { + throw new Action_Failed_Exception( static::class, '`wp_mail()` cannot send email', $error ); + } +} diff --git a/core/integrations/exceptions/action-failed-exception.php b/core/integrations/exceptions/action-failed-exception.php new file mode 100644 index 00000000..0536c5a9 --- /dev/null +++ b/core/integrations/exceptions/action-failed-exception.php @@ -0,0 +1,18 @@ +action, + $message + ); + } +} diff --git a/core/integrations/exceptions/action-validation-failed-exception.php b/core/integrations/exceptions/action-validation-failed-exception.php new file mode 100644 index 00000000..a7757731 --- /dev/null +++ b/core/integrations/exceptions/action-validation-failed-exception.php @@ -0,0 +1,18 @@ +action, + $message + ); + } +} diff --git a/core/integrations/exceptions/exception-base.php b/core/integrations/exceptions/exception-base.php new file mode 100644 index 00000000..1184d4d2 --- /dev/null +++ b/core/integrations/exceptions/exception-base.php @@ -0,0 +1,70 @@ +action = $action; + $this->meta = $meta; + + $message = $this->format_message( $message ); + + parent::__construct( $message ); + } + + /** + * Log the exception to Elementor's log. + * + * @return void + */ + public function log() { + Plugin::elementor()->logger->get_logger()->error( $this->getMessage(), [ 'meta' => $this->meta ] ); + } + + /** + * Get the error format. + * + * @return string + */ + public function __toString() { + return sprintf( + '%s: %s', + __CLASS__, + $this->getMessage() + ); + } +} diff --git a/core/integrations/integrations-manager.php b/core/integrations/integrations-manager.php new file mode 100644 index 00000000..73a89a96 --- /dev/null +++ b/core/integrations/integrations-manager.php @@ -0,0 +1,112 @@ +actions_registrar = new Registrar(); + } + + /** + * Get an action instance. + * + * @shortcut `Registrar->get()`. + * + * @return \ElementorPro\Core\Integrations\Actions\Action_Base|null + */ + public function get_action( $id ) { + if ( ! $this->is_initialized() ) { + $this->init_actions(); + } + + return $this->actions_registrar->get( $id ); + } + + /** + * Run an action for a selected payload. + * + * @param array|mixed $payloads - Payloads instances to run the actions on. + * @param null|string $id - If `$payloads` is not an array, a custom action ID can be provided. + * + * @return void + */ + public function run( $payloads, $id = null ) { + if ( ! is_array( $payloads ) ) { + $payloads = $id ? [ $id => $payloads ] : [ $payloads ]; + } + + foreach ( $payloads as $key => $payload ) { + // Get the action ID for the provided payload type. + $action_id = is_numeric( $key ) ? get_class( $payload ) : $key; + + /** + * @type Action_Base $action + */ + $action = $this->get_action( $action_id ); + + if ( ! $action ) { + throw new \Exception( "{$action_id} doesn't have an associated `Action`." ); + } + + if ( ! ( $action instanceof Action_Base ) ) { + $action_class = get_class( $action ); + + throw new \Exception( "{$action_class} is not a valid `Action_Base`." ); + } + + try { + $action->run( $payload ); + } catch ( Action_Validation_Failed_Exception $e ) { + $e->log(); + } catch ( Action_Failed_Exception $e ) { + $e->log(); + } + } + } + + /** + * Initialize the manager actions. + * + * @return void + */ + protected function init_actions() { + add_action( 'elementor_pro/core/integrations/actions/register', function ( Registrar $actions_registrar ) { + $actions_registrar->register( new Email(), Email_Message::class ); + } ); + + do_action( 'elementor_pro/core/integrations/actions/register', $this->actions_registrar ); + } + + /** + * Determine if the manager is initialized. + * + * @return boolean + */ + protected function is_initialized() { + return ! ! did_action( 'elementor_pro/core/integrations/actions/register' ); + } +} diff --git a/core/isolation/wordpress-adapter-interface.php b/core/isolation/wordpress-adapter-interface.php new file mode 100644 index 00000000..e9e6f140 --- /dev/null +++ b/core/isolation/wordpress-adapter-interface.php @@ -0,0 +1,12 @@ +experiments->add_feature( $experimental_data ); + + if ( ! Plugin::elementor()->experiments->is_feature_active( $experimental_data['name'] ) ) { + continue; + } + } + + if ( $class_name::is_active() ) { + $this->modules[ $module_name ] = $class_name::instance(); + } + } + } + + /** + * @param string $module_name + * + * @return Module_Base|Module_Base[] + */ + public function get_modules( $module_name ) { + if ( $module_name ) { + if ( isset( $this->modules[ $module_name ] ) ) { + return $this->modules[ $module_name ]; + } + + return null; + } + + return $this->modules; + } +} diff --git a/core/notifications/notification.php b/core/notifications/notification.php new file mode 100644 index 00000000..18076462 --- /dev/null +++ b/core/notifications/notification.php @@ -0,0 +1,29 @@ +get_payloads( $notifiable ); + + Plugin::instance()->integrations->run( $payloads ); + + return $this; + } +} diff --git a/core/notifications/traits/notifiable.php b/core/notifications/traits/notifiable.php new file mode 100644 index 00000000..257e8314 --- /dev/null +++ b/core/notifications/traits/notifiable.php @@ -0,0 +1,30 @@ +notify( new User_Created_Notification( $new_user ) ); + * + * @param Notification $notification - Notification to send. + * + * @throws \Exception + * + * @return void + */ + public function notify( Notification $notification ) { + Plugin::instance()->notifications->send( $notification, $this ); + } +} diff --git a/core/php-api.php b/core/php-api.php new file mode 100644 index 00000000..75ddf663 --- /dev/null +++ b/core/php-api.php @@ -0,0 +1,23 @@ +get_css_assets_url( 'preview' ), + [], + ELEMENTOR_PRO_VERSION + ); + } + + protected function get_assets_base_url() { + return ELEMENTOR_PRO_URL; + } +} diff --git a/core/security/access-control.php b/core/security/access-control.php new file mode 100644 index 00000000..1a3c5abd --- /dev/null +++ b/core/security/access-control.php @@ -0,0 +1,39 @@ +get_col( + 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND `meta_value` LIKE \'%"widgetType":"form"%\';' + ); + + if ( empty( $post_ids ) ) { + return; + } + + foreach ( $post_ids as $post_id ) { + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( $document ) { + $data = $document->get_elements_data(); + } + + if ( empty( $data ) ) { + continue; + } + + $data = Plugin::elementor()->db->iterate_data( $data, function( $element ) { + if ( empty( $element['widgetType'] ) || 'form' !== $element['widgetType'] ) { + return $element; + } + + if ( ! isset( $element['settings']['submit_actions'] ) ) { + $element['settings']['submit_actions'] = [ 'email' ]; + } + + if ( ! empty( $element['settings']['redirect_to'] ) ) { + if ( ! in_array( 'redirect', $element['settings']['submit_actions'] ) ) { + $element['settings']['submit_actions'][] = 'redirect'; + } + } + + if ( ! empty( $element['settings']['webhooks'] ) ) { + if ( ! in_array( 'webhook', $element['settings']['submit_actions'] ) ) { + $element['settings']['submit_actions'][] = 'webhook'; + } + } + + return $element; + } ); + + self::save_editor( $post_id, $data ); + } + } + + public static function _v_1_4_0() { + global $wpdb; + + // Move all posts columns to classic skin (Just add prefix) + $post_ids = $wpdb->get_col( + 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND `meta_value` LIKE \'%"widgetType":"posts"%\';' + ); + + if ( empty( $post_ids ) ) { + return; + } + + foreach ( $post_ids as $post_id ) { + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( $document ) { + $data = $document->get_elements_data(); + } + + if ( empty( $data ) ) { + continue; + } + + $data = Plugin::elementor()->db->iterate_data( $data, function( $element ) { + if ( empty( $element['widgetType'] ) || 'posts' !== $element['widgetType'] ) { + return $element; + } + + $fields_to_change = [ + 'columns', + 'columns_mobile', + 'columns_tablet', + ]; + + foreach ( $fields_to_change as $field ) { + // TODO: Remove old value later + $new_field_key = 'classic_' . $field; + if ( isset( $element['settings'][ $field ] ) && ! isset( $element['settings'][ $new_field_key ] ) ) { + $element['settings'][ $new_field_key ] = $element['settings'][ $field ]; + } + } + + return $element; + } ); + + $document = Plugin::elementor()->documents->get( $post_id ); + + $document->save( [ + 'elements' => $data, + ] ); + } + } + + public static function _v_1_12_0() { + global $wpdb; + + // Set `mailchimp_api_key_source` to `custom`. + $post_ids = $wpdb->get_col( + 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND `meta_value` LIKE \'%"widgetType":"form"%\';' + ); + + if ( empty( $post_ids ) ) { + return; + } + + foreach ( $post_ids as $post_id ) { + $do_update = false; + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( $document ) { + $data = $document->get_elements_data(); + } + + if ( empty( $data ) ) { + continue; + } + + $data = Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$do_update ) { + if ( empty( $element['widgetType'] ) || 'form' !== $element['widgetType'] ) { + return $element; + } + + if ( ! empty( $element['settings']['mailchimp_api_key'] ) && ! isset( $element['settings']['mailchimp_api_key_source'] ) ) { + $element['settings']['mailchimp_api_key_source'] = 'custom'; + $do_update = true; + } + + return $element; + } ); + + // Only update if form has mailchimp + if ( ! $do_update ) { + continue; + } + // We need the `wp_slash` in order to avoid the unslashing during the `update_post_meta` + $json_value = wp_slash( wp_json_encode( $data ) ); + + update_metadata( 'post', $post_id, '_elementor_data', $json_value ); + } + } + + /** + * Replace 'sticky' => 'yes' with 'sticky' => 'top' in sections. + */ + public static function _v_2_0_3() { + global $wpdb; + + $post_ids = $wpdb->get_col( + 'SELECT `post_id` FROM `' . $wpdb->postmeta . '` WHERE `meta_key` = "_elementor_data" AND `meta_value` LIKE \'%"sticky":"yes"%\';' + ); + + if ( empty( $post_ids ) ) { + return; + } + + foreach ( $post_ids as $post_id ) { + $do_update = false; + + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( ! $document ) { + continue; + } + + $data = $document->get_elements_data(); + + if ( empty( $data ) ) { + continue; + } + + $data = Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$do_update ) { + if ( empty( $element['elType'] ) || 'section' !== $element['elType'] ) { + return $element; + } + + if ( ! empty( $element['settings']['sticky'] ) && 'yes' === $element['settings']['sticky'] ) { + $element['settings']['sticky'] = 'top'; + $do_update = true; + } + + return $element; + } ); + + if ( ! $do_update ) { + continue; + } + // We need the `wp_slash` in order to avoid the unslashing during the `update_metadata` + $json_value = wp_slash( wp_json_encode( $data ) ); + + update_metadata( 'post', $post_id, '_elementor_data', $json_value ); + } // End foreach(). + } + + private static function save_editor( $post_id, $posted ) { + // Change the global post to current library post, so widgets can use `get_the_ID` and other post data + if ( isset( $GLOBALS['post'] ) ) { + $global_post = $GLOBALS['post']; + } + $GLOBALS['post'] = get_post( $post_id ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + + $editor_data = self::get_editor_data( $posted ); + + // We need the `wp_slash` in order to avoid the unslashing during the `update_post_meta` + $json_value = wp_slash( wp_json_encode( $editor_data ) ); + + $is_meta_updated = update_metadata( 'post', $post_id, '_elementor_data', $json_value ); + + if ( $is_meta_updated ) { + Revisions_Manager::handle_revision(); + } + + // Restore global post + if ( isset( $global_post ) ) { + $GLOBALS['post'] = $global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + } else { + unset( $GLOBALS['post'] ); + } + + /** + * After editor saves data. + * + * Fires after Elementor editor data was saved. + * + * @since 1.0.0 + * + * @param int $post_id The ID of the post. + * @param array $editor_data The editor data. + */ + do_action( 'elementor/editor/after_save', $post_id, $editor_data ); + } + + private static function get_editor_data( $data, $with_html_content = false ) { + $editor_data = []; + + foreach ( $data as $element_data ) { + $element = Plugin::elementor()->elements_manager->create_element_instance( $element_data ); + + if ( ! $element ) { + continue; + } + + $editor_data[] = $element->get_raw_data( $with_html_content ); + } // End Section + + return $editor_data; + } + + public static function _v_2_5_0_form( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_repeater_settings' ], + 'control_ids' => [ + 'form_fields' => [ + '_id' => 'custom_id', + ], + ], + ], + ]; + + return self::_update_widget_settings( 'form', $updater, $changes ); + } + + public static function _v_2_5_0_woocommerce_menu_cart( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings' ], + 'control_ids' => [ + 'checkout_button_border_color' => 'checkout_border_color', + 'view_cart_button_border_color' => 'view_cart_border_color', + ], + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_slider_to_border_settings' ], + 'control_ids' => [ + 'checkout_button_border_width' => [ + 'new' => 'checkout_border_width', + 'add' => 'checkout_border_border', + ], + 'view_cart_button_border_width' => [ + 'new' => 'view_cart_border_width', + 'add' => 'view_cart_border_border', + ], + ], + ], + ]; + + return self::_update_widget_settings( 'woocommerce-menu-cart', $updater, $changes ); + } + + public static function _v_3_7_2_woocommerce_rename_related_to_related_products( $updater ) { + $changes = self::get_woocommerce_rename_related_to_related_products_changes(); + + return self::_update_widget_settings( 'woocommerce-products', $updater, $changes ); + } + + public static function _slider_to_border_settings( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + foreach ( $changes as $old => $new ) { + if ( ! empty( $element['settings'][ $old ] ) && ! isset( $element['settings'][ $new['new'] ] ) ) { + $new_border_width = [ + 'unit' => $element['settings'][ $old ]['unit'], + 'top' => $element['settings'][ $old ]['size'], + 'bottom' => $element['settings'][ $old ]['size'], + 'left' => $element['settings'][ $old ]['size'], + 'right' => $element['settings'][ $old ]['size'], + 'isLinked' => true, + ]; + $element['settings'][ $new ['new'] ] = $new_border_width; + $element['settings'][ $new ['add'] ] = 'solid'; + $args['do_update'] = true; + } + } + return $element; + } + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _rename_repeater_settings( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + foreach ( $changes as $change_key => $change ) { + foreach ( $change as $old => $new ) { + foreach ( $element['settings'][ $change_key ] as &$repeater ) { + if ( ! empty( $repeater[ $old ] ) && ! isset( $repeater[ $new ] ) ) { + $repeater[ $new ] = $repeater[ $old ]; + $args['do_update'] = true; + } + } + } + } + + return $element; + } + + private static function taxonomies_mapping( $prefix, $map_to ) { + $taxonomy_filter_args = [ + 'show_in_nav_menus' => true, + ]; + + $taxonomies = get_taxonomies( $taxonomy_filter_args ); + + $mapping = []; + + foreach ( $taxonomies as $taxonomy ) { + $mapping[ $prefix . $taxonomy . '_ids' ] = $map_to; + } + + return $mapping; + } + + public static function _v_2_5_0_posts( $updater ) { + $add_taxonomies = self::taxonomies_mapping( 'posts_', [ 'posts_include' => 'terms' ] ); + $merge_taxonomies = self::taxonomies_mapping( 'posts_', 'posts_include_term_ids' ); + + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings' ], + 'control_ids' => [ + 'orderby' => 'posts_orderby', + 'order' => 'posts_order', + 'offset' => 'posts_offset', + 'exclude' => 'posts_exclude', + 'exclude_ids' => 'posts_exclude_ids', + 'posts_query_id' => 'posts_posts_query_id', + 'avoid_duplicates' => 'posts_avoid_duplicates', + 'posts_authors' => 'posts_include_authors', + ], + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_add_widget_settings_to_array' ], + 'control_ids' => array_merge( $add_taxonomies, [ + 'posts_authors' => [ 'posts_include' => 'authors' ], + ] ), + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_merge_widget_settings' ], + 'control_ids' => $merge_taxonomies, + ], + ]; + + return self::_update_widget_settings( 'posts', $updater, $changes ); + } + + public static function _v_2_5_0_portfolio( $updater ) { + $add_taxonomies = self::taxonomies_mapping( 'posts_', [ 'posts_include' => 'terms' ] ); + $merge_taxonomies = self::taxonomies_mapping( 'posts_', 'posts_include_term_ids' ); + + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings' ], + 'control_ids' => [ + 'orderby' => 'posts_orderby', + 'order' => 'posts_order', + 'offset' => 'posts_offset', + 'exclude' => 'posts_exclude', + 'exclude_ids' => 'posts_exclude_ids', + 'posts_query_id' => 'posts_posts_query_id', + 'avoid_duplicates' => 'posts_avoid_duplicates', + 'posts_authors' => 'posts_include_authors', + ], + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_add_widget_settings_to_array' ], + 'control_ids' => array_merge( $add_taxonomies, [ + 'posts_authors' => [ 'posts_include' => 'authors' ], + ] ), + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_merge_widget_settings' ], + 'control_ids' => $merge_taxonomies, + ], + ]; + + return self::_update_widget_settings( 'portfolio', $updater, $changes ); + } + + public static function _v_2_5_0_products( $updater ) { + $add_taxonomies = self::taxonomies_mapping( 'query_', [ 'query_include' => 'terms' ] ); + $merge_taxonomies = self::taxonomies_mapping( 'query_', 'query_include_term_ids' ); + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings' ], + 'control_ids' => [ + 'orderby' => 'query_orderby', + 'order' => 'query_order', + 'exclude' => 'query_exclude', + 'exclude_ids' => 'query_exclude_ids', + 'query_authors' => 'query_include_authors', + 'query_product_tag_ids' => 'query_include_term_ids', + 'query_product_cat_ids' => 'query_include_term_ids', + ], + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_add_widget_settings_to_array' ], + 'control_ids' => array_merge( $add_taxonomies, [ + 'query_authors' => [ 'query_include' => 'authors' ], + ] ), + ], + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_merge_widget_settings' ], + 'control_ids' => $merge_taxonomies, + ], + ]; + + return self::_update_widget_settings( 'woocommerce-products', $updater, $changes ); + } + + /** + * @param $updater + * + * @return bool Should run again. + */ + public static function _v_2_5_0_sitemap( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings' ], + 'control_ids' => [ + 'exclude' => 'sitemap_exclude', + 'exclude_ids' => 'sitemap_exclude_ids', + ], + ], + ]; + + return self::_update_widget_settings( 'sitemap', $updater, $changes ); + } + + /** + * @param Updater $updater + * + * @return bool + */ + public static function _v_2_5_0_popup_border_radius( $updater ) { + global $wpdb; + + $post_ids = $updater->query_col( + "SELECT pm1.post_id + FROM {$wpdb->postmeta} AS pm1 + LEFT JOIN {$wpdb->postmeta} AS pm2 ON (pm1.post_id = pm2.post_id) + WHERE pm1.meta_key = '_elementor_template_type' + AND pm1.meta_value = 'popup' + AND pm2.`meta_key` = '" . Document::PAGE_META_KEY . "' + AND pm2.`meta_value` LIKE '%border_radius%';" + ); + + if ( empty( $post_ids ) ) { + return false; + } + + foreach ( $post_ids as $post_id ) { + // Clear WP cache for next step. + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( ! $document ) { + continue; + } + + $page_settings = $document->get_settings(); + + // Check if there isn't 'border_radius' setting or if it has already been upgraded + if ( empty( $page_settings['border_radius']['size'] ) ) { + continue; + } + + $border_radius = $page_settings['border_radius']; + + $new_border_radius = [ + 'unit' => $border_radius['unit'], + 'top' => $border_radius['size'], + 'bottom' => $border_radius['size'], + 'left' => $border_radius['size'], + 'right' => $border_radius['size'], + 'isLinked' => true, + ]; + + $page_settings['border_radius'] = $new_border_radius; + + // TODO: `$document->update_settings`. + $document->update_meta( Document::PAGE_META_KEY, $page_settings ); + + wp_cache_flush(); + } // End foreach(). + + return $updater->should_run_again( $post_ids ); + } + + public static function _v_2_5_4_posts( $updater ) { + $merge_taxonomies = self::taxonomies_mapping( 'posts_', 'posts_include_term_ids' ); + + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_term_id_to_term_taxonomy_id' ], + 'control_ids' => $merge_taxonomies, + 'prefix' => 'posts_', + 'new_id' => 'include_term_ids', + ], + ]; + + return self::_update_widget_settings( 'posts', $updater, $changes ); + } + + public static function _v_2_5_4_portfolio( $updater ) { + $merge_taxonomies = self::taxonomies_mapping( 'posts_', 'posts_include_term_ids' ); + + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_term_id_to_term_taxonomy_id' ], + 'control_ids' => $merge_taxonomies, + 'prefix' => 'posts_', + 'new_id' => 'include_term_ids', + ], + ]; + + return self::_update_widget_settings( 'portfolio', $updater, $changes ); + } + + public static function _v_2_5_4_products( $updater ) { + $merge_taxonomies = self::taxonomies_mapping( 'query_', 'query_include_term_ids' ); + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_term_id_to_term_taxonomy_id' ], + 'control_ids' => $merge_taxonomies, + 'prefix' => 'query_', + 'new_id' => 'include_term_ids', + ], + ]; + + return self::_update_widget_settings( 'woocommerce-products', $updater, $changes ); + } + + public static function _v_2_5_4_form( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_missing_form_custom_id_settings' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'form', $updater, $changes ); + } + + public static function _v_3_1_0_media_carousel( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_progress_to_progressbar' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'media-carousel', $updater, $changes ); + } + + public static function _v_3_1_0_reviews( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_progress_to_progressbar' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'reviews', $updater, $changes ); + } + + public static function _v_3_1_0_testimonial_carousel( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_convert_progress_to_progressbar' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'testimonial-carousel', $updater, $changes ); + } + + public static function _v_3_1_0_slides( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_migrate_slides_button_color_settings' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'slides', $updater, $changes ); + } + + public static function _v_3_3_0_nav_menu_icon( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_migrate_indicator_control_to_submenu_icon' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'nav-menu', $updater, $changes ); + } + + public static function _v_3_3_0_recalc_usage_data( $updater ) { + return Core_Upgrades::recalc_usage_data( $updater ); + } + + public static function _v_3_5_0_price_list( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_copy_title_styles_to_new_price_controls' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'price-list', $updater, $changes ); + } + + /** + * $changes is an array of arrays in the following format: + * [ + * 'control_ids' => array of control ids + * 'callback' => user callback to manipulate the control_ids + * ] + * + * @param $widget_id + * @param $updater + * @param array $changes + * + * @return bool + */ + public static function _update_widget_settings( $widget_id, $updater, $changes ) { + global $wpdb; + + $post_ids = $updater->query_col( + 'SELECT `post_id` + FROM `' . $wpdb->postmeta . '` + WHERE `meta_key` = "_elementor_data" + AND `meta_value` LIKE \'%"widgetType":"' . $widget_id . '"%\';' + ); + + if ( empty( $post_ids ) ) { + return false; + } + + foreach ( $post_ids as $post_id ) { + $do_update = false; + + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( ! $document ) { + continue; + } + + $data = $document->get_elements_data(); + + if ( empty( $data ) ) { + continue; + } + + // loop through callbacks & array + foreach ( $changes as $change ) { + $args = [ + 'do_update' => &$do_update, + 'widget_id' => $widget_id, + 'control_ids' => $change['control_ids'], + ]; + if ( isset( $change['prefix'] ) ) { + $args['prefix'] = $change['prefix']; + $args['new_id'] = $change['new_id']; + } + $data = Plugin::elementor()->db->iterate_data( $data, $change['callback'], $args ); + if ( ! $do_update ) { + continue; + } + + // We need the `wp_slash` in order to avoid the unslashing during the `update_metadata` + $json_value = wp_slash( wp_json_encode( $data ) ); + + update_metadata( 'post', $post_id, '_elementor_data', $json_value ); + } + } // End foreach(). + + return $updater->should_run_again( $post_ids ); + } + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _rename_widget_settings( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + foreach ( $changes as $old => $new ) { + if ( ! empty( $element['settings'][ $old ] ) && ! isset( $element['settings'][ $new ] ) ) { + $element['settings'][ $new ] = $element['settings'][ $old ]; + $args['do_update'] = true; + } + } + + return $element; + } + + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _rename_widget_settings_value( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( self::is_widget_matched( $element, $widget_id ) ) { + $element = self::apply_rename( $changes, $element, $args ); + } + + return $element; + } + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _add_widget_settings_to_array( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + foreach ( $changes as $old_key => $added_key ) { + if ( ! empty( $element['settings'][ $old_key ] ) ) { + foreach ( $added_key as $control_id => $val ) { + if ( ! in_array( $val, $element['settings'][ $control_id ], true ) ) { + $element['settings'][ $control_id ][] = $val; + $args['do_update'] = true; + } + } + } + } + + return $element; + } + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _merge_widget_settings( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + foreach ( $changes as $old => $new ) { + if ( ! empty( $element['settings'][ $old ] ) ) { + if ( ! isset( $element['settings'][ $new ] ) ) { + $element['settings'][ $new ] = $element['settings'][ $old ]; + } else { + $element['settings'][ $new ] = array_unique( array_merge( $element['settings'][ $old ], $element['settings'][ $new ] ) ); + } + $args['do_update'] = true; + } + } + + return $element; + } + + /** + * Possible scenarios: + * 1) custom_id is not empty --> do nothing + * 2) Existing _id: Empty or Missing custom_id --> create custom_id and set the value to the value of _id + * 3) Missing _id: Empty or Missing custom_id --> generate a unique key and set it as custom_id value + * @param $element + * @param $args + * + * @return mixed + */ + public static function _missing_form_custom_id_settings( $element, $args ) { + $widget_id = $args['widget_id']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + $random_id = (int) substr( time(), -5 ); + //form_fields loop: + foreach ( $element['settings']['form_fields'] as &$repeater_item ) { + if ( ! empty( $repeater_item['custom_id'] ) ) { // Scenario 1 + continue; + } + + if ( ! empty( $repeater_item['_id'] ) ) { // Scenario 2 + $repeater_item['custom_id'] = $repeater_item['_id']; + } else { // Scenario 3 + $repeater_item['custom_id'] = 'field_' . $random_id; + $random_id++; + } + + $args['do_update'] = true; + } + + return $element; + } + + /** + * Migrates the value saved for the 'indicator' SELECT control in the Nav Menu Widget to the new replacement + * 'submenu_icon' ICONS control. + * + * @param $element + * @param $args + * + * @return mixed; + */ + public static function _migrate_indicator_control_to_submenu_icon( $element, $args ) { + $widget_id = $args['widget_id']; + + // If the current element is not a Nav Menu widget, go to the next one. + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + // If this Nav Menu widget's 'indicator' control value is the default one (there is no value in the DB), + // there is nothing to migrate, since the default icon is identical in the new control. Go to the next element. + if ( ! isset( $element['settings']['indicator'] ) ) { + return $element; + } + + $new_value = ''; + $new_library = 'fa-solid'; + + switch ( $element['settings']['indicator'] ) { + case 'none': + $new_library = ''; + break; + case 'classic': + $new_value = 'fa-caret-down'; + break; + case 'chevron': + $new_value = 'fa-chevron-down'; + break; + case 'angle': + $new_value = 'fa-angle-down'; + break; + case 'plus': + $new_value = 'e-plus-icon'; + $new_library = ''; + break; + } + + // This is done in order to make sure that the menu will not look any different for users who upgrade. + // The 'None' option should be completely empty. + if ( $new_value ) { + if ( Icons_Manager::is_migration_allowed() ) { + // If the site has been migrated to FA5, add the new FA Solid class. + $new_value = 'fas ' . $new_value; + } else { + // If the site has not been migrated, add the old generic 'fa' class. + $new_value = 'fa ' . $new_value; + } + } + + // Set the migrated value for the new control. + $element['settings']['submenu_icon'] = [ + 'value' => $new_value, + 'library' => $new_library, + ]; + + $args['do_update'] = true; + + return $element; + } + + /** + * @param $element + * @param $args + * + * @return mixed + */ + public static function _convert_term_id_to_term_taxonomy_id( $element, $args ) { + $widget_id = $args['widget_id']; + $changes = $args['control_ids']; + $prefix = $args['prefix']; + $new_id = $prefix . $args['new_id']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + // Exit if new is empty (should not happen) + if ( empty( $element['settings'][ $new_id ] ) ) { + return $element; + } + + // 1) Convert each term-id to the equivalent term_taxonomy_id + $term_taxonomy_ids = []; + $old_term_ids = []; + foreach ( $changes as $old => $new ) { + if ( ! empty( $element['settings'][ $old ] ) ) { + $start = strlen( $prefix ); + $end = -strlen( '_ids' ); + $taxonomy = substr( $old, $start, $end ); + foreach ( $element['settings'][ $old ] as $term_id ) { + $old_term_ids[] = $term_id; + $term_obj = get_term( $term_id, $taxonomy, OBJECT ); + if ( $term_obj && ! is_wp_error( $term_obj ) ) { + $term_taxonomy_ids[] = $term_obj->term_taxonomy_id; + } + } + } + } + + // 2) Check if the widget's settings were changed after the u/g to 2.5.0 + $diff = array_diff( $element['settings'][ $new_id ], array_unique( $old_term_ids ) ); + if ( empty( $diff ) ) { // Nothing was changed + $element['settings'][ $new_id . '_backup' ] = $element['settings'][ $new_id ]; + $element['settings'][ $new_id ] = $term_taxonomy_ids; + $args['do_update'] = true; + } + + return $element; + } + + /** + * Convert 'progress' to 'progressbar' + * + * Before Elementor 2.2.0, the progress bar option key was 'progress'. In Elementor 2.2.0, + * it was changed to 'progressbar'. This upgrade script migrated the DB data for old websites using 'progress'. + * + * @param $element + * @param $args + * @return mixed + */ + public static function _convert_progress_to_progressbar( $element, $args ) { + $widget_id = $args['widget_id']; + + if ( empty( $element['widgetType'] ) || $widget_id !== $element['widgetType'] ) { + return $element; + } + + if ( 'progress' === $element['settings']['pagination'] ) { + $element['settings']['pagination'] = 'progressbar'; + $args['do_update'] = true; + } + + return $element; + } + + /** + * Migrate Slides Button Color Settings + * + * Move Slides Widget's 'button_color' settings to 'button_text_color' and 'button_border_color' as necessary, + * to allow for removing the redundant control. + * + * @param $element + * @param $args + * @return mixed + */ + public static function _migrate_slides_button_color_settings( $element, $args ) { + if ( empty( $element['widgetType'] ) || $args['widget_id'] !== $element['widgetType'] ) { + return $element; + } + + // If the element doesn't use the 'button_color' control, no need to do anything. + if ( ! isset( $element['settings']['button_color'] ) ) { + return $element; + } + + // Check if button_text_color is set. If it is not set, transfer the value from button_color to button_text_color. + if ( ! isset( $element['settings']['button_text_color'] ) ) { + $element['settings']['button_text_color'] = $element['settings']['button_color']; + $args['do_update'] = true; + } + + // Check if button_border_color is set. If it is not set, transfer the value from button_color to button_border_color. + if ( ! isset( $element['settings']['button_border_color'] ) ) { + $element['settings']['button_border_color'] = $element['settings']['button_color']; + $args['do_update'] = true; + } + + return $element; + } + + /** + * Copy Title Styles to New Price Controls + * + * Copy the values from the Price List widget's Title Style controls to new Price Style controls. + * + * @param $element + * @param $args + * @return mixed + * @since 3.4.0 + * + */ + public static function _copy_title_styles_to_new_price_controls( $element, $args ) { + if ( empty( $element['widgetType'] ) || $args['widget_id'] !== $element['widgetType'] ) { + return $element; + } + + if ( ! empty( $element['settings']['heading_color'] ) ) { + $element['settings']['price_color'] = $element['settings']['heading_color']; + + $args['do_update'] = true; + } + + $old_control_prefix = 'heading_typography_'; + $new_control_prefix = 'price_typography_'; + + foreach ( self::$typography_control_names as $control_name ) { + if ( ! empty( $element['settings'][ $old_control_prefix . $control_name ] ) ) { + $element['settings'][ $new_control_prefix . $control_name ] = $element['settings'][ $old_control_prefix . $control_name ]; + + $args['do_update'] = true; + } + } + + return $element; + } + + public static function _remove_remote_info_api_data() { + global $wpdb; + + $key = API::TRANSIENT_KEY_PREFIX; + + return $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '{$key}%';"); // phpcs:ignore + } + + /** + * @param $element + * @param $to + * @param $control_id + * @param $args + * @return array + */ + protected static function set_new_value( $element, $to, $control_id, $args ) { + $element['settings'][ $control_id ] = $to; + $args['do_update'] = true; + return $element; + } + + /** * + * @param $change + * @param array $element + * @param $args + * @return array + */ + protected static function replace_value_if_found( $change, array $element, $args ) { + $control_id = key( $args['control_ids'] ); + $from = $change['from']; + $to = $change['to']; + if ( self::is_control_exist_in_settings( $element, $control_id ) && self::is_need_to_replace_value( $element, $control_id, $from ) ) { + $element = self::set_new_value( $element, $to, $control_id, $args ); + } + return $element; + } + + /** + * @param $element + * @param $widget_id + * @return bool + */ + protected static function is_widget_matched( $element, $widget_id ) { + return ! empty( $element['widgetType'] ) && $widget_id === $element['widgetType']; + } + + /** + * @param $changes + * @param $element + * @param $args + * @return array|mixed + */ + protected static function apply_rename( $changes, $element, $args ) { + foreach ( $changes as $change ) { + $element = self::replace_value_if_found( $change, $element, $args ); + } + return $element; + } + + /** + * @param $element + * @param $control_id + * @return bool + */ + protected static function is_control_exist_in_settings( $element, $control_id ) { + return ! empty( $element['settings'][ $control_id ] ); + } + + /** + * @param $element + * @param $new + * @return bool + */ + protected static function is_need_to_replace_value( $element, $control_id, $value_to_replace ) { + return $element['settings'][ $control_id ] === $value_to_replace; + } + + /** + * @return array[] + */ + public static function get_woocommerce_rename_related_to_related_products_changes() { + return [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_rename_widget_settings_value' ], + 'control_ids' => [ + 'query_post_type' => [ + 'from' => 'related', + 'to' => 'related_products', + ], + ], + ], + ]; + } + + public static function _v_3_30_0_post_navigation_inline_icons( $updater ) { + $changes = [ + [ + 'callback' => [ 'ElementorPro\Core\Upgrade\Upgrades', '_migration_select_to_icon_value' ], + 'control_ids' => [], + ], + ]; + + return self::_update_widget_settings( 'post-navigation', $updater, $changes ); + } + + public static function _migration_select_to_icon_value( $element, $args ) { + $is_need_upgrade = ! empty( $element['settings']['arrow'] ) && empty( $element['settings']['arrow_next_icon'] && empty( $element['settings']['arrow_previous_icon'] ) ); + + if ( ! $is_need_upgrade ) { + return $element; + } + + $args['do_update'] = true; + + if ( is_rtl() ) { + $previous_direction = 'right'; + $next_direction = 'left'; + } else { + $previous_direction = 'left'; + $next_direction = 'right'; + } + + $new_value = str_replace( 'fa ', 'fas ', $element['settings']['arrow'] ); + + $element['settings']['arrow_next_icon'] = [ + 'value' => str_replace( '-left', '-' . $next_direction, $new_value ), + 'library' => 'fa-solid', + ]; + + $element['settings']['arrow_previous_icon'] = [ + 'value' => str_replace( '-left', '-' . $previous_direction, $new_value ), + 'library' => 'fa-solid', + ]; + + return $element; + } +} diff --git a/core/utils.php b/core/utils.php new file mode 100644 index 00000000..2f756166 --- /dev/null +++ b/core/utils.php @@ -0,0 +1,454 @@ + true, + ]; + + // Keep for backwards compatibility + if ( ! empty( $args['post_type'] ) ) { + $post_type_args['name'] = $args['post_type']; + unset( $args['post_type'] ); + } + + $post_type_args = wp_parse_args( $post_type_args, $args ); + + $_post_types = get_post_types( $post_type_args, 'objects' ); + + $post_types = []; + + foreach ( $_post_types as $post_type => $object ) { + $post_types[ $post_type ] = $object->label; + } + + /** + * Supported post types. + * + * Filters the allowed post types Elementor should work on. + * + * By default Elementor can be applied on publicly available post + * types. This hook allows developers to alter those post types to + * add new and remove existing types. + * + * @since 2.3.0 + * + * @param array $post_types Elementor supported post types. + */ + $post_types = apply_filters( 'elementor_pro/utils/get_public_post_types', $post_types ); + + return $post_types; + } + + public static function get_client_ip() { + $server_ip_keys = [ + 'HTTP_CLIENT_IP', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED', + 'HTTP_X_CLUSTER_CLIENT_IP', + 'HTTP_FORWARDED_FOR', + 'HTTP_FORWARDED', + 'REMOTE_ADDR', + ]; + + foreach ( $server_ip_keys as $key ) { + $value = static::_unstable_get_super_global_value( $_SERVER, $key ); + if ( $value && filter_var( $value, FILTER_VALIDATE_IP ) ) { + return $value; + } + } + + // Fallback local ip. + return '127.0.0.1'; + } + + public static function get_site_domain() { + return str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ); + } + + public static function get_current_post_id() { + if ( isset( Plugin::elementor()->documents ) && Plugin::elementor()->documents->get_current() ) { + return Plugin::elementor()->documents->get_current()->get_main_id(); + } + + return get_the_ID(); + } + + public static function get_the_archive_url() { + $url = ''; + + if ( Taxonomy_Loop_Provider::is_loop_taxonomy_strict() ) { + global $wp_query; + $url = get_term_link( $wp_query->loop_term ); + } elseif ( is_category() || is_tag() || is_tax() ) { + $url = get_term_link( get_queried_object() ); + } elseif ( is_author() ) { + $url = get_author_posts_url( get_queried_object_id() ); + } elseif ( is_year() ) { + $url = get_year_link( get_query_var( 'year' ) ); + } elseif ( is_month() ) { + $url = get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ); + } elseif ( is_day() ) { + $url = get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) ); + } elseif ( is_post_type_archive() ) { + $url = get_post_type_archive_link( get_post_type() ); + } + + return $url; + } + + public static function get_page_title( $include_context = true ) { + $title = ''; + + if ( is_singular() ) { + /* translators: %s: Search term. */ + $title = get_the_title(); + + if ( $include_context ) { + $post_type_obj = get_post_type_object( get_post_type() ); + $title = sprintf( '%s: %s', $post_type_obj->labels->singular_name, $title ); + } + } elseif ( is_search() ) { + /* translators: %s: Search term. */ + $title = sprintf( esc_html__( 'Search Results for: %s', 'elementor-pro' ), get_search_query() ); + + if ( get_query_var( 'paged' ) ) { + /* translators: %s: Page number. */ + $title .= sprintf( esc_html__( ' – Page %s', 'elementor-pro' ), get_query_var( 'paged' ) ); + } + } elseif ( is_category() ) { + $title = single_cat_title( '', false ); + + if ( $include_context ) { + /* translators: Category archive title. %s: Category name. */ + $title = sprintf( esc_html__( 'Category: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_tag() ) { + $title = single_tag_title( '', false ); + if ( $include_context ) { + /* translators: Tag archive title. %s: Tag name. */ + $title = sprintf( esc_html__( 'Tag: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_author() ) { + $title = '' . get_the_author() . ''; + + if ( $include_context ) { + /* translators: Author archive title. %s: Author name. */ + $title = sprintf( esc_html__( 'Author: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_year() ) { + $title = get_the_date( _x( 'Y', 'yearly archives date format', 'elementor-pro' ) ); + + if ( $include_context ) { + /* translators: Yearly archive title. %s: Year. */ + $title = sprintf( esc_html__( 'Year: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_month() ) { + $title = get_the_date( _x( 'F Y', 'monthly archives date format', 'elementor-pro' ) ); + + if ( $include_context ) { + /* translators: Monthly archive title. %s: Month name and a year. */ + $title = sprintf( esc_html__( 'Month: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_day() ) { + $title = get_the_date( _x( 'F j, Y', 'daily archives date format', 'elementor-pro' ) ); + + if ( $include_context ) { + /* translators: Daily archive title. %s: Date. */ + $title = sprintf( esc_html__( 'Day: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_tax( 'post_format' ) ) { + if ( is_tax( 'post_format', 'post-format-aside' ) ) { + $title = _x( 'Asides', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-gallery' ) ) { + $title = _x( 'Galleries', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-image' ) ) { + $title = _x( 'Images', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-video' ) ) { + $title = _x( 'Videos', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-quote' ) ) { + $title = _x( 'Quotes', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-link' ) ) { + $title = _x( 'Links', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-status' ) ) { + $title = _x( 'Statuses', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-audio' ) ) { + $title = _x( 'Audio', 'post format archive title', 'elementor-pro' ); + } elseif ( is_tax( 'post_format', 'post-format-chat' ) ) { + $title = _x( 'Chats', 'post format archive title', 'elementor-pro' ); + } + } elseif ( is_post_type_archive() ) { + $title = post_type_archive_title( '', false ); + + if ( $include_context ) { + /* translators: Post type archive title. %s: Post type name. */ + $title = sprintf( esc_html__( 'Archives: %s', 'elementor-pro' ), $title ); + } + } elseif ( is_tax() ) { + $title = single_term_title( '', false ); + + if ( $include_context ) { + $tax = get_taxonomy( get_queried_object()->taxonomy ); + /* translators: Taxonomy term archive title. 1: Taxonomy singular name, 2: Current taxonomy term. */ + $title = sprintf( esc_html__( '%1$s: %2$s', 'elementor-pro' ), $tax->labels->singular_name, $title ); + } + } elseif ( is_archive() ) { + $title = esc_html__( 'Archives', 'elementor-pro' ); + } elseif ( is_404() ) { + $title = esc_html__( 'Page Not Found', 'elementor-pro' ); + } // End if(). + + /** + * Page title. + * + * Filters the title of the page. + * + * By default different pages have different titles depending of the page + * context (archive, singular, 404 etc.). This hook allows developers to + * alter those titles. + * + * @since 1.0.0 + * + * @param string $title Page title to be displayed. + */ + $title = apply_filters( 'elementor/utils/get_the_archive_title', $title ); + + return $title; + } + + public static function set_global_authordata() { + global $authordata; + if ( ! isset( $authordata->ID ) ) { + $post = get_post(); + $authordata = get_userdata( $post->post_author ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + } + } + + /** + * Used to overcome core bug when taxonomy is in more then one post type + * + * @see https://core.trac.wordpress.org/ticket/27918 + * + * @global array $wp_taxonomies The registered taxonomies. + * + * + * @param array $args + * @param string $output + * @param string $operator + * + * @return array + */ + public static function get_taxonomies( $args = [], $output = 'names', $operator = 'and' ) { + global $wp_taxonomies; + + $field = ( 'names' === $output ) ? 'name' : false; + + // Handle 'object_type' separately. + if ( isset( $args['object_type'] ) ) { + $object_type = (array) $args['object_type']; + unset( $args['object_type'] ); + } + + $taxonomies = wp_filter_object_list( $wp_taxonomies, $args, $operator ); + + if ( isset( $object_type ) ) { + foreach ( $taxonomies as $tax => $tax_data ) { + if ( ! array_intersect( $object_type, $tax_data->object_type ) ) { + unset( $taxonomies[ $tax ] ); + } + } + } + + if ( $field ) { + $taxonomies = wp_list_pluck( $taxonomies, $field ); + } + + return $taxonomies; + } + + public static function get_ensure_upload_dir( $path ) { + if ( file_exists( $path . '/index.php' ) ) { + return $path; + } + + wp_mkdir_p( $path ); + + $files = [ + [ + 'file' => 'index.php', + 'content' => [ + ' '.htaccess', + 'content' => [ + 'Options -Indexes', + '', + ' ', + ' Header set Content-Disposition attachment', + ' ', + '', + ], + ], + ]; + + foreach ( $files as $file ) { + if ( ! file_exists( trailingslashit( $path ) . $file['file'] ) ) { + $content = implode( PHP_EOL, $file['content'] ); + @ file_put_contents( trailingslashit( $path ) . $file['file'], $content ); + } + } + + return $path; + } + + /** + * Remove words from a sentence. + * + * @param string $text + * @param integer $length + * + * @return string + */ + public static function trim_words( $text, $length ) { + if ( ! $length ) { + return $text; + } + + $whitespace_pattern = '/\s+/u'; + $words = preg_split( $whitespace_pattern, $text, -1, PREG_SPLIT_NO_EMPTY ); + + if ( count( $words ) > $length ) { + $words = array_slice( $words, 0, $length ); + } + + return implode( ' ', $words ); + } + + /** + * Get a user option with default value as fallback. + * TODO: Use `\Elementor\User::get_user_option_with_default()` after this PR is merged: + * https://github.com/elementor/elementor/pull/17745 + * + * @param string $option - Option key. + * @param int $user_id - User ID + * @param mixed $default - Default fallback value. + * + * @return mixed + */ + public static function get_user_option_with_default( $option, $user_id, $default ) { + $value = get_user_option( $option, $user_id ); + + return ( false === $value ) ? $default : $value; + } + + /** + * TODO: Use core method instead (after merging PR of the original function in core). + * PR URL: https://github.com/elementor/elementor/pull/18670. + * + * @param $file + * @param mixed ...$args + * @return false|string + */ + public static function _unstable_file_get_contents( $file, ...$args ) { + if ( ! is_file( $file ) || ! is_readable( $file ) ) { + return false; + } + + return file_get_contents( $file, ...$args ); + } + + /** + * TODO: Use core method instead (after Pro minimum requirements is updated). + * PR URL: https://github.com/elementor/elementor/pull/24092 + */ + public static function _unstable_get_super_global_value( $super_global, $key ) { + if ( ! isset( $super_global[ $key ] ) ) { + return null; + } + + if ( $_FILES === $super_global ) { + return isset( $super_global[ $key ]['name'] ) ? + static::sanitize_file_name( $super_global[ $key ] ) : + static::sanitize_multi_upload( $super_global[ $key ] ); + } + + return wp_kses_post_deep( wp_unslash( $super_global[ $key ] ) ); + } + + private static function sanitize_multi_upload( $fields ) { + return array_map( function( $field ) { + return array_map( [ __CLASS__, 'sanitize_file_name' ], $field ); + }, $fields ); + } + + private static function sanitize_file_name( $file ) { + $file['name'] = sanitize_file_name( $file['name'] ); + + return $file; + } + + /** + * TODO: Use a core method instead (after Pro minimum requirements is updated). + * @throws \Exception + */ + public static function _unstable_get_document_for_edit( $id ) { + $document = Plugin::elementor()->documents->get( $id ); + + if ( ! $document ) { + throw new \Exception( 'Not found.' ); + } + + if ( ! $document->is_editable_by_current_user() ) { + throw new \Exception( 'Access denied.' ); + } + + return $document; + } + + public static function format_control_condition( $name, $operator, $value ) { + return compact( 'name', 'operator', 'value' ); + } + + public static function create_widget_instance_from_db( $post_id, $widget_id ) { + $document = Plugin::elementor()->documents->get( $post_id ); + $widget_data = \Elementor\Utils::find_element_recursive( $document->get_elements_data(), $widget_id ); + + return Plugin::elementor()->elements_manager->create_element_instance( $widget_data ); + } + + public static function has_invalid_post_permissions( $post ): bool { + $is_image_attachment = 'attachment' === $post->post_type && strpos( $post->post_mime_type, 'image/' ) === 0; + + if ( $is_image_attachment ) { + return false; + } + + $is_private = 'private' === $post->post_status + && ! current_user_can( 'read_private_posts', $post->ID ); + + $not_allowed = 'publish' !== $post->post_status + && ! current_user_can( 'edit_post', $post->ID ); + + $password_required = post_password_required( $post->ID ) + && ! current_user_can( 'edit_post', $post->ID ); + + return $is_private || $not_allowed || $password_required; + } + + public static function is_sale_time(): bool { + return \Elementor\Utils::is_sale_time(); + } +} diff --git a/core/utils/abtest.php b/core/utils/abtest.php new file mode 100644 index 00000000..620000d0 --- /dev/null +++ b/core/utils/abtest.php @@ -0,0 +1,40 @@ +map_with_keys( function ( $item ) use ( $key ) { + return [ $item->{$key} => $item ]; + } ); + } + + /** + * Flatten the items recursively. + * + * @return array + */ + public function flatten_recursive() { + $output = []; + $items = $this->all(); + + array_walk_recursive($items, function( $item ) use ( &$output ) { + $output[] = $item; + } ); + + return $output; + } + + /** + * Run array_diff between the collection and other array or collection. + * + * @param $filter + * + * @return $this + */ + public function diff( $filter ) { + if ( $filter instanceof Collection_Base ) { + $filter = $filter->all(); + } + + return new static( array_diff( $this->all(), $filter ) ); + } + + /** + * Reverse the array + * + * @param false $preserve_keys + * + * @return $this + */ + public function reverse( $preserve_keys = false ) { + return new static( + array_reverse( $this->all(), $preserve_keys ) + ); + } + + /** + * Return a JSON serialized representation of the Collection. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() { + return $this->all(); + } +} diff --git a/core/utils/hints.php b/core/utils/hints.php new file mode 100644 index 00000000..6f8cf978 --- /dev/null +++ b/core/utils/hints.php @@ -0,0 +1,100 @@ + $value ) { + switch ( $key ) { + case self::DISMISSED: + // support multiple dismissed hints + foreach ( (array) $value as $dismissed_hint ) { + if ( self::is_dismissed( $dismissed_hint ) ) { + return false; + } + } + break; + case self::CAPABILITY: + if ( ! current_user_can( $value ) ) { + return false; + } + break; + case self::DEFINED: + if ( defined( $value ) ) { + return false; + } + break; + case self::PLUGIN_INSTALLED: + if ( ! self::is_plugin_installed( $value ) ) { + return false; + } + break; + case self::PLUGIN_ACTIVE: + if ( ! self::is_plugin_active( $value ) ) { + return false; + } + break; + } + } + return true; + } + + public static function get_hints( $hint_key = null ): array { + $hints = [ + 'site_mailer_forms_email_notice' => [ + self::DISMISSED => 'site_mailer_forms_email_notice', + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SITE_MAILER_VERSION', + ], + 'site_mailer_forms_submissions_notice' => [ + self::DISMISSED => [ 'site_mailer_forms_submissions_notice', 'site_mailer_forms_email_notice' ], + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SITE_MAILER_VERSION', + ], + 'send_app_wc_widgets_notice' => [ + self::DISMISSED => [ 'send_app_wc_widgets_notice' ], + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SEND_VERSION', + ], + 'send_app_forms_submissions_notice' => [ + self::DISMISSED => [ 'send_app_forms_submissions_notice', 'send_app_forms_actions_notice' ], + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SEND_VERSION', + ], + 'send_app_forms_actions_notice' => [ + self::DISMISSED => [ 'send_app_forms_actions_notice' ], + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SEND_VERSION', + ], + 'send_app_forms_triggers_notice' => [ + self::DISMISSED => [ 'send_app_forms_triggers_notice' ], + self::CAPABILITY => 'install_plugins', + self::DEFINED => 'SEND_VERSION', + ], + ]; + if ( ! $hint_key ) { + return $hints; + } + + return $hints[ $hint_key ] ?? []; + } +} diff --git a/core/utils/registrar.php b/core/utils/registrar.php new file mode 100644 index 00000000..55f979b3 --- /dev/null +++ b/core/utils/registrar.php @@ -0,0 +1,68 @@ +items = []; + } + + /** + * Register a new item. + * + * @param $instance - Item instance. + * @param string $id - Optional - For BC - Deprecated. + * + * @return boolean - Whether the item was registered. + */ + public function register( $instance, $id = null ) { + // TODO: For BC. Remove in the future. + if ( ! $id ) { + // Get the ID or default to the class name. + $id = ( method_exists( $instance, 'get_id' ) ) ? $instance->get_id() : get_class( $instance ); + } + + if ( $this->get( $id ) ) { + return false; + } + + $this->items[ $id ] = $instance; + + return true; + } + + /** + * Get an item by ID. + * + * @param string $id + * + * @return array|null + */ + public function get( $id = null ) { + if ( ! $id ) { + return $this->items; + } + + return isset( $this->items[ $id ] ) ? $this->items[ $id ] : null; + } +} diff --git a/data/base/controller.php b/data/base/controller.php new file mode 100644 index 00000000..7533ed83 --- /dev/null +++ b/data/base/controller.php @@ -0,0 +1,13 @@ +namespace = 'elementor-pro/v1'; + } +} diff --git a/data/http-status.php b/data/http-status.php new file mode 100644 index 00000000..ebea7760 --- /dev/null +++ b/data/http-status.php @@ -0,0 +1,23 @@ + +Modifications Copyright (C) 2020–2025 PRO Elements team + +This program incorporates and is a derivative work of code from Elementor Pro +by Elementor Ltd., which is licensed under the GNU General Public License +version 3 (GPLv3). Accordingly, this program is licensed under the terms of +the GNU General Public License, version 3 or (at your option) any later version. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this +program. If not, see . + +Additional terms under GPLv3 §7 (permitted): +- Preserve the above copyright notices and the GPL license notice in redistributions. +- Mark altered source versions plainly as changed, and do not misrepresent them as the + original work. + +Trademark note (informative, not a license term): +“Elementor” is a trademark of Elementor Ltd.; no trademark rights are granted by this license. \ No newline at end of file diff --git a/license/admin.php b/license/admin.php new file mode 100644 index 00000000..b283f2fb --- /dev/null +++ b/license/admin.php @@ -0,0 +1,91 @@ +register_rest_controller(); + } + + public function get_installed_time() { + $installed_time = get_option( '_elementor_pro_installed_time' ); + + if ( ! $installed_time ) { + $installed_time = time(); + update_option( '_elementor_pro_installed_time', $installed_time ); + } + + return $installed_time; + } + + public static function get_license_key() { + return ""; + } + + /** + * @return Activate + */ + private function get_app() { + return Plugin::elementor()->common->get_component( 'connect' )->get_app( 'activate' ); + } + + public function get_connect_url( $params = [] ) { + return $this->get_app()->get_admin_url( 'authorize', $params ); + } + + public static function get_url() { + return ""; + } + + public function rest_remove_pro_templates ( $response, $handler, $request ) { + $route = $request->get_route(); + if ( $request->get_method() === 'GET' && strpos( $route, '/elementor/v1/template-library/templates' ) !== false ) { + if ( isset( $response->data['templates'] ) ) { + $response->data['templates'] = array_filter( $response->data['templates'], function( $item ) { + return empty( $item['is_pro'] ) || intval( $item['is_pro'] ) === 0; + }); + } + } + + return $response; + } + public function http_remove_pro_templates ( $response, $parsed_args, $url ) { + if ( strpos( $url, static::API_TEMPLATES_URL ) === 0 ) { + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + + if ( is_array( $body ) ) { + $body = array_filter( $body, function( $item ) { + return empty( $item['is_pro'] ) || intval( $item['is_pro'] ) === 0; + }); + $response['body'] = wp_json_encode( array_values( $body ) ); + } + } + return $response; + } + + public function register_actions() { + add_filter( 'http_response', [ $this, 'http_remove_pro_templates'], 10, 3 ); + + add_filter( 'rest_request_after_callbacks', [ $this, 'rest_remove_pro_templates' ], 10, 3 ); + } + + private function register_rest_controller() { + new Controller(); + } +} diff --git a/license/api.php b/license/api.php new file mode 100644 index 00000000..6d89564c --- /dev/null +++ b/license/api.php @@ -0,0 +1,391 @@ + strtotime( $expiration, current_time( 'timestamp' ) ), + 'value' => json_encode( $value ), + ]; + + $updated = update_option( $cache_key, $data, false ); + if ( false === $updated ) { + self::$transient_data[ $cache_key ] = $data; + } + } + + private static function get_transient( $cache_key ) { + $cache = self::$transient_data[ $cache_key ] ?? get_option( $cache_key ); + + if ( empty( $cache['timeout'] ) ) { + return false; + } + + if ( current_time( 'timestamp' ) > $cache['timeout'] && is_user_logged_in() ) { + return false; + } + + return json_decode( $cache['value'], true ); + } + + public static function set_license_data( $license_data, $expiration = null ) { + } + public static function get_license_data( $force_request = false ) { + $license_data['success'] = true; + $license_data['expires'] = 'lifetime'; + $license_data['features'] = [ + 'custom-attributes', + 'custom_code', + 'custom-css', + 'global-css', + 'display-conditions', + 'dynamic-tags-acf', + 'dynamic-tags-pods', + 'dynamic-tags-toolset', + 'element-manager-permissions', + 'global-widget', + 'editor_comments', + 'stripe-button', + 'popup', + 'role-manager', + 'woocommerce-menu-cart', + 'product-single', + 'product-archive', + 'settings-woocommerce-pages', + 'settings-woocommerce-notices', + 'dynamic-tags-wc', + 'settings-woocommerce-pages', + 'settings-woocommerce-notices']; + return $license_data; + } + + public static function get_version( $force_update = true, $additional_status = '' ) { + return []; + } + + public static function get_plugin_package_url( $version ) { + return ''; + } + + public static function get_errors() { + return [ + 'no_activations_left' => '', + 'expired' => '', + 'missing' => '', + 'cancelled' => '', + 'key_mismatch' => '', + ]; + } + + public static function get_error_message( $error ) { + $errors = self::get_errors(); + + if ( isset( $errors[ $error ] ) ) { + $error_msg = $errors[ $error ]; + } else { + $error_msg = esc_html__( 'An error occurred. Please check your internet connection and try again. If the problem persists, contact our support.', 'elementor-pro' ) . ' (' . $error . ')'; + } + + return $error_msg; + } + + public static function is_license_active() { + $license_data = self::get_license_data(); + + return (bool) $license_data['success']; + } + + public static function is_license_expired() { + $license_data = self::get_license_data(); + + return ! empty( $license_data['error'] ) && self::STATUS_EXPIRED === $license_data['error']; + } + + public static function is_licence_pro_trial() { + return self::is_licence_has_feature( self::FEATURE_PRO_TRIAL ); + } + + public static function is_licence_has_feature( $feature_name, $license_check_validator = null ) { + $license_data = self::get_license_data(); + + if ( self::custom_licence_validator_passed( $license_check_validator ) ) { + return true; + } + + return ! empty( $license_data['features'] ) + && in_array( $feature_name, $license_data['features'], true ); + } + + private static function custom_licence_validator_passed( $license_check_validator ) { + return null !== $license_check_validator && + is_callable( [ __CLASS__, $license_check_validator ] ) && + self::$license_check_validator(); + } + + private static function should_allow_all_features() { + return ! self::licence_supports_tiers() || self::is_frontend(); + } + + private static function is_frontend() { + return ! is_admin() && ! Plugin::elementor()->preview->is_preview_mode(); + } + + /* + * We can consider removing this function and it's usages at a future point if + * we feel confident that all user's Licence Caches has been refreshed + * and should definitely contain a tier and generation. + */ + private static function licence_supports_tiers() { + $license_data = self::get_license_data(); + + return ! empty( $license_data[ static::LICENCE_TIER_KEY ] ) && ! empty( $license_data[ static::LICENCE_GENERATION_KEY ] ); + } + + public static function is_need_to_show_upgrade_promotion() { + if ( ! self::licence_supports_tiers() ) { + return false; + } + + return self::is_licence_tier( static::TIER_ESSENENTIAL ) && self::is_licence_generation( static::GENERATION_EMPTY ); + } + + private static function is_licence_tier( $tier ) { + if ( ! self::licence_supports_tiers() ) { + return false; + } + + return self::get_license_data()[ static::LICENCE_TIER_KEY ] === $tier; + } + + private static function is_licence_generation( $generation ) { + if ( ! self::licence_supports_tiers() ) { + return false; + } + + return self::get_license_data()[ static::LICENCE_GENERATION_KEY ] === $generation; + } + + public static function filter_active_features( $features ) { + if ( self::should_allow_all_features() ) { + return array_values( $features ); + } + + $license_data = self::get_license_data(); + $filtered_values = []; + + if ( ! is_array( $license_data['features'] ) ) { + $license_data['features'] = []; + } + + foreach ( $license_data['features'] as $key ) { + if ( ! array_key_exists( $key, $features ) ) { + continue; + } + + $filtered_values[] = $features[ $key ]; + } + + return $filtered_values; + } + + public static function get_promotion_widgets() { + $promotions = Core_API::get_promotion_widgets(); + $license_data = self::get_license_data(); + + if ( ! self::licence_supports_tiers() ) { + return []; + } + + if ( ! is_array( $license_data['features'] ) ) { + $license_data['features'] = []; + } + + foreach ( $promotions as $key => $promotion ) { + if ( ! in_array( $promotion['name'], $license_data['features'] ) ) { + continue; + } + + unset( $promotions[ $key ] ); + } + + return array_values( $promotions ); + } + + /* + * Check if the Licence is not Expired and also has a Feature. + * Needed because even Expired Licences keep the features array for BC. + */ + public static function active_licence_has_feature( $feature_name ) { + return ! self::is_license_expired() && self::is_licence_has_feature( $feature_name, static::BC_VALIDATION_CALLBACK ); + } + + public static function is_license_about_to_expire() { + $license_data = self::get_license_data(); + + if ( ! empty( $license_data['recurring'] ) ) { + return false; + } + + if ( 'lifetime' === $license_data['expires'] ) { + return false; + } + + return time() > strtotime( '-28 days', strtotime( $license_data['expires'] ) ); + } + + /** + * @param string $library_type + * + * @return int + */ + public static function get_library_access_level( $library_type = 'template' ) { + $license_data = static::get_license_data(); + + $access_level = ConnectModule::ACCESS_LEVEL_CORE; + + if ( static::is_license_active() ) { + $access_level = ConnectModule::ACCESS_LEVEL_PRO; + } + + // For BC: making sure that it returns the correct access_level even if "features" is not defined in the license data. + if ( ! isset( $license_data['features'] ) || ! is_array( $license_data['features'] ) ) { + return $access_level; + } + + $library_access_level_prefix = "{$library_type}_access_level_"; + + foreach ( $license_data['features'] as $feature ) { + if ( strpos( $feature, $library_access_level_prefix ) !== 0 ) { + continue; + } + + $access_level = (int) str_replace( $library_access_level_prefix, '', $feature ); + } + + return $access_level; + } + + /** + * The license API uses "tiers" and "generations". + * Because we don't use the same logic, and have a flat list of prioritized tiers & generations, + * we take the generation if exists and fallback to the tier otherwise. + * + * For example: + * [ 'tier' => 'essential', 'generation' => 'essential-oct2023' ] => 'essential-oct2023' + * [ 'tier' => 'essential', 'generation' => 'empty' ] => 'essential' + * [ 'tier' => '', 'generation' => '' ] => 'essential-oct2023' + * [] => 'essential-oct2023' + * + * @return string + */ + public static function get_access_tier() { + if ( ! static::is_license_active() ) { + return 'free'; + } + + $license_data = static::get_license_data(); + $tier = $license_data['tier'] ?? null; + $generation = $license_data['generation'] ?? null; + + // Fallback to legacy license when the API returns empty values. + $is_legacy_api = empty( $tier ) || empty( $generation ); + + if ( $is_legacy_api ) { + return 'essential-oct2023'; + } + + // The license API returns "empty" instead of empty string. + $has_generation = 'empty' !== $generation; + + if ( $has_generation ) { + return $generation; + } + + return $tier; + } + + public static function get_plan_type() { + if ( ! static::is_license_active() ) { + return 'free'; + } + + $license_data = static::get_license_data(); + $plan_type = $license_data['tier'] ?? 'free'; + + return $plan_type; + } +} diff --git a/license/data/controller.php b/license/data/controller.php new file mode 100644 index 00000000..f343b95a --- /dev/null +++ b/license/data/controller.php @@ -0,0 +1,19 @@ +register_endpoint( Endpoints\Get_Tier_Features::class ); + } +} diff --git a/license/data/endpoints/get-tier-features.php b/license/data/endpoints/get-tier-features.php new file mode 100644 index 00000000..9223b54e --- /dev/null +++ b/license/data/endpoints/get-tier-features.php @@ -0,0 +1,48 @@ +controller->get_namespace(), + '/' . $this->controller->get_name() . '/' . $this->get_route(), + [ + [ + 'methods' => 'GET', + 'callback' => [ $this, 'get_features' ], + 'permission_callback' => [ $this, 'permission_callback' ], + ], + ] + ); + } + + public function get_features( $request ) { + $license_data = API::get_license_data(); + $features = ! empty( $license_data['features'] ) ? $license_data['features'] : []; + + return new \WP_REST_Response( [ + 'features' => $features, + ], 200 ); + } + + public function permission_callback( $request ) { + return is_user_logged_in(); + } +} diff --git a/modules/admin-top-bar/module.php b/modules/admin-top-bar/module.php new file mode 100644 index 00000000..040c50d8 --- /dev/null +++ b/modules/admin-top-bar/module.php @@ -0,0 +1,53 @@ +get_settings(); + $current_screen = null; + + // For BC support. + // when the action 'elementor/admin-top-bar/init' triggered before screen is registered. + // TODO: need to remove if elementor core version 3.5.0 is stable + if ( function_exists( 'get_current_screen' ) ) { + $current_screen = get_current_screen(); + } + + /** @var Activate $activate */ + $activate = Plugin::elementor()->common->get_component( 'connect' )->get_app( 'activate' ); + + $settings['is_user_connected'] = $settings['is_user_connected'] && API::is_license_active(); + $settings['connect_url'] = ! API::is_license_active() ? + $activate->get_admin_url( 'authorize', [ + 'utm_source' => 'top-bar', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + 'utm_content' => $current_screen ? $current_screen->id : '', + ] ) : + $settings['connect_url']; + + $module->set_settings( $settings ); + } ); + } +} diff --git a/modules/animated-headline/module.php b/modules/animated-headline/module.php new file mode 100644 index 00000000..85cd2da1 --- /dev/null +++ b/modules/animated-headline/module.php @@ -0,0 +1,53 @@ +get_css_assets_url( 'widget-animated-headline', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/animated-headline/widgets/animated-headline.php b/modules/animated-headline/widgets/animated-headline.php new file mode 100644 index 00000000..b67034e8 --- /dev/null +++ b/modules/animated-headline/widgets/animated-headline.php @@ -0,0 +1,680 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-animated-headline' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'text_elements', + [ + 'label' => esc_html__( 'Headline', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'headline_style', + [ + 'label' => esc_html__( 'Animation Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'highlight', + 'options' => [ + 'highlight' => esc_html__( 'Highlighted Text', 'elementor-pro' ), + 'rotate' => esc_html__( 'Rotating Text', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-headline--style-', + 'render_type' => 'template', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'animation_type', + [ + 'label' => esc_html__( 'Animation Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'typing' => 'Typing', + 'clip' => 'Clip', + 'flip' => 'Flip', + 'swirl' => 'Swirl', + 'blinds' => 'Blinds', + 'drop-in' => 'Drop-in', + 'wave' => 'Wave', + 'slide' => 'Slide', + 'slide-down' => 'Slide Down', + ], + 'default' => 'typing', + 'condition' => [ + 'headline_style' => 'rotate', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'marker', + [ + 'label' => esc_html__( 'Animation Shape', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'circle', + 'options' => [ + 'circle' => _x( 'Circle', 'Shapes', 'elementor-pro' ), + 'curly' => _x( 'Curly', 'Shapes', 'elementor-pro' ), + 'underline' => _x( 'Underline', 'Shapes', 'elementor-pro' ), + 'double' => _x( 'Double', 'Shapes', 'elementor-pro' ), + 'double_underline' => _x( 'Double Underline', 'Shapes', 'elementor-pro' ), + 'underline_zigzag' => _x( 'Underline Zigzag', 'Shapes', 'elementor-pro' ), + 'diagonal' => _x( 'Diagonal', 'Shapes', 'elementor-pro' ), + 'strikethrough' => _x( 'Strikethrough', 'Shapes', 'elementor-pro' ), + 'x' => 'X', + ], + 'render_type' => 'template', + 'condition' => [ + 'headline_style' => 'highlight', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'before_text', + [ + 'label' => esc_html__( 'Before Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::TEXT_CATEGORY, + ], + ], + 'default' => esc_html__( 'This page is', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your headline', 'elementor-pro' ), + 'label_block' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'highlighted_text', + [ + 'label' => esc_html__( 'Highlighted Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::TEXT_CATEGORY, + ], + ], + 'default' => esc_html__( 'Amazing', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'headline_style' => 'highlight', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'rotating_text', + [ + 'label' => esc_html__( 'Rotating Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'placeholder' => esc_html__( 'Enter each word in a separate line', 'elementor-pro' ), + 'default' => "Better\nBigger\nFaster", + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::TEXT_CATEGORY, + ], + ], + 'condition' => [ + 'headline_style' => 'rotate', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'after_text', + [ + 'label' => esc_html__( 'After Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::TEXT_CATEGORY, + ], + ], + 'placeholder' => esc_html__( 'Enter your headline', 'elementor-pro' ), + 'label_block' => true, + ] + ); + + $this->add_control( + 'loop', + [ + 'label' => esc_html__( 'Infinite Loop', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'render_type' => 'template', + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--iteration-count: infinite', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'highlight_animation_duration', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'default' => 1200, + 'render_type' => 'template', + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--animation-duration: {{VALUE}}ms', + ], + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->add_control( + 'highlight_iteration_delay', + [ + 'label' => esc_html__( 'Delay', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'default' => 8000, + 'render_type' => 'template', + 'frontend_available' => true, + 'condition' => [ + 'headline_style' => 'highlight', + 'loop' => 'yes', + ], + ] + ); + + $this->add_control( + 'rotate_iteration_delay', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'default' => 2500, + 'render_type' => 'template', + 'frontend_available' => true, + 'condition' => [ + 'headline_style' => 'rotate', + ], + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'h3', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_text', + [ + 'label' => esc_html__( 'Headline', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .elementor-headline' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-headline-plain-text' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-headline', + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-headline .elementor-headline-plain-text', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'title_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-headline .elementor-headline-plain-text', + ] + ); + + $this->add_control( + 'heading_words_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Animated Text', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'words_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--dynamic-text-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'words_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-headline-dynamic-text', + 'exclude' => [ 'font_size' ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'animated_text_stroke', + 'selector' => '{{WRAPPER}} .elementor-headline .elementor-headline-dynamic-wrapper', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'animated_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-headline .elementor-headline-dynamic-wrapper', + ] + ); + + $this->add_control( + 'typing_animation_highlight_colors', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Selected Text', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'headline_style' => 'rotate', + 'animation_type' => 'typing', + ], + ] + ); + + $this->add_control( + 'highlighted_text_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--typing-selected-bg-color: {{VALUE}}', + ], + 'condition' => [ + 'headline_style' => 'rotate', + 'animation_type' => 'typing', + ], + ] + ); + + $this->add_control( + 'highlighted_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--typing-selected-color: {{VALUE}}', + ], + 'condition' => [ + 'headline_style' => 'rotate', + 'animation_type' => 'typing', + ], + ] + ); + + $this->add_control( + 'highlight_animation_shape_colors', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Highlighted Shape', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->add_control( + 'marker_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-headline-dynamic-wrapper path' => 'stroke: {{VALUE}}', + ], + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->add_control( + 'stroke_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-headline-dynamic-wrapper path' => 'stroke-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->add_control( + 'above_content', + [ + 'label' => esc_html__( 'Bring to Front', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}} .elementor-headline-dynamic-wrapper svg' => 'z-index: 2', + '{{WRAPPER}} .elementor-headline-dynamic-text' => 'z-index: auto', + ], + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->add_control( + 'rounded_edges', + [ + 'label' => esc_html__( 'Rounded Edges', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}} .elementor-headline-dynamic-wrapper path' => 'stroke-linecap: round; stroke-linejoin: round', + ], + 'condition' => [ + 'headline_style' => 'highlight', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + $tag = Utils::validate_html_tag( $settings['tag'] ); + + $this->add_render_attribute( 'headline', 'class', 'elementor-headline' ); + + if ( 'rotate' === $settings['headline_style'] ) { + $this->add_render_attribute( 'headline', 'class', 'elementor-headline-animation-type-' . $settings['animation_type'] ); + + $is_letter_animation = in_array( $settings['animation_type'], [ 'typing', 'swirl', 'blinds', 'wave' ] ); + + if ( $is_letter_animation ) { + $this->add_render_attribute( 'headline', 'class', 'elementor-headline-letters' ); + } + } + + if ( ! empty( $settings['link']['url'] ) ) { + $this->add_link_attributes( 'url', $settings['link'] ); + ?> + print_render_attribute_string( 'url' ); ?>> + + + < print_render_attribute_string( 'headline' ); ?>> + + get_settings_for_display( 'before_text' ) ); ?> + + + $text ) : ?> + + + + + + get_settings_for_display( 'highlighted_text' ) ); ?> + + + + get_settings_for_display( 'after_text' ) ); ?> + + > + '; + } + } + + /** + * Render Animated Headline widget output in the editor. + * + * Written as a Backbone JavaScript template and used to generate the live preview. + * + * @since 2.9.0 + * @access protected + */ + protected function content_template() { + ?> + <# + var headlineClasses = 'elementor-headline', + tag = elementor.helpers.validateHTMLTag( settings.tag ); + const sanitizedAnimationType = elementor.helpers.sanitize( settings.animation_type ).replaceAll(/'|"/g, ''); + + if ( 'rotate' === settings.headline_style ) { + headlineClasses += ' elementor-headline-animation-type-' + sanitizedAnimationType; + + var isLetterAnimation = -1 !== [ 'typing', 'swirl', 'blinds', 'wave' ].indexOf( settings.animation_type ); + + if ( isLetterAnimation ) { + headlineClasses += ' elementor-headline-letters'; + } + } + + if ( settings.link?.url ) { #> + + <# } #> + <{{{ tag }}} class="{{{ headlineClasses }}}"> + <# if ( settings.before_text ) { #> + {{{ elementor.helpers.sanitize( settings.before_text, { ALLOW_DATA_ATTR: false } ) }}} + <# } #> + + <# if ( settings.rotating_text ) { #> + + <# if ( 'rotate' === settings.headline_style && settings.rotating_text ) { + var rotatingText = ( settings.rotating_text || '' ).split( '\n' ); + for ( var i = 0; i < rotatingText.length; i++ ) { + var statusClass = 0 === i ? 'elementor-headline-text-active' : ''; #> + + {{{ rotatingText[ i ].replace( ' ', ' ' ) }}} + + <# } + } + + else if ( 'highlight' === settings.headline_style && settings.highlighted_text ) { #> + {{{ elementor.helpers.sanitize( settings.highlighted_text, { ALLOW_DATA_ATTR: false } ) }}} + <# } #> + + <# } #> + + <# if ( settings.after_text ) { #> + {{{ elementor.helpers.sanitize( settings.after_text, { ALLOW_DATA_ATTR: false } ) }}} + <# } #> + + <# if ( settings.link?.url ) { #> + + <# } #> + strtotime( '-' . static::MUTED_PERIOD . ' days' ) ) { + return false; + } + + return true; + } +} diff --git a/modules/assets-manager/asset-types/admin-menu-items/custom-fonts-menu-item.php b/modules/assets-manager/asset-types/admin-menu-items/custom-fonts-menu-item.php new file mode 100644 index 00000000..a3d31144 --- /dev/null +++ b/modules/assets-manager/asset-types/admin-menu-items/custom-fonts-menu-item.php @@ -0,0 +1,32 @@ +license_admin->get_connect_url( [ + 'utm_source' => 'wp-custom-fonts', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + ] ); + + $renew_url = 'https://go.elementor.com/renew-custom-fonts/'; + + return API::is_license_expired() + ? $renew_url + : $connect_url; + } + + public function get_cta_text() { + return API::is_license_expired() + ? esc_html__( 'Renew now', 'elementor-pro' ) + : esc_html__( 'Connect & Activate', 'elementor-pro' ); + } + + public function get_label() { + return esc_html__( 'Custom Fonts', 'elementor-pro' ); + } + + public function get_page_title() { + return esc_html__( 'Custom Fonts', 'elementor-pro' ); + } + + public function get_promotion_title() { + return esc_html__( 'Add Your Custom Fonts', 'elementor-pro' ); + } + + public function get_promotion_description() { + return esc_html__( + 'Custom Fonts allows you to add your self-hosted fonts and use them on your projects to create a unique brand language.', + 'elementor-pro' + ); + } + + /** + * @deprecated use get_promotion_description instead + * @return void + */ + public function render_promotion_description() { + echo $this->get_promotion_description(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/assets-manager/asset-types/admin-menu-items/custom-icons-menu-item.php b/modules/assets-manager/asset-types/admin-menu-items/custom-icons-menu-item.php new file mode 100644 index 00000000..fb329ee8 --- /dev/null +++ b/modules/assets-manager/asset-types/admin-menu-items/custom-icons-menu-item.php @@ -0,0 +1,33 @@ +license_admin->get_connect_url( [ + 'utm_source' => 'wp-custom-icons', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + ] ); + + $renew_url = 'https://go.elementor.com/renew-custom-icons/'; + + return API::is_license_expired() + ? $renew_url + : $connect_url; + } + + public function get_position() { + return null; + } + + public function get_cta_text() { + return API::is_license_expired() + ? esc_html__( 'Renew now', 'elementor-pro' ) + : esc_html__( 'Connect & Activate', 'elementor-pro' ); + } + + public function get_label() { + return esc_html__( 'Custom Icons', 'elementor-pro' ); + } + + public function get_page_title() { + return esc_html__( 'Custom Icons', 'elementor-pro' ); + } + + public function get_promotion_title() { + return esc_html__( 'Add Your Custom Icons', 'elementor-pro' ); + } + + public function get_promotion_description() { + return esc_html__( + 'Don\'t rely solely on the FontAwesome icons everyone else is using! Differentiate your website and your style with custom icons you can upload from your favorite icons source.', + 'elementor-pro' + ); + } + + /** + * @deprecated use get_promotion_description instead + * @return void + */ + public function render_promotion_description() { + echo $this->get_promotion_description(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/assets-manager/asset-types/fonts-manager.php b/modules/assets-manager/asset-types/fonts-manager.php new file mode 100644 index 00000000..0c5f4d1f --- /dev/null +++ b/modules/assets-manager/asset-types/fonts-manager.php @@ -0,0 +1,690 @@ +font_types; + } + + if ( isset( $this->font_types[ $type ] ) ) { + return $this->font_types[ $type ]; + } + + return false; + } + + /** + * Add a font type to the font manager + * + * @param string $font_type + * @param Classes\Font_Base $instance + */ + public function add_font_type( $font_type, $instance ) { + $this->font_types[ $font_type ] = $instance; + } + + /** + * Register elementor font custom post type and elementor font type custom taxonomy + */ + public function register_post_type_and_tax() { + $labels = [ + 'name' => _x( 'Custom Fonts', 'CPT Name', 'elementor-pro' ), + 'singular_name' => _x( 'Font', 'CPT Singular Name', 'elementor-pro' ), + 'add_new' => esc_html__( 'Add New', 'elementor-pro' ), + 'add_new_item' => esc_html__( 'Add New Font', 'elementor-pro' ), + 'edit_item' => esc_html__( 'Edit Font', 'elementor-pro' ), + 'new_item' => esc_html__( 'New Font', 'elementor-pro' ), + 'all_items' => esc_html__( 'All Fonts', 'elementor-pro' ), + 'view_item' => esc_html__( 'View Font', 'elementor-pro' ), + 'search_items' => esc_html__( 'Search Font', 'elementor-pro' ), + 'not_found' => esc_html__( 'No fonts found', 'elementor-pro' ), + 'not_found_in_trash' => esc_html__( 'No fonts found in trash', 'elementor-pro' ), + 'parent_item_colon' => '', + 'menu_name' => _x( 'Custom Fonts', 'CPT Menu Name', 'elementor-pro' ), + ]; + + $args = [ + 'labels' => $labels, + 'public' => false, + 'rewrite' => false, + 'show_ui' => true, + 'show_in_menu' => false, + 'show_in_nav_menus' => false, + 'exclude_from_search' => true, + 'capability_type' => 'post', + 'hierarchical' => false, + 'supports' => [ 'title' ], + ]; + + $this->post_type_object = register_post_type( self::CPT, $args ); + + $taxonomy_labels = [ + 'name' => _x( 'Font Types', 'Font type taxonomy general name', 'elementor-pro' ), + 'singular_name' => _x( 'Font Type', 'Font type singular name', 'elementor-pro' ), + 'search_items' => esc_html__( 'Search Font Types', 'elementor-pro' ), + 'popular_items' => esc_html__( 'Popular Font Types', 'elementor-pro' ), + 'all_items' => esc_html__( 'All Font Types', 'elementor-pro' ), + 'edit_item' => esc_html__( 'Edit Font Type', 'elementor-pro' ), + 'update_item' => esc_html__( 'Update Font Type', 'elementor-pro' ), + 'add_new_item' => esc_html__( 'Add New Font Type', 'elementor-pro' ), + 'new_item_name' => esc_html__( 'New Font Type Name', 'elementor-pro' ), + 'separate_items_with_commas' => esc_html__( 'Separate Font Types with commas', 'elementor-pro' ), + 'add_or_remove_items' => esc_html__( 'Add or remove Font Types', 'elementor-pro' ), + 'choose_from_most_used' => esc_html__( 'Choose from the most used Font Types', 'elementor-pro' ), + 'not_found' => esc_html__( 'No Font Types found.', 'elementor-pro' ), + 'menu_name' => esc_html__( 'Font Types', 'elementor-pro' ), + ]; + + $taxonomy_args = [ + 'labels' => $taxonomy_labels, + 'hierarchical' => false, + 'show_ui' => true, + 'show_in_nav_menus' => false, + 'query_var' => is_admin(), + 'rewrite' => false, + 'public' => false, + 'meta_box_cb' => [ $this, 'print_taxonomy_metabox' ], + ]; + + $this->taxonomy_object = register_taxonomy( self::TAXONOMY, self::CPT, $taxonomy_args ); + } + + public function post_updated_messages( $messages ) { + $messages[ self::CPT ] = [ + 0 => '', // Unused. Messages start at index 1. + 1 => esc_html__( 'Font updated.', 'elementor-pro' ), + 2 => esc_html__( 'Custom field updated.', 'elementor-pro' ), + 3 => esc_html__( 'Custom field deleted.', 'elementor-pro' ), + 4 => esc_html__( 'Font updated.', 'elementor-pro' ), + /* translators: %s: Date and time of the revision. */ + 5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Font restored to revision from %s', 'elementor-pro' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => esc_html__( 'Font saved.', 'elementor-pro' ), + 7 => esc_html__( 'Font saved.', 'elementor-pro' ), + 8 => esc_html__( 'Font submitted.', 'elementor-pro' ), + 9 => esc_html__( 'Font updated.', 'elementor-pro' ), + 10 => esc_html__( 'Font draft updated.', 'elementor-pro' ), + ]; + + return $messages; + } + + /** + * Print Font Type metabox + * + * @param $post + * @param $box + */ + public function print_taxonomy_metabox( $post, $box ) { + wp_nonce_field( self::CPT, self::CPT . '_nonce' ); + $name = self::TAXONOMY; + ?> +
    + ID, $name ); + $slug = false; + if ( is_array( $term_obj ) && isset( $term_obj[0] ) ) { + $slug = $term_obj[0]->slug; + } + $options = ''; + foreach ( $this->font_types as $type => $instance ) { + $options .= sprintf( '' . "\n", $type, selected( $slug, $type, false ), $instance->get_name() ); + } + ?> + +
    + can_use_custom_fonts() ) { + $admin_menu_manager->register( static::MENU_SLUG, new Custom_Fonts_Menu_Item() ); + } else { + $admin_menu_manager->register( static::PROMOTION_MENU_SLUG, new Custom_Fonts_Promotion_Menu_Item() ); + } + } + + private function can_use_custom_fonts() { + return ( API::is_license_active() || $this->has_fonts() ); + } + + private function has_fonts() { + if ( null !== $this->has_fonts ) { + return $this->has_fonts; + } + + $existing_fonts = new \WP_Query( [ + 'post_type' => static::CPT, + 'posts_per_page' => 1, + ] ); + + $this->has_fonts = $existing_fonts->post_count > 0; + + return $this->has_fonts; + } + + public function redirect_admin_old_page_to_new() { + if ( ! empty( $_GET['page'] ) && 'elementor_custom_fonts' === $_GET['page'] ) { + wp_safe_redirect( admin_url( static::MENU_SLUG ) ); + die; + } + } + + /** + * Render preview column in font manager admin listing + * + * @param $column + * @param $post_id + */ + public function render_columns( $column, $post_id ) { + if ( 'font_preview' === $column ) { + $font_type = $this->get_font_type_by_post_id( $post_id, true ); + + if ( false === $font_type ) { + return; + } + + $font_type->render_preview_column( $post_id ); + } + + if ( 'font_type' === $column ) { + $font_type = $this->get_font_type_by_post_id( $post_id, true ); + + if ( false === $font_type ) { + return; + } + + $font_type->render_type_column( $post_id ); + } + } + + /** + * Handle editor request to embed/link font CSS per font type + * + * @param array $data + * + * @return array + * @throws \Exception + */ + public function assets_manager_panel_action_data( array $data ) { + $document = Pro_Utils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + if ( empty( $data['type'] ) ) { + throw new \Exception( 'Font type is required.' ); + } + + if ( empty( $data['font'] ) ) { + throw new \Exception( 'Font is required.' ); + } + + if ( 'variable' === $data['type'] ) { + $data['type'] = 'custom'; + } + + $asset = $this->get_font_type_object( $data['type'] ); + + if ( ! $asset ) { + throw new \Exception( 'Font type not found.' ); + } + + try { + return $asset->handle_panel_request( $data ); + + } catch ( \Exception $exception ) { + throw $exception; + } + } + + /** + * Clean up admin Font manager admin listing + */ + public function clean_admin_listing_page() { + global $typenow; + + if ( self::CPT !== $typenow ) { + return; + } + + add_filter( 'months_dropdown_results', '__return_empty_array' ); + add_action( 'manage_' . self::CPT . '_posts_custom_column', [ $this, 'render_columns' ], 10, 2 ); + add_filter( 'display_post_states', [ $this, 'display_post_states' ], 10, 2 ); + add_filter( 'screen_options_show_screen', '__return_false' ); + } + + public function update_enter_title_here( $title, $post ) { + if ( isset( $post->post_type ) && self::CPT === $post->post_type ) { + return esc_html__( 'Enter Font Family', 'elementor-pro' ); + } + + return $title; + } + + public function get_font_variables( $font_variables ) { + $font_manager_fonts = $this->get_fonts(); + + if ( empty( $font_manager_fonts ) ) { + return $font_variables; + } + + foreach ( $font_manager_fonts as $font_family => $font_data ) { + if ( empty( $font_data['variables'] ) ) { + continue; + } + + $font_variables[ $font_family ] = $font_data['variables']; + } + + return $font_variables; + } + + public function get_font_variable_ranges( $font_variable_ranges ) { + $font_manager_fonts = $this->get_fonts(); + + if ( empty( $font_manager_fonts ) ) { + return $font_variable_ranges; + } + + foreach ( $font_manager_fonts as $font_family => $font_data ) { + if ( empty( $font_data['variable_ranges'] ) ) { + continue; + } + + $font_variable_ranges[ $font_family ] = $font_data['variable_ranges']; + } + + return $font_variable_ranges; + } + + public function post_row_actions( $actions, $post ) { + if ( self::CPT !== $post->post_type ) { + return $actions; + } + + unset( $actions['inline hide-if-no-js'] ); + + return $actions; + } + + public function display_post_states( $post_states, $post ) { + $font_type = $this->get_font_type_by_post_id( $post->ID, true ); + + if ( false !== $font_type ) { + $font_type->get_font_variations_count( $post->ID ); + } + + return $post_states; + } + + /** + * Define which columns to display in font manager admin listing + * + * @param $columns + * + * @return array + */ + public function manage_columns( $columns ) { + return [ + 'cb' => '', + 'title' => esc_html__( 'Font Family', 'elementor-pro' ), + 'font_preview' => esc_html__( 'Preview', 'elementor-pro' ), + 'font_type' => esc_html__( 'Type', 'elementor-pro' ), + ]; + } + + public function register_fonts_in_control( $fonts ) { + $custom_fonts = $this->get_font_types(); + if ( empty( $custom_fonts ) ) { + $this->generate_fonts_list(); + $custom_fonts = $this->get_font_types(); + } + + return array_replace( $custom_fonts, $fonts ); + } + + public function register_fonts_groups( $font_groups ) { + $new_groups = []; + + foreach ( $this->get_font_type_object() as $type => $instance ) { + $new_groups[ $type ] = $instance->get_name(); + } + + $new_groups['variable'] = esc_html__( 'Variable Fonts', 'elementor-pro' ); + + return array_replace( $new_groups, $font_groups ); + } + + /** + * Gets a Font type for any given post id + * + * @param $post_id + * @param bool $return_object + * + * @return array|bool|Classes\Font_Base + */ + private function get_font_type_by_post_id( $post_id, $return_object = false ) { + $term_obj = get_the_terms( $post_id, self::TAXONOMY ); + + if ( is_array( $term_obj ) ) { + $type_obj = array_shift( $term_obj ); + + if ( false === $return_object ) { + return $type_obj->slug; + } + + return $this->get_font_type_object( $type_obj->slug ); + } + + return false; + } + + /** + * Get font manager fonts as font family => font type array + * @return array + */ + private function get_font_types() { + static $font_types = false; + + if ( ! $font_types ) { + $font_types = get_option( self::FONTS_NAME_TYPE_OPTION_NAME, [] ); + } + + return $font_types; + } + + /** + * Generates a list of all Font Manager fonts and stores it in the options table + * @return array + */ + private function generate_fonts_list() { + $fonts = new \WP_Query( [ + 'post_type' => self::CPT, + 'posts_per_page' => -1, + ] ); + + $new_fonts = []; + $font_types = []; + + foreach ( $fonts->posts as $font ) { + $font_type = $this->get_font_type_by_post_id( $font->ID, true ); + + if ( false === $font_type ) { + continue; + } + + $font_types = array_replace( $font_types, $font_type->get_font_family_type( $font->ID, $font->post_title ) ); + $new_fonts = array_replace( $new_fonts, $font_type->get_font_data( $font->ID, $font->post_title ) ); + } + + update_option( self::FONTS_NAME_TYPE_OPTION_NAME, $font_types ); + update_option( self::FONTS_OPTION_NAME, $new_fonts ); + + return $new_fonts; + } + + /** + * runs on Elementor font post save and calls the font type handler save meta method + * + * @param int $post_id + * @param \WP_Post $post + * @param bool $update + * + * @return mixed + */ + public function save_post_meta( $post_id, $post, $update ) { + // If this is an autosave, our form has not been submitted, + // so we don't want to do anything. + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return $post_id; + } + + // Check the user's permissions. + if ( ! current_user_can( 'edit_post', $post_id ) ) { + return $post_id; + } + + // Check if our nonce is set. + if ( ! isset( $_POST[ self::CPT . '_nonce' ] ) ) { + return $post_id; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( + Pro_Utils::_unstable_get_super_global_value( $_POST, self::CPT . '_nonce' ), + self::CPT + ) ) { + return $post_id; + } + + // Save font type + // only custom for now + $custom_font = $this->get_font_type_object( 'custom' ); + + wp_set_object_terms( $post_id, $custom_font->get_type(), self::TAXONOMY ); + + // Let Font type handle saving + // Sanitize the whole $_POST array + $custom_font->save_meta( $post_id, Pro_Utils::_unstable_get_super_global_value( [ 'data' => $_POST ], 'data' ) ); + } + + /** + * Helper to clean font list on save/update + */ + public function clear_fonts_list() { + delete_option( self::FONTS_OPTION_NAME ); + delete_option( self::FONTS_NAME_TYPE_OPTION_NAME ); + } + + /** + * Get fonts array form the database or generate a new list if $force is set to true + * + * @param bool $force + * + * @return array|bool|mixed + */ + public function get_fonts() { + static $fonts = false; + + if ( false !== $fonts ) { + return $fonts; + } + + $fonts = $this->generate_fonts_list(); + + $fonts = get_option( self::FONTS_OPTION_NAME, false ); + + return $fonts; + } + + /** + * Enqueue fonts css + * + * @param $post_css + */ + public function enqueue_fonts( $post_css ) { + $used_fonts = $post_css->get_fonts(); + $font_manager_fonts = $this->get_fonts(); + $font_types = $this->get_font_types(); + + foreach ( $used_fonts as $font_family ) { + if ( ! isset( $font_types[ $font_family ] ) || in_array( $font_family, $this->enqueued_fonts ) ) { + continue; + } + + $font_type_name = $font_types[ $font_family ]; + + if ( 'variable' === $font_type_name ) { + $font_type_name = 'custom'; + } + + $font_type = $this->get_font_type_object( $font_type_name ); + if ( ! $font_type ) { + continue; + } + + $font_data = []; + if ( isset( $font_manager_fonts[ $font_family ] ) ) { + $font_data = $font_manager_fonts[ $font_family ]; + } + $font_type->enqueue_font( $font_family, $font_data, $post_css ); + + $this->enqueued_fonts[] = $font_family; + } + } + + public function register_ajax_actions( Ajax $ajax ) { + $ajax->register_ajax_action( 'pro_assets_manager_panel_action_data', [ $this, 'assets_manager_panel_action_data' ] ); + } + + public function add_finder_item( array $categories ) { + $categories['settings']['items']['custom-fonts'] = [ + 'title' => esc_html__( 'Custom Fonts', 'elementor-pro' ), + 'icon' => 'typography', + 'url' => admin_url( static::MENU_SLUG ), + 'keywords' => [ 'custom', 'fonts', 'elementor' ], + ]; + + if ( ! $this->can_use_custom_fonts() ) { + $lock = new Feature_Lock( [ 'type' => 'custom-font' ] ); + + $categories['settings']['items']['custom-fonts']['lock'] = $lock->get_config(); + } + + return $categories; + } + + public function admin_menu_make_open_on_subpage( $parent_file ) { + if ( static::MENU_SLUG === $parent_file ) { + $parent_file = Settings::PAGE_ID; + } + + return $parent_file; + } + + /** + * Register Font Manager action and filter hooks + */ + protected function actions() { + add_action( 'init', [ $this, 'register_post_type_and_tax' ] ); + + if ( is_admin() ) { + add_action( 'init', [ $this, 'redirect_admin_old_page_to_new' ] ); + + add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu_manager ) { + $this->register_admin_menu( $admin_menu_manager ); + } ); + + // TODO: BC - Remove after `Admin_Menu_Manager` will be the standard. + add_action( 'admin_menu', function () { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + $menu_title = _x( 'Custom Fonts', 'Elementor Font', 'elementor-pro' ); + + add_submenu_page( + Settings::PAGE_ID, + $menu_title, + $menu_title, + self::CAPABILITY, + static::MENU_SLUG + ); + }, 50 ); + + add_action( 'admin_head', [ $this, 'clean_admin_listing_page' ] ); + } + + // TODO: Maybe just ignore all of those when the user can't use custom fonts? + add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 ); + add_filter( 'manage_' . self::CPT . '_posts_columns', [ $this, 'manage_columns' ], 100 ); + add_action( 'save_post_' . self::CPT, [ $this, 'save_post_meta' ], 10, 3 ); + add_action( 'save_post_' . self::CPT, [ $this, 'clear_fonts_list' ], 100 ); + + add_filter( 'elementor/fonts/groups', [ $this, 'register_fonts_groups' ] ); + add_filter( 'elementor/fonts/additional_fonts', [ $this, 'register_fonts_in_control' ] ); + add_filter( 'elementor/finder/categories', [ $this, 'add_finder_item' ] ); + add_action( 'elementor/css-file/post/parse', [ $this, 'enqueue_fonts' ] ); + add_action( 'elementor/css-file/global/parse', [ $this, 'enqueue_fonts' ] ); + add_filter( 'post_updated_messages', [ $this, 'post_updated_messages' ] ); + add_filter( 'enter_title_here', [ $this, 'update_enter_title_here' ], 10, 2 ); + + add_filter( 'elementor/typography/font_variables', [ $this, 'get_font_variables' ] ); + add_filter( 'elementor/typography/font_variable_ranges', [ $this, 'get_font_variable_ranges' ] ); + + add_filter( 'parent_file', [ $this, 'admin_menu_make_open_on_subpage' ] ); + + // Ajax. + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + /** + * Elementor fonts manager loaded. + * + * Fires after the fonts manager was fully loaded and instantiated. + * + * @since 2.0.0 + * + * @param Fonts_Manager $this An instance of fonts manager. + */ + do_action( 'elementor_pro/fonts_manager_loaded', $this ); + } + + /** + * Fonts_Manager constructor. + */ + public function __construct() { + $this->actions(); + $this->add_font_type( 'custom', new Fonts\Custom_Fonts() ); + $this->add_font_type( 'typekit', new Fonts\Typekit_Fonts() ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/custom-fonts.php b/modules/assets-manager/asset-types/fonts/custom-fonts.php new file mode 100644 index 00000000..863e8676 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/custom-fonts.php @@ -0,0 +1,664 @@ + 'font/woff|application/font-woff|application/x-font-woff|application/octet-stream', + 'woff2' => 'font/woff2|application/octet-stream|font/x-woff2', + 'ttf' => 'application/x-font-ttf|application/octet-stream|font/ttf', + 'svg' => 'image/svg+xml|application/octet-stream|image/x-svg+xml', + 'eot' => 'application/vnd.ms-fontobject|application/octet-stream|application/x-vnd.ms-fontobject', + ]; + } + + public function add_meta_box() { + add_meta_box( + 'elementor-font-' . $this->get_type() . 'metabox', + __( 'Manage Your Font Files', 'elementor-pro' ), + [ $this, 'render_metabox' ], + Fonts_Manager::CPT, + 'normal', + 'default' + ); + } + + public function render_metabox( $post ) { + wp_enqueue_media(); + + $fields = [ + [ + 'id' => 'font_type', + 'field_type' => 'input', + 'input_type' => 'hidden', + ], + [ + 'id' => 'open_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'repeater-content-top', + ], + ], + [ + 'id' => 'font_weight', + 'field_type' => 'select', + 'label' => esc_html__( 'Weight', 'elementor-pro' ) . ':', + 'extra_attributes' => [ + 'class' => 'font_weight', + ], + 'options' => $this->get_font_weight_options(), + ], + [ + 'id' => 'font_style', + 'field_type' => 'select', + 'label' => esc_html__( 'Style', 'elementor-pro' ) . ':', + 'extra_attributes' => [ + 'class' => 'font_style', + ], + 'options' => $this->get_font_style_options(), + ], + [ + 'id' => 'preview_label', + 'field_type' => 'html', + 'label' => false, + 'raw_html' => sprintf( '
    %s
    ', esc_html__( 'PRO Elements Is Making the Web Beautiful', 'elementor-pro' ) ), + ], + [ + 'id' => 'toolbar', + 'field_type' => 'toolbar', + 'label' => false, + ], + [ + 'id' => 'close_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'open_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'repeater-content-bottom', + ], + ], + [ + 'id' => 'variable_description', + 'field_type' => 'html', + 'label' => false, + 'raw_html' => sprintf( '
    %s %s
    ', + esc_html__( 'Check the boxes to enable Width and Weight, then define the minimum and maximum values for each.', 'elementor-pro' ), + '' . esc_html__( 'Learn More', 'elementor-pro' ) . '.' + ), + ], + [ + 'id' => 'open_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'variable-width-wrap', + ], + ], + [ + 'id' => 'variable_width', + 'field_type' => 'input', + 'input_type' => 'checkbox', + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'value' => 'yes', + ], + [ + 'id' => 'variable_width_min', + 'field_type' => 'input', + 'input_type' => 'number', + 'label' => esc_html__( 'Min Width', 'elementor-pro' ), + ], + [ + 'id' => 'variable_width_max', + 'field_type' => 'input', + 'input_type' => 'number', + 'label' => esc_html__( 'Max Width', 'elementor-pro' ), + ], + [ + 'id' => 'close_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'open_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'variable-weight-wrap', + ], + ], + [ + 'id' => 'variable_weight', + 'field_type' => 'input', + 'input_type' => 'checkbox', + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'value' => 'yes', + ], + [ + 'id' => 'variable_weight_min', + 'field_type' => 'input', + 'input_type' => 'number', + 'label' => esc_html__( 'Min Weight', 'elementor-pro' ), + ], + [ + 'id' => 'variable_weight_max', + 'field_type' => 'input', + 'input_type' => 'number', + 'label' => esc_html__( 'Max Weight', 'elementor-pro' ), + ], + [ + 'id' => 'close_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + ]; + + foreach ( $this->get_file_types() as $type => $mine ) { + $fields[] = [ + 'id' => $type, + 'field_type' => 'file', + 'mine' => str_replace( '|', ',', $mine ), + 'ext' => $type, + /* translators: %s: Font file format. */ + 'label' => sprintf( esc_html__( '%s File', 'elementor-pro' ), strtoupper( $type ) ), + /* translators: %s: Font file format. */ + 'box_title' => sprintf( esc_html__( 'Upload font .%s file', 'elementor-pro' ), $type ), + /* translators: %s: Font file format. */ + 'box_action' => sprintf( esc_html__( 'Select .%s file', 'elementor-pro' ), $type ), + 'preview_anchor' => 'none', + 'description' => $this->get_file_type_description( $type ), + ]; + } + + $fields[] = [ + 'id' => 'close_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ]; + + $font_data = get_post_meta( $post->ID, self::FONT_META_KEY, true ); + + $repeater = [ + 'fields' => $fields, + 'id' => 'font_face', + 'label' => false, + 'add_label' => esc_html__( 'Add Static Font', 'elementor-pro' ), + 'toggle_title' => esc_html__( 'Edit', 'elementor-pro' ), + 'remove_title' => esc_html__( 'Delete', 'elementor-pro' ), + 'field_type' => 'repeater', + 'row_label' => [ + 'default' => 'Settings', + 'selector' => '.font_weight', + ], + 'saved' => $font_data, + ]; + + $add_variable_font_button = [ + 'id' => 'add-variable-font', + 'field_type' => 'input', + 'input_type' => 'button', + 'value' => esc_html__( 'Add Variable Font', 'elementor-pro' ), + 'class' => 'button button-secondary', + ]; + + $this->print_metabox( [ $repeater, $add_variable_font_button ] ); + + // PHPCS - Dedicated for CSS. + printf( '', get_post_meta( $post->ID, self::FONT_FACE_META_KEY, true ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function save_meta( $post_id, $data ) { + if ( ! isset( $data['font_face'] ) || ! is_array( $data['font_face'] ) ) { + return; + } + + // Sanitize a little + $font_face = []; + foreach ( $data['font_face'] as $font_data ) { + $font_face[] = $this->sanitize_text_field_recursive( $font_data ); + } + + // All good save the files array + update_post_meta( $post_id, self::FONT_META_KEY, $font_face ); + + // Save font face + update_post_meta( $post_id, self::FONT_FACE_META_KEY, $this->generate_font_face( $post_id ) ); + } + + public function upload_mimes( $mine_types ) { + if ( current_user_can( Fonts_Manager::CAPABILITY ) && $this->is_elementor_font_upload() ) { + foreach ( $this->get_file_types() as $type => $mine ) { + if ( ! isset( $mine_types[ $type ] ) ) { + $mine_types[ $type ] = $mine; + } + } + } + + return $mine_types; + } + + public function wp_handle_upload_prefilter( $file ) { + if ( ! $this->is_elementor_font_upload() ) { + return $file; + } + + $ext = pathinfo( $file['name'], PATHINFO_EXTENSION ); + + if ( 'svg' !== $ext ) { + return $file; + } + + /** + * @var \Elementor\Core\Files\Assets\Svg\Svg_Handler $svg_handler; + */ + $svg_handler = Plugin::elementor()->assets_manager->get_asset( 'svg-handler' ); + + if ( Files_Upload_Handler::file_sanitizer_can_run() && ! $svg_handler->sanitize_svg( $file['tmp_name'] ) ) { + $file['error'] = esc_html__( 'Invalid SVG Format, file not uploaded for security reasons', 'elementor-pro' ); + } + + return $file; + } + + private function is_elementor_font_upload() { + return isset( $_POST['uploadTypeCaller'] ) && 'elementor-admin-font-upload' === $_POST['uploadTypeCaller']; // phpcs:ignore + } + + /** + * A workaround for upload validation which relies on a PHP extension (fileinfo) with inconsistent reporting behaviour. + * ref: https://core.trac.wordpress.org/ticket/39550 + * ref: https://core.trac.wordpress.org/ticket/40175 + */ + public function filter_fix_wp_check_filetype_and_ext( $data, $file, $filename, $mimes ) { + if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) { + return $data; + } + + $registered_file_types = $this->get_file_types(); + $filetype = wp_check_filetype( $filename, $mimes ); + + if ( ! isset( $registered_file_types[ $filetype['ext'] ] ) ) { + return $data; + } + // Fix incorrect file mime type + $filetype['type'] = explode( '|', $filetype['type'] )[0]; + + return [ + 'ext' => $filetype['ext'], + 'type' => $filetype['type'], + 'proper_filename' => $data['proper_filename'], + ]; + } + + public function generate_font_face( $post_id ) { + $saved = get_post_meta( $post_id, self::FONT_META_KEY, true ); + if ( ! is_array( $saved ) ) { + return false; + } + + $font_family = get_the_title( $post_id ); + $font_face = ''; + + foreach ( $saved as $font_data ) { + $font_face .= $this->get_font_face_from_data( $font_family, $font_data ) . PHP_EOL; + } + + return $font_face; + } + + private function get_font_variables( $post_id ) { + $saved = get_post_meta( $post_id, self::FONT_META_KEY, true ); + if ( ! is_array( $saved ) ) { + return false; + } + + $variables = []; + + foreach ( $saved as $font_data ) { + if ( ! empty( $font_data['variable_weight'] ) ) { + $variables[] = 'weight'; + } + + if ( ! empty( $font_data['variable_width'] ) ) { + $variables[] = 'width'; + } + + break; + } + + return $variables; + } + + private function get_font_variable_ranges( $post_id ) { + $saved = get_post_meta( $post_id, self::FONT_META_KEY, true ); + if ( ! is_array( $saved ) ) { + return false; + } + + $variable_ranges = []; + + foreach ( $saved as $font_data ) { + if ( ! empty( $font_data['variable_weight'] ) ) { + $variable_ranges['weight'] = [ + 'min' => 1, + 'max' => 1000, + ]; + + if ( ! empty( $font_data['variable_weight_min'] ) ) { + $variable_ranges['weight']['min'] = (int) $font_data['variable_weight_min']; + } + + if ( ! empty( $font_data['variable_weight_max'] ) ) { + $variable_ranges['weight']['max'] = (int) $font_data['variable_weight_max']; + } + } + + if ( ! empty( $font_data['variable_width'] ) ) { + $variable_ranges['width'] = [ + 'min' => 0, + 'max' => 150, + ]; + + if ( ! empty( $font_data['variable_width_min'] ) ) { + $variable_ranges['width']['min'] = (int) $font_data['variable_width_min']; + } + + if ( ! empty( $font_data['variable_width_max'] ) ) { + $variable_ranges['width']['max'] = (int) $font_data['variable_width_max']; + } + } + + break; + } + + return $variable_ranges; + } + + private function is_font_variable( $post_id ): bool { + $saved = get_post_meta( $post_id, self::FONT_META_KEY, true ); + if ( ! is_array( $saved ) ) { + return false; + } + + foreach ( $saved as $font_data ) { + return ! empty( $font_data['font_type'] ) && 'variable' === $font_data['font_type']; + } + + return false; + } + + public function get_font_face_from_data( $font_family, $data ) { + $src = []; + foreach ( [ 'eot', 'woff2', 'woff', 'ttf', 'svg' ] as $type ) { + if ( ! isset( $data[ $type ] ) || ! isset( $data[ $type ]['url'] ) || empty( $data[ $type ]['url'] ) ) { + continue; + } + + if ( 'svg' === $type ) { + $data[ $type ]['url'] .= '#' . str_replace( ' ', '', $font_family ); + } + + $src[] = $this->get_font_src_per_type( $type, $data[ $type ]['url'] ); + } + + $font_face = '@font-face {' . PHP_EOL; + $font_face .= "\tfont-family: '" . $font_family . "';" . PHP_EOL; + + if ( empty( $data['font_type'] ) || 'variable' !== $data['font_type'] ) { + $font_face .= "\tfont-style: " . $data['font_style'] . ';' . PHP_EOL; + $font_face .= "\tfont-weight: " . $data['font_weight'] . ';' . PHP_EOL; + } + + $font_face .= "\tfont-display: " . apply_filters( 'elementor_pro/custom_fonts/font_display', 'auto', $font_family, $data ) . ';' . PHP_EOL; + + if ( isset( $data['eot'] ) && isset( $data['eot']['url'] ) && ! empty( $data['eot']['url'] ) ) { + $font_face .= "\tsrc: url('" . esc_attr( $data['eot']['url'] ) . "');" . PHP_EOL; + } + + $font_face .= "\tsrc: " . implode( ',' . PHP_EOL . "\t\t", $src ) . ';' . PHP_EOL . '}'; + + return $font_face; + } + + private function get_font_src_per_type( $type, $url ) { + $src = 'url(\'' . esc_attr( $url ) . '\') '; + switch ( $type ) { + case 'woff': + case 'woff2': + case 'svg': + $src .= 'format(\'' . $type . '\')'; + break; + + case 'ttf': + $src .= 'format(\'truetype\')'; + break; + + case 'eot': + $src = 'url(\'' . esc_attr( $url ) . '?#iefix\') format(\'embedded-opentype\')'; + break; + } + + return $src; + } + + public function get_fonts( $force = false ) { + $fonts = get_option( self::FONTS_OPTION_NAME, false ); + if ( $fonts && ! $force ) { + return $fonts; + } + + $fonts = new \WP_Query( [ + 'post_type' => Fonts_Manager::CPT, + 'posts_per_page' => -1, + ] ); + + $new_fonts = []; + foreach ( $fonts->posts as $font ) { + $new_fonts[ $font->post_title ] = 'custom'; + } + + update_option( self::FONTS_OPTION_NAME, $new_fonts ); + + return $new_fonts; + } + + private function get_font_face_by_font_family( $font_family ) { + global $wpdb; + + $id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = %s LIMIT 1", $font_family, Fonts_Manager::CPT ) ); + + if ( $id ) { + return get_post_meta( $id, self::FONT_FACE_META_KEY, true ); + } + + return ''; + } + + public function render_preview_column( $post_id ) { + $font_face = get_post_meta( $post_id, self::FONT_FACE_META_KEY, true ); + + if ( ! $font_face ) { + return; + } + + // PHPCS - the variable $font_face is CSS. the property $this->font_preview_phrase is safe. + printf( '%s', $font_face, esc_html( get_the_title( $post_id ) ), $this->font_preview_phrase ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function render_type_column( $post_id ) { + echo $this->is_font_variable( $post_id ) ? esc_html__( 'Variable', 'elementor-pro' ) : esc_html__( 'Static', 'elementor-pro' ); + } + + public function get_font_family_type( $post_id, $post_title ) { + $type = $this->get_type(); + + if ( $this->is_font_variable( $post_id ) ) { + $type = 'variable'; + } + + return [ + $post_title => $type, + ]; + } + + public function get_font_data( $post_id, $post_title ) { + $font_data = [ + 'font_face' => $this->generate_font_face( $post_id ), + 'post_id' => $post_id, + ]; + + $variables = $this->get_font_variables( $post_id ); + if ( ! empty( $variables ) ) { + $font_data['variables'] = $variables; + } + + $variable_ranges = $this->get_font_variable_ranges( $post_id ); + if ( ! empty( $variable_ranges ) ) { + $font_data['variable_ranges'] = $variable_ranges; + } + + return [ + $post_title => $font_data, + ]; + } + + public function get_font_variations_count( $post_id ) { + $data = get_post_meta( $post_id, self::FONT_META_KEY, true ); + if ( ! empty( $data ) && count( $data ) > 0 ) { + echo sprintf( '%d', count( $data ) ); + } + } + + /** + * @param string $font_family + * @param array $font_data + * @param Base $post_css + */ + public function enqueue_font( $font_family, $font_data, $post_css ) { + $font_faces = isset( $font_data['font_face'] ) ? $font_data['font_face'] : $this->get_font_face_by_font_family( $font_family ); + // Add a css comment + $custom_css = '/* Start Custom Fonts CSS */' . $font_faces . '/* End Custom Fonts CSS */'; + $post_css->get_stylesheet()->add_raw_css( $custom_css ); + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + $font_family = sanitize_text_field( $data['font'] ); + + $font_face = $this->get_font_face_by_font_family( $font_family ); + + if ( empty( $font_face ) ) { + /* translators: %s: Font family. */ + $error_message = sprintf( esc_html__( 'Font %s was not found.', 'elementor-pro' ), $font_family ); + + throw new \Exception( $error_message ); + } + + return [ + 'font_face' => $font_face, + ]; + } + + private function get_font_style_options() { + return [ + 'normal' => esc_html__( 'Normal', 'elementor-pro' ), + 'italic' => esc_html__( 'Italic', 'elementor-pro' ), + 'oblique' => esc_html__( 'Oblique', 'elementor-pro' ), + ]; + } + + private function get_font_weight_options() { + return [ + 'normal' => esc_html__( 'Normal', 'elementor-pro' ), + 'bold' => esc_html__( 'Bold', 'elementor-pro' ), + '100' => '100', + '200' => '200', + '300' => '300', + '400' => '400', + '500' => '500', + '600' => '600', + '700' => '700', + '800' => '800', + '900' => '900', + ]; + } + + private function get_file_type_description( $file_type ) { + $descriptions = [ + 'eot' => esc_html__( 'Embedded OpenType, Used by IE6-IE9 Browsers', 'elementor-pro' ), + 'woff2' => esc_html__( 'The Web Open Font Format 2, Used by Super Modern Browsers', 'elementor-pro' ), + 'woff' => esc_html__( 'The Web Open Font Format, Used by Modern Browsers', 'elementor-pro' ), + 'ttf' => esc_html__( 'TrueType Fonts, Used for better supporting Safari, Android, iOS', 'elementor-pro' ), + 'svg' => esc_html__( 'SVG fonts allow SVG to be used as glyphs when displaying text, Used by Legacy iOS', 'elementor-pro' ), + ]; + + return isset( $descriptions[ $file_type ] ) ? $descriptions[ $file_type ] : ''; + } + + private function replace_urls( $rows_affected, $from, $to ) { + global $wpdb; + + $rows_affected = $wpdb->query( + "UPDATE {$wpdb->postmeta} " . + $wpdb->prepare( 'SET `meta_value` = REPLACE(`meta_value`, %s, %s) ', $from, $to ) . + 'WHERE `meta_key` = \'' . self::FONT_FACE_META_KEY . '\'' + ); + + return $rows_affected; + } + + protected function actions() { + parent::actions(); + + add_filter( 'elementor/tools/replace-urls', function( $rows_affected, $from, $to ) { + return $this->replace_urls( $rows_affected, $from, $to ); + }, 10, 3 ); + add_filter( 'wp_check_filetype_and_ext', [ $this, 'filter_fix_wp_check_filetype_and_ext' ], 10, 4 ); + add_filter( 'wp_handle_upload_prefilter', [ $this, 'wp_handle_upload_prefilter' ] ); + add_filter( 'upload_mimes', [ $this, 'upload_mimes' ] ); + add_action( 'add_meta_boxes_' . Fonts_Manager::CPT, [ $this, 'add_meta_box' ] ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export-customization/export-runner.php b/modules/assets-manager/asset-types/fonts/import-export-customization/export-runner.php new file mode 100644 index 00000000..0082451a --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export-customization/export-runner.php @@ -0,0 +1,118 @@ +get_fonts( true ); + + $include_custom_fonts = $data['customization']['settings']['customFonts'] ?? true; + + if ( empty( $fonts ) || ! $include_custom_fonts ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $fonts_data = []; + $manifest = []; + + foreach ( $fonts as $font_family => $font_type ) { + $font_data = $this->prepare_font_data( $font_family ); + if ( $font_data ) { + $fonts_data[] = $font_data; + $manifest['custom-fonts'][ $font_family ] = $font_data; + } + } + + return [ + 'files' => [ + 'path' => Import_Export_Customization::FILE_NAME, + 'data' => $fonts_data, + ], + 'manifest' => [ + $manifest, + ], + ]; + } + + private function prepare_font_data( $font_family ) { + $font_query = new \WP_Query( [ + 'post_type' => Fonts_Manager::CPT, + 'post_status' => 'any', + 'posts_per_page' => 1, + 'title' => $font_family, + ] ); + + if ( ! $font_query->have_posts() ) { + return null; + } + + $font_post = $font_query->posts[0]; + + $custom_fonts = new Custom_Fonts(); + + $font_files = get_post_meta( $font_post->ID, Custom_Fonts::FONT_META_KEY, true ); + $font_face = get_post_meta( $font_post->ID, Custom_Fonts::FONT_FACE_META_KEY, true ); + + $font_type = $custom_fonts->get_font_family_type( $font_post->ID, $font_post->post_title ); + $is_font_variable = 'variable' === $font_type; + + $font_variables = []; + $font_variable_ranges = []; + + if ( $is_font_variable ) { + $font_data = $custom_fonts->get_font_data( $font_post->ID, $font_post->post_title ); + $font_variables = $font_data[ $font_post->post_title ]['variables'] ?? null; + $font_variable_ranges = $font_data[ $font_post->post_title ]['variable_ranges'] ?? null; + } + + $attachments = get_attached_media( '', $font_post->ID ); + $attachments_data = []; + + foreach ( $attachments as $attachment ) { + $url = wp_get_attachment_url( $attachment->ID ); + $attachments_data[] = [ + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'url' => $url, + ]; + + do_action( 'elementor/templates/collect_media_url', $url, (array) $attachment ); + } + + return [ + 'ID' => $font_post->ID, + 'post_title' => $font_post->post_title, + 'post_content' => $font_post->post_content, + 'post_status' => $font_post->post_status, + 'font_type' => $font_type, + 'font_files' => $font_files, + 'font_face' => $font_face, + 'font_variables' => $font_variables, + 'font_variable_ranges' => $font_variable_ranges, + 'attachments' => $attachments_data, + ]; + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export-customization/import-export-customization.php b/modules/assets-manager/asset-types/fonts/import-export-customization/import-export-customization.php new file mode 100644 index 00000000..d74d4449 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export-customization/import-export-customization.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/import-kit', function ( Import $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/revert-kit', function ( Revert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export-customization/import-runner.php b/modules/assets-manager/asset-types/fonts/import-export-customization/import-runner.php new file mode 100644 index 00000000..6d268f7f --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export-customization/import-runner.php @@ -0,0 +1,136 @@ +session_id = $data['session_id']; + + $include_custom_fonts = $data['customization']['settings']['customFonts'] ?? true; + + $custom_fonts = new Custom_Fonts(); + $custom_fonts->get_fonts( true ); + + $result = []; + + $custom_fonts_file_path = $data['extracted_directory_path'] . Import_Export_Customization::FILE_NAME; + $fonts_data = ImportExportUtils::read_json_file( $custom_fonts_file_path ); + + if ( empty( $fonts_data ) || ! $include_custom_fonts ) { + return $result; + } + + foreach ( $fonts_data as $font_data ) { + $this->import_font( $font_data ); + } + + if ( empty( $this->imported_fonts ) ) { + return $result; + } + + $result['site-settings']['custom-fonts'] = $this->imported_fonts; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_fonts' => $this->imported_fonts, + ]; + } + + private function import_font( $font_data ) { + $existing_font = $this->get_existing_font( $font_data['post_title'] ); + + if ( $existing_font ) { + return []; + } + + $font_id = $this->create_font( $font_data ); + + if ( $font_id ) { + $this->imported_fonts[] = [ + 'id' => $font_id, + 'title' => $font_data['post_title'], + ]; + } + } + + private function get_existing_font( $font_title ) { + $font_query = new \WP_Query( [ + 'post_type' => Fonts_Manager::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $font_title, + ] ); + + if ( $font_query->have_posts() ) { + $font_post = $font_query->posts[0]; + return [ + 'id' => $font_post->ID, + 'title' => $font_post->post_title, + ]; + } + + return null; + } + + private function create_font( $font_data ) { + $font_id = wp_insert_post( [ + 'post_title' => $font_data['post_title'], + 'post_content' => $font_data['post_content'], + 'post_status' => $font_data['post_status'], + 'post_type' => Fonts_Manager::CPT, + ] ); + + if ( is_wp_error( $font_id ) ) { + return false; + } + + $this->set_session_post_meta( $font_id, $this->session_id ); + + if ( ! empty( $font_data['font_files'] ) ) { + update_post_meta( $font_id, Custom_Fonts::FONT_META_KEY, $font_data['font_files'] ); + } + + if ( ! empty( $font_data['font_face'] ) ) { + update_post_meta( $font_id, Custom_Fonts::FONT_FACE_META_KEY, $font_data['font_face'] ); + } + + if ( ! empty( $font_data['attachments'] ) ) { + $this->import_font_attachments( $font_id, $font_data['attachments'] ); + } + + return $font_id; + } + + private function import_font_attachments( $font_id, $attachments_data ) { + $this->create_attachments_from_urls( $font_id, $attachments_data ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export-customization/revert-runner.php b/modules/assets-manager/asset-types/fonts/import-export-customization/revert-runner.php new file mode 100644 index 00000000..4f3ee0ed --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export-customization/revert-runner.php @@ -0,0 +1,81 @@ +revert_imported_fonts( $metadata ); + + $this->revert_attachments( $data['session_id'] ); + + $custom_fonts = new Custom_Fonts(); + $custom_fonts->get_fonts( true ); + } + + private function revert_imported_fonts( $metadata ) { + $imported_fonts = $metadata['imported_fonts'] ?? []; + + foreach ( $imported_fonts as $font ) { + $this->delete_font_and_attachments( $font['id'] ); + } + } + + private function revert_attachments( $session_id ) { + $attachments_query = new \WP_Query( [ + 'post_type' => 'attachment', + 'post_status' => 'inherit', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => static::META_KEY_ELEMENTOR_IMPORT_SESSION_ID, + 'value' => $session_id, + 'compare' => '=', + ], + ], + ] ); + + if ( ! $attachments_query->have_posts() ) { + return; + } + + foreach ( $attachments_query->posts as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + } + + private function delete_font_and_attachments( $font_id ) { + $attachments = get_attached_media( '', $font_id ); + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + wp_delete_post( $font_id, true ); + } +} + diff --git a/modules/assets-manager/asset-types/fonts/import-export/export-runner.php b/modules/assets-manager/asset-types/fonts/import-export/export-runner.php new file mode 100644 index 00000000..19deea59 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export/export-runner.php @@ -0,0 +1,113 @@ +get_fonts( true ); + + if ( empty( $fonts ) ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $fonts_data = []; + $manifest_data = []; + + foreach ( $fonts as $font_family => $font_type ) { + $font_data = $this->prepare_font_data( $font_family ); + if ( $font_data ) { + $fonts_data[] = $font_data; + $manifest['custom-fonts'][ $font_family ] = $font_data; + } + } + + return [ + 'files' => [ + 'path' => Import_Export::FILE_NAME, + 'data' => $fonts_data, + ], + 'manifest' => [ + $manifest_data, + ], + ]; + } + + private function prepare_font_data( $font_family ) { + $font_query = new \WP_Query( [ + 'post_type' => Fonts_Manager::CPT, + 'post_status' => 'any', + 'posts_per_page' => 1, + 'title' => $font_family, + ] ); + + if ( ! $font_query->have_posts() ) { + return null; + } + + $font_post = $font_query->posts[0]; + + $custom_fonts = new Custom_Fonts(); + + $font_files = get_post_meta( $font_post->ID, Custom_Fonts::FONT_META_KEY, true ); + $font_face = get_post_meta( $font_post->ID, Custom_Fonts::FONT_FACE_META_KEY, true ); + + $font_type = $custom_fonts->get_font_family_type( $font_post->ID, $font_post->post_title ); + $is_font_variable = 'variable' === $font_type; + + $font_variables = []; + $font_variable_ranges = []; + + if ( $is_font_variable ) { + $font_data = $custom_fonts->get_font_data( $font_post->ID, $font_post->post_title ); + $font_variables = $font_data[ $font_post->post_title ]['variables'] ?? null; + $font_variable_ranges = $font_data[ $font_post->post_title ]['variable_ranges'] ?? null; + } + + $attachments = get_attached_media( '', $font_post->ID ); + $attachments_data = []; + + foreach ( $attachments as $attachment ) { + $attachments_data[] = [ + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'url' => wp_get_attachment_url( $attachment->ID ), + ]; + } + + return [ + 'ID' => $font_post->ID, + 'post_title' => $font_post->post_title, + 'post_content' => $font_post->post_content, + 'post_status' => $font_post->post_status, + 'font_type' => $font_type, + 'font_files' => $font_files, + 'font_face' => $font_face, + 'font_variables' => $font_variables, + 'font_variable_ranges' => $font_variable_ranges, + 'attachments' => $attachments_data, + ]; + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export/import-export.php b/modules/assets-manager/asset-types/fonts/import-export/import-export.php new file mode 100644 index 00000000..2d8929d7 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export/import-export.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export/import-kit', function ( Import $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export/revert-kit', function ( Revert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export/import-runner.php b/modules/assets-manager/asset-types/fonts/import-export/import-runner.php new file mode 100644 index 00000000..45d29988 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export/import-runner.php @@ -0,0 +1,134 @@ +session_id = $data['session_id']; + + $custom_fonts = new Custom_Fonts(); + $custom_fonts->get_fonts( true ); + + $result = []; + + $custom_fonts_file_path = $data['extracted_directory_path'] . Import_Export::FILE_NAME; + $fonts_data = ImportExportUtils::read_json_file( $custom_fonts_file_path ); + + if ( empty( $fonts_data ) ) { + return $result; + } + + foreach ( $fonts_data as $font_data ) { + $this->import_font( $font_data ); + } + + if ( empty( $this->imported_fonts ) ) { + return $result; + } + + $result['site-settings']['custom-fonts'] = $this->imported_fonts; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_fonts' => $this->imported_fonts, + ]; + } + + private function import_font( $font_data ) { + $existing_font = $this->get_existing_font( $font_data['post_title'] ); + + if ( $existing_font ) { + return []; + } + + $font_id = $this->create_font( $font_data ); + + if ( $font_id ) { + $this->imported_fonts[] = [ + 'id' => $font_id, + 'title' => $font_data['post_title'], + ]; + } + } + + private function get_existing_font( $font_title ) { + $font_query = new \WP_Query( [ + 'post_type' => Fonts_Manager::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $font_title, + ] ); + + if ( $font_query->have_posts() ) { + $font_post = $font_query->posts[0]; + return [ + 'id' => $font_post->ID, + 'title' => $font_post->post_title, + ]; + } + + return null; + } + + private function create_font( $font_data ) { + $font_id = wp_insert_post( [ + 'post_title' => $font_data['post_title'], + 'post_content' => $font_data['post_content'], + 'post_status' => $font_data['post_status'], + 'post_type' => Fonts_Manager::CPT, + ] ); + + if ( is_wp_error( $font_id ) ) { + return false; + } + + $this->set_session_post_meta( $font_id, $this->session_id ); + + if ( ! empty( $font_data['font_files'] ) ) { + update_post_meta( $font_id, Custom_Fonts::FONT_META_KEY, $font_data['font_files'] ); + } + + if ( ! empty( $font_data['font_face'] ) ) { + update_post_meta( $font_id, Custom_Fonts::FONT_FACE_META_KEY, $font_data['font_face'] ); + } + + if ( ! empty( $font_data['attachments'] ) ) { + $this->import_font_attachments( $font_id, $font_data['attachments'] ); + } + + return $font_id; + } + + private function import_font_attachments( $font_id, $attachments_data ) { + $this->create_attachments_from_urls( $font_id, $attachments_data ); + } +} diff --git a/modules/assets-manager/asset-types/fonts/import-export/revert-runner.php b/modules/assets-manager/asset-types/fonts/import-export/revert-runner.php new file mode 100644 index 00000000..892f944e --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/import-export/revert-runner.php @@ -0,0 +1,81 @@ +revert_imported_fonts( $metadata ); + + $this->revert_attachments( $data['session_id'] ); + + $custom_fonts = new Custom_Fonts(); + $custom_fonts->get_fonts( true ); + } + + private function revert_imported_fonts( $metadata ) { + $imported_fonts = $metadata['imported_fonts'] ?? []; + + foreach ( $imported_fonts as $font ) { + $this->delete_font_and_attachments( $font['id'] ); + } + } + + private function revert_attachments( $session_id ) { + $attachments_query = new \WP_Query( [ + 'post_type' => 'attachment', + 'post_status' => 'inherit', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => static::META_KEY_ELEMENTOR_IMPORT_SESSION_ID, + 'value' => $session_id, + 'compare' => '=', + ], + ], + ] ); + + if ( ! $attachments_query->have_posts() ) { + return; + } + + foreach ( $attachments_query->posts as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + } + + private function delete_font_and_attachments( $font_id ) { + $attachments = get_attached_media( '', $font_id ); + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + wp_delete_post( $font_id, true ); + } +} + diff --git a/modules/assets-manager/asset-types/fonts/typekit-fonts.php b/modules/assets-manager/asset-types/fonts/typekit-fonts.php new file mode 100644 index 00000000..4b2d09f0 --- /dev/null +++ b/modules/assets-manager/asset-types/fonts/typekit-fonts.php @@ -0,0 +1,262 @@ +get_typekit_kit_id(); + if ( ! $kit_id ) { + return false; + } + + $response = wp_remote_get( $this->api_base . '/' . $kit_id . '/published' ); + + // Response is a WP_Error object + if ( is_wp_error( $response ) ) { + return false; + } + + // Response code is not success + $response_code = (int) wp_remote_retrieve_response_code( $response ); + $response_body = json_decode( wp_remote_retrieve_body( $response ) ); + if ( 200 !== $response_code ) { + switch ( $response_code ) { + case 404: + $this->error = esc_html__( 'Project not found.', 'elementor-pro' ); + break; + default: + $this->error = $response_code; + if ( isset( $response_body->errors ) ) { + $this->error .= ': ' . implode( ', ', $response_body->errors ); + } + break; + } + + return false; + } + + if ( ! $response_body ) { + $this->error = esc_html__( 'No project data was returned.', 'elementor-pro' ); + + return false; + } + + /* + * Expected Json response example + * { + * "kit": { + * "id": "nmm7qvq", + * "families": [ + * { + * "id": "hmqz", + * "name": "Adobe Caslon Pro", + * "slug": "adobe-caslon-pro", + * "css_names": [ + * "adobe-caslon-pro" + * ], + * "css_stack": "\"adobe-caslon-pro\",serif", + * "variations": [ "n6","i6","i7" ] + * } + * ] + * } + * } + */ + if ( ! is_object( $response_body ) || ! isset( $response_body->kit ) || ! isset( $response_body->kit->families ) || ! is_array( $response_body->kit->families ) ) { + return false; + } + + $families = []; + foreach ( $response_body->kit->families as $font_family ) { + $font_css = isset( $font_family->css_names[0] ) ? $font_family->css_names[0] : $font_family->slug; + $families[ $font_css ] = $this->get_type(); + } + update_option( self::TYPEKIT_FONTS_OPTION_NAME, $families ); + + return $families; + } + + private function get_kit_fonts() { + $typekit_fonts = $this->get_typekit_fonts(); + if ( ! $typekit_fonts ) { + $typekit_fonts = $this->fetch_typekit_data(); + } + + return $typekit_fonts; + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + $font_family = sanitize_text_field( $data['font'] ); + + $typekit_fonts = $this->get_kit_fonts(); + + if ( ! $typekit_fonts || ! is_array( $typekit_fonts ) ) { + throw new \Exception( 'Error with TypeKit fonts.' ); + } + + if ( ! in_array( $font_family, array_keys( $typekit_fonts ) ) ) { + throw new \Exception( 'Font missing in Project.' ); + } + + $kit_id = $this->get_typekit_kit_id(); + + return [ 'font_url' => sprintf( self::TYPEKIT_FONTS_LINK, $kit_id ) ]; + } + + public function sanitize_kit_id_settings( $input ) { + if ( empty( $input ) ) { + delete_option( self::TYPEKIT_FONTS_OPTION_NAME ); + } + + return $input; + } + + public function register_admin_fields( Settings $settings ) { + $fonts = $this->get_typekit_fonts(); + $button_label = esc_html__( 'Get Project ID', 'elementor-pro' ); + $found_label = '{{count}} ' . esc_html__( 'Fonts Families Found in project. Please note that typekit takes a few minutes to sync once you publish or update a project.', 'elementor-pro' ); + if ( $fonts && is_array( $fonts ) ) { + $button_label = esc_html__( 'Sync Project', 'elementor-pro' ); + } + $settings->add_section( Settings::TAB_INTEGRATIONS, 'typekit', [ + 'callback' => function() { + echo '

    ' . esc_html__( 'Adobe Fonts (TypeKit)', 'elementor-pro' ) . '

    '; + echo esc_html__( 'TypeKit partners with the world’s leading type foundries to bring thousands of beautiful fonts to designers every day.', 'elementor-pro' ); + }, + 'fields' => [ + self::TYPEKIT_KIT_ID_OPTION_NAME => [ + 'label' => esc_html__( 'Project ID', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Enter Your %1$sTypeKit Project ID%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + 'setting_args' => [ + 'sanitize_callback' => [ $this, 'sanitize_kit_id_settings' ], + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '

    ', + esc_html( $found_label ), + self::TYPEKIT_KIT_ID_OPTION_NAME . '_fetch', + wp_create_nonce( self::TYPEKIT_KIT_ID_OPTION_NAME ), + $button_label + ), + ], + ], + ], + ] ); + } + + public function register_fonts_in_control( $fonts ) { + $typekit_fonts = $this->get_kit_fonts(); + if ( $typekit_fonts ) { + return array_merge( $typekit_fonts, $fonts ); + } + + return $fonts; + } + + public function print_font_link( $font ) { + if ( $this->kit_enqueued ) { + return; + } + if ( $this->is_font_in_kit( $font ) ) { + $kit_url = sprintf( self::TYPEKIT_FONTS_LINK, $this->get_typekit_kit_id() ); + echo ''; + $this->kit_enqueued = true; + } + } + + private function is_font_in_kit( $font ) { + $kit_fonts = $this->get_kit_fonts(); + if ( ! $kit_fonts || ! is_array( $kit_fonts ) ) { + return false; + } + + return in_array( $font, array_keys( $kit_fonts ) ); + } + + public function integrations_admin_ajax_handler() { + check_ajax_referer( self::TYPEKIT_KIT_ID_OPTION_NAME, '_nonce' ); + + if ( ! current_user_can( Fonts_Manager::CAPABILITY ) ) { + wp_send_json_error( 'Permission denied' ); + } + + $kit_id = Utils::_unstable_get_super_global_value( $_POST, 'kit_id' ); + + if ( ! $kit_id ) { + wp_send_json_error(); + } + $fonts = []; + try { + update_option( 'elementor_' . self::TYPEKIT_KIT_ID_OPTION_NAME, sanitize_text_field( $kit_id ) ); + $fonts = $this->fetch_typekit_data(); + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success( [ + 'fonts' => $fonts, + 'count' => count( $fonts ), + ] ); + } + + protected function actions() { + parent::actions(); + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 100 ); + } + add_filter( 'elementor/fonts/additional_fonts', [ $this, 'register_fonts_in_control' ] ); + add_action( 'elementor/fonts/print_font_links/' . $this->get_type(), [ $this, 'print_font_link' ] ); + add_action( 'wp_ajax_elementor_pro_admin_fetch_fonts', [ $this, 'integrations_admin_ajax_handler' ] ); + } +} diff --git a/modules/assets-manager/asset-types/icons-manager.php b/modules/assets-manager/asset-types/icons-manager.php new file mode 100644 index 00000000..0afec5df --- /dev/null +++ b/modules/assets-manager/asset-types/icons-manager.php @@ -0,0 +1,255 @@ +icon_types; + } + + if ( isset( $this->icon_types[ $type ] ) ) { + return $this->icon_types[ $type ]; + } + + return false; + } + + /** + * Add a font type to the font manager + * + * @param string $icon_type + * @param Classes\Assets_Base $instance + */ + public function add_icon_type( $icon_type, $instance ) { + $this->icon_types[ $icon_type ] = $instance; + } + + /** + * Register elementor icon set custom post type + */ + public function register_post_type() { + $labels = [ + 'name' => _x( 'Custom Icons', 'CPT Name', 'elementor-pro' ), + 'singular_name' => _x( 'Icon Set', 'CPT Singular Name', 'elementor-pro' ), + 'add_new' => esc_html__( 'Add New', 'elementor-pro' ), + 'add_new_item' => esc_html__( 'Add New Icon Set', 'elementor-pro' ), + 'edit_item' => esc_html__( 'Edit Icon Set', 'elementor-pro' ), + 'new_item' => esc_html__( 'New Icon Set', 'elementor-pro' ), + 'all_items' => esc_html__( 'All Icons', 'elementor-pro' ), + 'view_item' => esc_html__( 'View Icon', 'elementor-pro' ), + 'search_items' => esc_html__( 'Search Icon Set', 'elementor-pro' ), + 'not_found' => esc_html__( 'No icons found', 'elementor-pro' ), + 'not_found_in_trash' => esc_html__( 'No icons found in trash', 'elementor-pro' ), + 'parent_item_colon' => '', + 'menu_name' => _x( 'Custom Icons', 'CPT Menu Name', 'elementor-pro' ), + ]; + + $args = [ + 'labels' => $labels, + 'public' => false, + 'rewrite' => false, + 'show_ui' => true, + 'show_in_menu' => false, + 'show_in_nav_menus' => false, + 'exclude_from_search' => true, + 'capability_type' => 'post', + 'hierarchical' => false, + 'supports' => [ 'title' ], + ]; + + $this->post_type_object = register_post_type( self::CPT, $args ); + } + + public function post_updated_messages( $messages ) { + $messages[ self::CPT ] = [ + 0 => '', // Unused. Messages start at index 1. + 1 => esc_html__( 'Icon Set updated.', 'elementor-pro' ), + 2 => esc_html__( 'Custom field updated.', 'elementor-pro' ), + 3 => esc_html__( 'Custom field deleted.', 'elementor-pro' ), + 4 => esc_html__( 'Icon Set updated.', 'elementor-pro' ), + /* translators: %s: Date and time of the revision. */ + 5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Icon Set restored to revision from %s', 'elementor-pro' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => esc_html__( 'Icon Set saved.', 'elementor-pro' ), + 7 => esc_html__( 'Icon Set saved.', 'elementor-pro' ), + 8 => esc_html__( 'Icon Set submitted.', 'elementor-pro' ), + 9 => esc_html__( 'Icon Set updated.', 'elementor-pro' ), + 10 => esc_html__( 'Icon Set draft updated.', 'elementor-pro' ), + ]; + + return $messages; + } + + /** + * Add Font manager link to admin menu + */ + private function register_admin_menu( Admin_Menu_Manager $admin_menu_manager ) { + if ( $this->can_use_custom_icons() ) { + $admin_menu_manager->register( static::MENU_SLUG, new Custom_Icons_Menu_Item() ); + } else { + $admin_menu_manager->register( static::PROMOTION_MENU_SLUG, new Custom_Icons_Promotion_Menu_Item() ); + } + } + + private function can_use_custom_icons() { + return ( API::is_license_active() || $this->has_icons() ); + } + + private function has_icons() { + if ( null !== $this->has_icons ) { + return $this->has_icons; + } + + $existing_icons = new \WP_Query( [ + 'post_type' => static::CPT, + 'posts_per_page' => 1, + ] ); + + $this->has_icons = $existing_icons->post_count > 0; + + return $this->has_icons; + } + + public function redirect_admin_old_page_to_new() { + if ( ! empty( $_GET['page'] ) && 'elementor_custom_icons' === $_GET['page'] ) { + wp_safe_redirect( admin_url( static::MENU_SLUG ) ); + die; + } + } + + /** + * Clean up admin Font manager admin listing + */ + public function clean_admin_listing_page() { + global $typenow; + + if ( self::CPT !== $typenow ) { + return; + } + + add_filter( 'months_dropdown_results', '__return_empty_array' ); + add_filter( 'screen_options_show_screen', '__return_false' ); + } + + public function post_row_actions( $actions, $post ) { + if ( self::CPT !== $post->post_type ) { + return $actions; + } + + unset( $actions['inline hide-if-no-js'] ); + + return $actions; + } + + public function add_finder_item( array $categories ) { + $categories['settings']['items']['custom-icons'] = [ + 'title' => esc_html__( 'Custom Icons', 'elementor-pro' ), + 'icon' => 'favorite', + 'url' => admin_url( static::MENU_SLUG ), + 'keywords' => [ 'custom', 'icons', 'elementor' ], + ]; + + if ( ! $this->can_use_custom_icons() ) { + $lock = new Feature_Lock( [ 'type' => 'custom-icon' ] ); + + $categories['settings']['items']['custom-icons']['lock'] = $lock->get_config(); + } + + return $categories; + } + + /** + * Register Font Manager action and filter hooks + */ + protected function actions() { + add_action( 'init', [ $this, 'register_post_type' ] ); + + if ( is_admin() ) { + add_action( 'init', [ $this, 'redirect_admin_old_page_to_new' ] ); + + add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu_manager ) { + $this->register_admin_menu( $admin_menu_manager ); + } ); + + // TODO: BC - Remove after `Admin_Menu_Manager` will be the standard. + add_action( 'admin_menu', function () { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + $menu_title = _x( 'Custom Icons', 'PRO Elements Font', 'elementor-pro' ); + + add_submenu_page( + Settings::PAGE_ID, + $menu_title, + $menu_title, + self::CAPABILITY, + static::MENU_SLUG + ); + }, 50 ); + + add_action( 'admin_head', [ $this, 'clean_admin_listing_page' ] ); + } + + // TODO: Maybe just ignore all of those when the user can't use custom icons? + add_filter( 'post_updated_messages', [ $this, 'post_updated_messages' ] ); + add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 ); + + add_filter( 'elementor/finder/categories', [ $this, 'add_finder_item' ] ); + + /** + * Elementor icons manager loaded. + * + * Fires after the icons manager was fully loaded and instantiated. + * + * @since 2.0.0 + * + * @param Fonts_Manager $this An instance of icons manager. + */ + do_action( 'elementor_pro/icons_manager_loaded', $this ); + } + + /** + * Fonts_Manager constructor. + */ + public function __construct() { + $this->actions(); + $this->add_icon_type( 'custom', new Icons\Custom_Icons() ); + $this->add_icon_type( 'font-awesome-pro', new Icons\Font_Awesome_Pro() ); + } +} diff --git a/modules/assets-manager/asset-types/icons/custom-icons.php b/modules/assets-manager/asset-types/icons/custom-icons.php new file mode 100644 index 00000000..bb4977b2 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/custom-icons.php @@ -0,0 +1,503 @@ +ID ); + + $fields = [ + [ + 'id' => 'open_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-icons-metabox', + ], + ], + [ + 'id' => 'zip_upload', + 'field_type' => 'dropzone', + 'accept' => 'zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed', + 'label' => false, + 'sub-label' => esc_html__( 'Your Fontello, IcoMoon or Fontastic .zip file', 'elementor-pro' ), + ], + [ + 'id' => 'close_div', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => self::META_KEY, + 'name' => self::META_KEY, + 'field_type' => 'input', + 'input_type' => 'hidden', + 'label' => false, + 'value' => $save_data, + 'saved' => $save_data, + ], + [ + 'id' => Icons_Manager::CPT . '_nonce', + 'name' => Icons_Manager::CPT . '_nonce', + 'field_type' => 'input', + 'input_type' => 'hidden', + 'label' => false, + 'value' => wp_create_nonce( Icons_Manager::CPT ), + ], + ]; + + foreach ( $fields as $field ) { + $field['saved'] = isset( $field['saved'] ) ? $field['saved'] : ''; + } + + $this->print_metabox( $fields ); + } + + public function save_post_meta( $post_id, $post, $update ) { + // If this is an autosave, our form has not been submitted, + // so we don't want to do anything. + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return $post_id; + } + + // Check the user's permissions. + if ( ! current_user_can( 'edit_post', $post_id ) ) { + return $post_id; + } + + // Check if our nonce is set. + if ( ! isset( $_POST[ Icons_Manager::CPT . '_nonce' ] ) ) { + return $post_id; + } + + // Verify that the nonce is valid. + if ( ! wp_verify_nonce( + Utils::_unstable_get_super_global_value( $_POST, Icons_Manager::CPT . '_nonce' ), + Icons_Manager::CPT + ) ) { + return $post_id; + } + + if ( ! isset( $_POST[ self::META_KEY ] ) ) { + return delete_post_meta( $post_id, self::META_KEY ); + } + + // PHPCS - It will be sanitized in the next line. + $json = json_decode( stripslashes_deep( $_POST[ self::META_KEY ] ), true ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + foreach ( $json as $property => $value ) { + $json[ $property ] = $this->sanitize_text_field_recursive( $value ); + } + + // All good save the files array + update_post_meta( $post_id, self::META_KEY, json_encode( $json ) ); + + // Force refresh of list in Options Table + self::clear_icon_list_option(); + } + + public static function get_supported_icon_sets() { + $icon_sets = [ + 'fontastic' => __NAMESPACE__ . '\IconSets\Fontastic', + 'fontello' => __NAMESPACE__ . '\IconSets\Fontello', + 'icomoon' => __NAMESPACE__ . '\IconSets\Icomoon', + ]; + + $additional_icon_sets = []; + + /** + * Additional icon sets. + * + * Filters the icon types supported by Elementor Pro. + * + * By default Elementor Pro supports 'fontastic', 'fontello' and 'icomoon'. + * This hook allows developers to add additional icon sets. + * + * @param array $additional_icon_sets Additional icon sets. + */ + $additional_icon_sets = apply_filters( 'elementor_pro/icons_manager/custom_icons/additional_supported_types', $additional_icon_sets ); + + return array_merge( $additional_icon_sets, $icon_sets ); + } + + private function get_active_icon_sets() { + $icons = new \WP_Query( [ + 'post_type' => Icons_Manager::CPT, + 'posts_per_page' => -1, + ] ); + $custom_icon_sets = []; + foreach ( $icons->posts as $icon_set ) { + $set_config = json_decode( self::get_icon_set_config( $icon_set->ID ), true ); + $set_config['custom_icon_post_id'] = $icon_set->ID; + $set_config['label'] = $icon_set->post_title; + $custom_icon_sets[ $set_config['name'] ] = $set_config; + } + return $custom_icon_sets; + } + + /** + * get_wp_filesystem + * @return \WP_Filesystem_Base + */ + public static function get_wp_filesystem() { + global $wp_filesystem; + if ( empty( $wp_filesystem ) ) { + require_once ABSPATH . '/wp-admin/includes/file.php'; + WP_Filesystem(); + } + return $wp_filesystem; + } + + private function upload() { + $file = Utils::_unstable_get_super_global_value( $_FILES, 'zip_upload' ); + $filename = $file['name']; + $ext = pathinfo( $filename, PATHINFO_EXTENSION ); + if ( 'zip' !== $ext ) { + unlink( $filename ); + return new \WP_Error( 'unsupported_file', esc_html__( 'Only zip files are allowed', 'elementor-pro' ) ); + } + if ( ! function_exists( 'wp_handle_upload' ) ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + } + // Handler upload archive file. + $upload_result = wp_handle_upload( $file, [ 'test_form' => false ] ); + if ( isset( $upload_result['error'] ) ) { + unlink( $filename ); + return new \WP_Error( 'upload_error', $upload_result['error'] ); + } + return $upload_result['file']; + } + + private function extract_zip( $file, $to ) { + // TODO: Move to core as a util. + $valid_field_types = [ + 'css', + 'eot', + 'html', + 'json', + 'otf', + 'svg', + 'ttf', + 'txt', + 'woff', + 'woff2', + ]; + + $zip = new \ZipArchive(); + + $zip->open( $file ); + + $valid_entries = []; + + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + for ( $i = 0; $i < $zip->numFiles; $i++ ) { + $zipped_file_name = $zip->getNameIndex( $i ); + $dirname = pathinfo( $zipped_file_name, PATHINFO_DIRNAME ); + + // Skip the OS X-created __MACOSX directory. + if ( '__MACOSX/' === substr( $dirname, 0, 9 ) ) { + continue; + } + + $zipped_extension = pathinfo( $zipped_file_name, PATHINFO_EXTENSION ); + // Skip files with transversal paths. + if ( strpos( $zipped_file_name, '..' ) !== false ) { + continue; + } + + if ( in_array( $zipped_extension, $valid_field_types, true ) ) { + $valid_entries[] = $zipped_file_name; + } + } + + $unzip_result = false; + + if ( ! empty( $valid_entries ) ) { + $unzip_result = $zip->extractTo( $to, $valid_entries ); + } + + if ( ! $unzip_result ) { + $unzip_result = new \WP_Error( 'error', esc_html__( 'Could not unzip or empty archive.', 'elementor-pro' ) ); + } + + @unlink( $file ); + + return $unzip_result; // TRUE | WP_Error instance. + } + + private function upload_and_extract_zip() { + $zip_file = $this->upload(); + if ( is_wp_error( $zip_file ) ) { + return $zip_file; + } + $filesystem = self::get_wp_filesystem(); + $extract_to = trailingslashit( get_temp_dir() . pathinfo( $zip_file, PATHINFO_FILENAME ) ); + + $unzipped = $this->extract_zip( $zip_file, $extract_to ); + if ( is_wp_error( $unzipped ) ) { + return $unzipped; + } + + // Find the right folder. + $source_files = array_keys( $filesystem->dirlist( $extract_to ) ); + if ( count( $source_files ) === 0 ) { + return new \WP_Error( 'incompatible_archive', esc_html__( 'Incompatible archive', 'elementor-pro' ) ); + } + + if ( 1 === count( $source_files ) && $filesystem->is_dir( $extract_to . $source_files[0] ) ) { + $directory = $extract_to . trailingslashit( $source_files[0] ); + } else { + $directory = $extract_to; + } + return [ + 'directory' => $directory, + 'extracted_to' => $extract_to, + ]; + } + + public function custom_icons_upload_handler( $data ) { + if ( ! current_user_can( Icons_Manager::CAPABILITY ) ) { + return new \WP_Error( Exceptions::FORBIDDEN, 'Access denied.' ); + } + + $this->current_post_id = $data['post_id']; + $results = $this->upload_and_extract_zip(); + if ( is_wp_error( $results ) ) { + return $results; + } + $supported_icon_sets = self::get_supported_icon_sets(); + foreach ( $supported_icon_sets as $key => $handler ) { + /** + * @var IconSets\Icon_Set_Base $icon_set_handler + */ + $icon_set_handler = new $handler( $results['directory'] ); + + if ( ! $icon_set_handler ) { + continue; + } + if ( ! $icon_set_handler->is_valid() ) { + continue; + } + $icon_set_handler->handle_new_icon_set(); + $icon_set_handler->move_files( $this->current_post_id ); + $config = $icon_set_handler->build_config(); + + // Notify about duplicate prefix + if ( self::icon_set_prefix_exists( $config['prefix'] ) ) { + $config['duplicate_prefix'] = true; + } + return [ + 'config' => $config, + ]; + } + return new \WP_Error( 'unsupported_zip_format', esc_html__( 'The zip file provided is not supported!', 'elementor-pro' ) ); + } + + public function handle_delete_icon_set( $post_id ) { + if ( Icons_Manager::CPT !== get_post_type( $post_id ) ) { + return; + } + + // remove all assets related to this icon set + $attachments = get_attached_media( '', $post_id ); + + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, 'true' ); + } + + // remove icon set assets directory + $icon_set_dir = get_post_meta( $post_id, '_elementor_icon_set_path', true ); + if ( ! empty( $icon_set_dir ) && is_dir( $icon_set_dir ) ) { + $this::get_wp_filesystem()->rmdir( $icon_set_dir, true ); + } + + // Force refresh of list in Options Table + self::clear_icon_list_option(); + } + + public static function clear_icon_list_option() { + delete_option( self::OPTION_NAME ); + } + + public function display_post_states( $post_states, $post ) { + if ( 'publish' !== $post->post_status || Icons_Manager::CPT !== $post->post_type ) { + return $post_states; + } + + $data = json_decode( self::get_icon_set_config( $post->ID ) ); + if ( ! empty( $data->count ) ) { + echo sprintf( '%d', esc_html( $data->count ) ); + } + + return $post_states; + } + + /** + * Render preview column in font manager admin listing + * + * @param $column + * @param $post_id + */ + public function render_columns( $column, $post_id ) { + if ( 'icons_prefix' === $column ) { + $data = json_decode( self::get_icon_set_config( $post_id ) ); + if ( ! empty( $data->prefix ) ) { + echo '
    ' . esc_html( '.' . $data->prefix ) . '
    '; + } + } + } + + /** + * Define which columns to display in font manager admin listing + * + * @param $columns + * + * @return array + */ + public function manage_columns( $columns ) { + return [ + 'cb' => '', + 'title' => esc_html__( 'Icon Set', 'elementor-pro' ), + 'icons_prefix' => esc_html__( 'CSS Prefix', 'elementor-pro' ), + ]; + } + + public function update_enter_title_here( $title, $post ) { + if ( isset( $post->post_type ) && Icons_Manager::CPT === $post->post_type ) { + return esc_html__( 'Enter Icon Set Name', 'elementor-pro' ); + } + + return $title; + } + + public function register_ajax_actions( Ajax $ajax ) { + $ajax->register_ajax_action( 'pro_assets_manager_custom_icon_upload', [ $this, 'custom_icons_upload_handler' ] ); + } + + public function register_icon_libraries_control( $additional_sets ) { + return array_replace( $additional_sets, self::get_custom_icons_config() ); + } + + public function add_custom_icon_templates( $current_screen ) { + if ( 'elementor_icons' !== $current_screen->id || 'post' !== $current_screen->base ) { + return; + } + Plugin::elementor()->common->add_template( __DIR__ . '/templates.php' ); + } + + public function add_custom_icons_url( $config ) { + $config['customIconsURL'] = admin_url( 'edit.php?post_type=' . Icons_Manager::CPT ); + return $config; + } + + public static function get_custom_icons_config() { + $config = get_option( self::OPTION_NAME, false ); + if ( false === $config ) { + $icons = new \WP_Query( [ + 'post_type' => Icons_Manager::CPT, + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + $config = []; + foreach ( $icons->posts as $icon_set ) { + $set_config = json_decode( self::get_icon_set_config( $icon_set->ID ), true ); + $set_config['custom_icon_post_id'] = $icon_set->ID; + $set_config['label'] = $icon_set->post_title; + if ( isset( $set_config['fetchJson'] ) ) { + unset( $set_config['icons'] ); + } + $config[ $set_config['name'] ] = $set_config; + } + update_option( self::OPTION_NAME, $config ); + } + return $config; + } + + public static function icon_set_prefix_exists( $prefix ) { + $config = self::get_custom_icons_config(); + if ( empty( $config ) ) { + return false; + } + foreach ( $config as $icon_set_name => $icon_config ) { + if ( $prefix === $icon_config['prefix'] ) { + return true; + } + } + return false; + } + + public function transition_post_status( $new_status, $old_status, $post ) { + if ( Icons_Manager::CPT !== $post->post_type ) { + return; + } + + if ( 'publish' === $old_status && 'publish' !== $new_status ) { + $this->clear_icon_list_option(); + } + } + + protected function actions() { + + parent::actions(); + if ( is_admin() ) { + add_action( 'add_meta_boxes_' . Icons_Manager::CPT, [ $this, 'add_meta_box' ] ); + add_action( 'save_post_' . Icons_Manager::CPT, [ $this, 'save_post_meta' ], 10, 3 ); + add_filter( 'display_post_states', [ $this, 'display_post_states' ], 10, 2 ); + add_action( 'manage_' . Icons_Manager::CPT . '_posts_custom_column', [ $this, 'render_columns' ], 10, 2 ); + add_filter( 'enter_title_here', [ $this, 'update_enter_title_here' ], 10, 2 ); + add_filter( 'manage_' . Icons_Manager::CPT . '_posts_columns', [ $this, 'manage_columns' ], 100 ); + add_action( 'current_screen', [ $this, 'add_custom_icon_templates' ] ); + } + + add_action( 'transition_post_status', [ $this, 'transition_post_status' ], 10, 3 ); + add_action( 'before_delete_post', [ $this, 'handle_delete_icon_set' ] ); + add_filter( 'elementor/icons_manager/additional_tabs', [ $this, 'register_icon_libraries_control' ] ); + add_filter( 'elementor/editor/localize_settings', [ $this, 'add_custom_icons_url' ] ); + + // Ajax. + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + } +} diff --git a/modules/assets-manager/asset-types/icons/font-awesome-pro.php b/modules/assets-manager/asset-types/icons/font-awesome-pro.php new file mode 100644 index 00000000..d413c4a3 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/font-awesome-pro.php @@ -0,0 +1,161 @@ + 'fa-regular', + 'label' => esc_html__( 'Font Awesome - Regular Pro', 'elementor-pro' ), + 'url' => false, + 'enqueue' => false, + 'prefix' => 'fa-', + 'displayPrefix' => 'far', + 'labelIcon' => 'fab fa-font-awesome-alt', + 'ver' => '5.15.1-pro', + 'fetchJson' => sprintf( $json_url, 'regular' ), + 'native' => true, + ]; + $icons['fa-solid'] = [ + 'name' => 'fa-solid', + 'label' => esc_html__( 'Font Awesome - Solid Pro', 'elementor-pro' ), + 'url' => false, + 'enqueue' => false, + 'prefix' => 'fa-', + 'displayPrefix' => 'fas', + 'labelIcon' => 'fab fa-font-awesome', + 'ver' => '5.15.1-pro', + 'fetchJson' => sprintf( $json_url, 'solid' ), + 'native' => true, + ]; + $icons['fa-brands'] = [ + 'name' => 'fa-brands', + 'label' => esc_html__( 'Font Awesome - Brands Pro', 'elementor-pro' ), + 'url' => false, + 'enqueue' => false, + 'prefix' => 'fa-', + 'displayPrefix' => 'fab', + 'labelIcon' => 'fab fa-font-awesome-flag', + 'ver' => '5.15.1-pro', + 'fetchJson' => sprintf( $json_url, 'brands' ), + 'native' => true, + ]; + $icons['fa-light'] = [ + 'name' => 'fa-light', + 'label' => esc_html__( 'Font Awesome - Light Pro', 'elementor-pro' ), + 'url' => false, + 'enqueue' => false, + 'prefix' => 'fa-', + 'displayPrefix' => 'fal', + 'labelIcon' => 'fal fa-flag', + 'ver' => '5.15.1-pro', + 'fetchJson' => sprintf( $json_url, 'light' ), + 'native' => true, + ]; + $icons['fa-duotone'] = [ + 'name' => 'fa-duotone', + 'label' => esc_html__( 'Font Awesome - Duotone Pro', 'elementor-pro' ), + 'url' => false, + 'enqueue' => false, + 'prefix' => 'fa-', + 'displayPrefix' => 'fad', + 'labelIcon' => 'fad fa-flag', + 'ver' => '5.15.1-pro', + 'fetchJson' => sprintf( $json_url, 'duotone' ), + 'native' => true, + ]; + // remove Free + unset( + $settings['fa-solid'], + $settings['fa-regular'], + $settings['fa-brands'] + ); + return array_merge( $icons, $settings ); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'font_awesome_pro', [ + 'callback' => function() { + echo '

    ' . esc_html__( 'Font Awesome Pro', 'elementor-pro' ) . '

    '; + echo esc_html__( 'Font Awesome, the web\'s most popular icon set and toolkit, Pro Integration', 'elementor-pro' ); + }, + 'fields' => [ + self::FA_KIT_ID_OPTION_NAME => [ + 'label' => esc_html__( 'Kit ID', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Enter Your %1$sFont Awesome Pro Kit ID%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + 'setting_args' => [ + 'sanitize_callback' => [ $this, 'sanitize_kit_id_settings' ], + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '

    ', + self::FA_KIT_ID_OPTION_NAME . '_fetch', + wp_create_nonce( self::FA_KIT_ID_OPTION_NAME ), + __( 'Validate Kit ID', 'elementor-pro' ) + ), + ], + ], + ], + ] ); + } + + public function enqueue_kit_js() { + wp_enqueue_script( 'font-awesome-pro', sprintf( self::FA_KIT_SCRIPT_LINK, $this->get_kit_id() ), [], ELEMENTOR_PRO_VERSION ); + } + + public function sanitize_kit_id_settings( $input ) { + if ( empty( $input ) ) { + delete_option( 'elementor_' . self::FA_KIT_ID_OPTION_NAME ); + } + + return $input; + } + + protected function actions() { + parent::actions(); + + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 100 ); + } + + if ( $this->get_kit_id() ) { + add_filter( 'elementor/icons_manager/native', [ $this, 'replace_font_awesome_pro' ] ); + add_action( 'elementor/editor/after_enqueue_scripts', [ $this, 'enqueue_kit_js' ] ); + add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'enqueue_kit_js' ] ); + } + } +} diff --git a/modules/assets-manager/asset-types/icons/icon-sets/fontastic.php b/modules/assets-manager/asset-types/icons/icon-sets/fontastic.php new file mode 100644 index 00000000..3b0d79bb --- /dev/null +++ b/modules/assets-manager/asset-types/icons/icon-sets/fontastic.php @@ -0,0 +1,76 @@ +data = Utils::_unstable_file_get_contents( $this->directory . $this->stylesheet_file ); + $this->dir_name = $this->get_unique_name(); + } + + public function get_type() { + return esc_html__( 'Fontastic', 'elementor-pro' ); + } + + public function is_valid() { + if ( ! file_exists( $this->directory . $this->data_file ) ) { + return false; // missing data file + } + return true; + } + + protected function extract_icon_list() { + $pattern = '/\.' . $this->get_prefix() . '(.*)\:before\s\{/'; + preg_match_all( $pattern, $this->data, $icons_matches ); + if ( empty( $icons_matches[1] ) ) { + return false; // missing icons list + } + $icons = []; + foreach ( $icons_matches[1] as $icon ) { + $icons[] = $icon; + } + return $icons; + } + + protected function get_prefix() { + static $set_prefix = null; + if ( null === $set_prefix ) { + $pattern = '/class\^="(.*)?"/'; + preg_match_all( $pattern, $this->data, $prefix ); + if ( ! isset( $prefix[1][0] ) ) { + return false; // missing css_prefix_text + } + $set_prefix = $prefix[1][0]; + } + return $set_prefix; + } + + public function get_name() { + static $set_name = null; + if ( null === $set_name ) { + $pattern = '/font-family: "(.*)"/'; + preg_match_all( $pattern, $this->data, $name ); + if ( ! isset( $name[1][0] ) ) { + return false; // missing name + } + $set_name = $name[1][0]; + } + return $set_name; + } + + protected function get_stylesheet( $unique_name = '' ) { + return $this->get_url() . '/' . $this->stylesheet_file; + } +} diff --git a/modules/assets-manager/asset-types/icons/icon-sets/fontello.php b/modules/assets-manager/asset-types/icons/icon-sets/fontello.php new file mode 100644 index 00000000..d646a47f --- /dev/null +++ b/modules/assets-manager/asset-types/icons/icon-sets/fontello.php @@ -0,0 +1,79 @@ +remove_fontello_styling(); + $this->dir_name = $this->get_unique_name(); + } + + public function get_type() { + return esc_html__( 'Fontello', 'elementor-pro' ); + } + + public function is_valid() { + if ( ! file_exists( $this->directory . $this->data_file ) ) { + return false; // missing data file + } + return true; + } + + private function remove_fontello_styling() { + $filename = $this->directory . 'css/' . $this->get_name() . '.css'; + $stylesheet = Utils::_unstable_file_get_contents( $filename ); + $stylesheet = str_replace( [ 'margin-left: .2em;', 'margin-right: .2em;' ], [ '', '' ], $stylesheet ); + file_put_contents( $filename, $stylesheet ); + } + + private function get_json() { + return json_decode( Utils::_unstable_file_get_contents( $this->directory . $this->data_file ) ); + } + + protected function extract_icon_list() { + $config = $this->get_json(); + if ( ! isset( $config->glyphs ) ) { + return false; // missing icons list + } + $icons = []; + foreach ( $config->glyphs as $icon ) { + $icons[] = $icon->css; + } + return $icons; + } + + protected function get_prefix() { + $config = $this->get_json(); + if ( ! isset( $config->css_prefix_text ) ) { + return false; // missing css_prefix_text + } + return $config->css_prefix_text; + } + + public function get_name() { + $config = $this->get_json(); + if ( ! isset( $config->name ) ) { + return false; // missing name + } + return $config->name; + } + + protected function get_stylesheet() { + $name = $this->get_name(); + if ( ! $name ) { + return false; // missing name + } + return $this->get_url() . '/css/' . $name . '.css'; + } +} diff --git a/modules/assets-manager/asset-types/icons/icon-sets/icomoon.php b/modules/assets-manager/asset-types/icons/icon-sets/icomoon.php new file mode 100644 index 00000000..1ccc3123 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/icon-sets/icomoon.php @@ -0,0 +1,76 @@ +dir_name = $this->get_unique_name(); + return []; + } + + public function get_type() { + return esc_html__( 'Icomoon', 'elementor-pro' ); + } + + public function is_valid() { + if ( ! file_exists( $this->directory . $this->data_file ) ) { + return false; // missing data file + } + return true; + } + + private function get_json() { + return json_decode( Utils::_unstable_file_get_contents( $this->directory . $this->data_file ) ); + } + + protected function extract_icon_list() { + $config = $this->get_json(); + if ( ! isset( $config->icons ) ) { + return false; // missing icons list + } + $icons = []; + foreach ( $config->icons as $icon ) { + $icons[] = $icon->properties->name; + } + return $icons; + } + + protected function get_prefix() { + $config = $this->get_json(); + if ( ! isset( $config->preferences->fontPref->prefix ) ) { + return false; // missing css_prefix_text + } + return $config->preferences->fontPref->prefix; + } + + protected function get_display_prefix() { + $config = $this->get_json(); + if ( ! isset( $config->preferences->fontPref->classSelector ) ) { + return false; // missing css_prefix_text + } + return str_replace( '.', '', $config->preferences->fontPref->classSelector ); + } + + public function get_name() { + $config = $this->get_json(); + if ( ! isset( $config->metadata->name ) ) { + return false; // missing name + } + return $config->metadata->name; + } + + protected function get_stylesheet() { + return $this->get_url( '/' . $this->stylesheet_file ); + } +} diff --git a/modules/assets-manager/asset-types/icons/icon-sets/icon-set-base.php b/modules/assets-manager/asset-types/icons/icon-sets/icon-set-base.php new file mode 100644 index 00000000..91c41ddd --- /dev/null +++ b/modules/assets-manager/asset-types/icons/icon-sets/icon-set-base.php @@ -0,0 +1,254 @@ +directory . $path_name; + if ( ! file_exists( $check ) ) { + return false; + } + if ( $this->is_path_dir( $path_name ) ) { + return is_dir( $check ); + } + return true; + } + + /** + * is icon set + * + * validate that the current uploaded zip is in this icon set format + * @return bool + */ + public function is_icon_set() { + foreach ( $this->allowed_zipped_files as $file ) { + if ( ! $this->is_file_allowed( $file ) ) { + return false; + } + } + return true; + } + + public function is_valid() { + return false; + } + + protected function get_display_prefix() { + return ''; + } + + protected function get_prefix() { + return ''; + } + + public function handle_new_icon_set() { + return $this->prepare(); + } + + /** + * cleanup_temp_files + * @param \WP_Filesystem_Base $wp_filesystem + */ + protected function cleanup_temp_files( $wp_filesystem ) { + $wp_filesystem->rmdir( $this->directory, true ); + } + + /** + * Gets the URL to uploaded file. + * + * @param $file_name + * + * @return string + */ + protected function get_file_url( $file_name ) { + $wp_upload_dir = wp_upload_dir(); + $url = $wp_upload_dir['baseurl'] . '/elementor/custom-icons/' . $file_name; + + /** + * Upload file URL. + * + * Filters the URL to a file uploaded using custom icons. + * + * By default URL to a file uploaded is set to `/elementor/custom-icons/{file_name}` + * inside the WordPress uploads folder. This hook allows developers to change this URL. + * + * @since 1.0.0 + * + * @param string $url File URL. + * @param string $file_name File name. + */ + $url = apply_filters( 'elementor_pro/icons_manager/custom_icons/url', $url, $file_name ); + + return $url; + } + + protected function get_icon_sets_dir() { + $wp_upload_dir = wp_upload_dir(); + $path = $wp_upload_dir['basedir'] . '/elementor/custom-icons'; + + /** + * Upload file path. + * + * Filters the path to a folder uploaded using custom icons. + * + * By default the folder path to custom icon files is set to `/elementor/custom-icons` + * inside the WordPress uploads folder. This hook allows developers to change this path. + * + * @param string $path Path to custom icons uploads directory. + */ + $path = apply_filters( 'elementor_pro/icons_manager/custom_icons/dir', $path ); + + Utils::get_ensure_upload_dir( $path ); + return $path; + } + + protected function get_ensure_upload_dir( $dir = '' ) { + $path = $this->get_icon_sets_dir(); + if ( ! empty( $dir ) ) { + $path .= '/' . $dir; + } + return Utils::get_ensure_upload_dir( $path ); + } + + public function move_files( $post_id ) { + // @todo: save only needed files + $wp_filesystem = Custom_Icons::get_wp_filesystem(); + $to = $this->get_ensure_upload_dir( $this->dir_name ) . '/'; + + foreach ( $wp_filesystem->dirlist( $this->directory, false, true ) as $file ) { + $full_path = $this->directory . $file['name']; + if ( $wp_filesystem->is_dir( $full_path ) ) { + $wp_filesystem->mkdir( $to . $file['name'] ); + + foreach ( $file['files'] as $filename => $sub_file ) { + $new_path = $to . $file['name'] . DIRECTORY_SEPARATOR . $filename; + $wp_filesystem->move( $full_path . DIRECTORY_SEPARATOR . $filename, $new_path ); + $this->insert_attachment( $this->get_url() . '/' . $file['name'] . '/' . $filename, $new_path, $post_id ); + } + } else { + $new_path = $to . $file['name']; + $wp_filesystem->move( $full_path, $new_path ); + $this->insert_attachment( $this->get_url() . '/' . $file['name'], $new_path, $post_id ); + } + } + + $this->cleanup_temp_files( $wp_filesystem ); + update_post_meta( $post_id, '_elementor_icon_set_path', $to ); + $this->directory = $to; + } + + private function insert_attachment( $file_url, $filename, $post_id = 0 ) { + $attachment = [ + 'file' => $filename, + 'guid' => $file_url, + 'post_parent' => $post_id, + 'post_type' => 'attachment', + ]; + $id = wp_insert_attachment( $attachment ); + return $id; + } + + public function get_unique_name() { + $name = $this->get_name(); + $basename = $name; + $counter = 1; + while ( ! $this->is_name_unique( $name ) ) { + $name = $basename . '-' . $counter; + $counter++; + } + return $name; + } + + private function is_name_unique( $name ) { + return ! is_dir( $this->get_icon_sets_dir() . '/' . $name ); + } + + protected function get_url( $filename = '' ) { + return $this->get_file_url( $this->dir_name . $filename ); + } + + protected function get_stylesheet() { + return ''; + } + + protected function get_version() { + return '1.0.0'; + } + + protected function get_enqueue() { + return false; + } + + public function build_config() { + $icon_set_config = [ + 'name' => $this->dir_name, + 'label' => ucwords( str_replace( [ '-', '_' ], ' ', $this->dir_name ) ), + 'url' => $this->get_stylesheet(), + 'enqueue' => $this->get_enqueue(), + 'prefix' => $this->get_prefix(), + 'displayPrefix' => $this->get_display_prefix(), + 'labelIcon' => 'eicon eicon-folder', + 'ver' => $this->get_version(), + 'custom_icon_type' => $this->get_type(), + ]; + + $icons = $this->extract_icon_list(); + $icon_set_config['count'] = count( $icons ); + $icon_set_config['icons'] = $icons; + + if ( 25 < $icon_set_config['count'] ) { + $icon_set_config['fetchJson'] = $this->store_icon_list_json( $icons ); + } + + return $icon_set_config; + } + + private function store_icon_list_json( $icons ) { + $wp_filesystem = Custom_Icons::get_wp_filesystem(); + $json_file = $this->get_ensure_upload_dir( $this->dir_name ) . '/e_icons.js'; + $wp_filesystem->put_contents( $json_file, json_encode( [ 'icons' => $icons ] ) ); + return $this->get_url() . '/e_icons.js'; + } + + /** + * Icon Set Base constructor. + * + * @param $directory + */ + public function __construct( $directory ) { + $this->directory = $directory; + return $this->is_icon_set() ? $this : false; + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export-customization/export-runner.php b/modules/assets-manager/asset-types/icons/import-export-customization/export-runner.php new file mode 100644 index 00000000..5ad2a2d2 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export-customization/export-runner.php @@ -0,0 +1,102 @@ +get_custom_icon_sets(); + + $include_custom_icons = $data['customization']['settings']['customIcons'] ?? true; + + if ( empty( $icon_sets ) || ! $include_custom_icons ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $icon_sets_data = []; + $manifest = []; + + foreach ( $icon_sets as $icon_set ) { + $icon_set_data = $this->prepare_icon_set_data( $icon_set ); + if ( $icon_set_data ) { + $icon_sets_data[] = $icon_set_data; + $manifest['custom-icons'][ $icon_set->ID ] = $icon_set_data; + } + } + + return [ + 'files' => [ + 'path' => Import_Export_Customization::FILE_NAME, + 'data' => $icon_sets_data, + ], + 'manifest' => [ + $manifest, + ], + ]; + } + + private function get_custom_icon_sets() { + return get_posts( [ + 'post_type' => Icons_Manager::CPT, + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + } + + private function prepare_icon_set_data( $icon_set ) { + $icon_set_config = Custom_Icons::get_icon_set_config( $icon_set->ID ); + $icon_set_path = get_post_meta( $icon_set->ID, '_elementor_icon_set_path', true ); + + $icon_type = ''; + if ( $icon_set_config ) { + $config_data = json_decode( $icon_set_config, true ); + $icon_type = $config_data['custom_icon_type'] ?? ''; + } + + $attachments = get_attached_media( '', $icon_set->ID ); + $attachments_data = []; + + foreach ( $attachments as $attachment ) { + $url = wp_get_attachment_url( $attachment->ID ); + $attachments_data[] = [ + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'url' => $url, + ]; + + do_action( 'elementor/templates/collect_media_url', $url, (array) $attachment ); + } + + return [ + 'ID' => $icon_set->ID, + 'post_title' => $icon_set->post_title, + 'post_content' => $icon_set->post_content, + 'post_status' => $icon_set->post_status, + 'icon_set_config' => $icon_set_config, + 'icon_set_path' => $icon_set_path, + 'icon_type' => $icon_type, + 'attachments' => $attachments_data, + ]; + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export-customization/import-export-customization.php b/modules/assets-manager/asset-types/icons/import-export-customization/import-export-customization.php new file mode 100644 index 00000000..707769a8 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export-customization/import-export-customization.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/import-kit', function ( Import $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/revert-kit', function ( Revert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export-customization/import-runner.php b/modules/assets-manager/asset-types/icons/import-export-customization/import-runner.php new file mode 100644 index 00000000..ecc0a704 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export-customization/import-runner.php @@ -0,0 +1,135 @@ +session_id = $data['session_id']; + + $result = []; + + $custom_icons_file_path = $data['extracted_directory_path'] . Import_Export_Customization::FILE_NAME; + $icon_sets_data = ImportExportUtils::read_json_file( $custom_icons_file_path ); + + $include_custom_icons = $data['customization']['settings']['customIcons'] ?? true; + + if ( empty( $icon_sets_data ) || ! $include_custom_icons ) { + return $result; + } + + foreach ( $icon_sets_data as $icon_set_data ) { + $this->import_icon_set( $icon_set_data ); + } + + if ( empty( $this->imported_icon_sets ) ) { + return $result; + } + + $result['site-settings']['custom-icons'] = $this->imported_icon_sets; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_icon_sets' => $this->imported_icon_sets, + ]; + } + + private function import_icon_set( $icon_set_data ) { + $existing_icon_set = $this->get_existing_icon_set( $icon_set_data['post_title'] ); + + if ( $existing_icon_set ) { + return; + } + + $icon_set_id = $this->create_icon_set( $icon_set_data ); + + if ( $icon_set_id ) { + $this->imported_icon_sets[] = [ + 'id' => $icon_set_id, + 'title' => $icon_set_data['post_title'], + ]; + } + } + + private function get_existing_icon_set( $icon_set_title ) { + $icon_set_query = new \WP_Query( [ + 'post_type' => Icons_Manager::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $icon_set_title, + ] ); + + if ( $icon_set_query->have_posts() ) { + $icon_set_post = $icon_set_query->posts[0]; + return [ + 'id' => $icon_set_post->ID, + 'title' => $icon_set_post->post_title, + ]; + } + + return null; + } + + private function create_icon_set( $icon_set_data ) { + $icon_set_id = wp_insert_post( [ + 'post_title' => $icon_set_data['post_title'], + 'post_content' => $icon_set_data['post_content'], + 'post_status' => $icon_set_data['post_status'], + 'post_type' => Icons_Manager::CPT, + ] ); + + if ( is_wp_error( $icon_set_id ) ) { + return false; + } + + $this->set_session_post_meta( $icon_set_id, $this->session_id ); + + if ( ! empty( $icon_set_data['icon_set_config'] ) ) { + update_post_meta( $icon_set_id, Custom_Icons::META_KEY, $icon_set_data['icon_set_config'] ); + } + + if ( ! empty( $icon_set_data['icon_set_path'] ) ) { + update_post_meta( $icon_set_id, '_elementor_icon_set_path', $icon_set_data['icon_set_path'] ); + } + + if ( ! empty( $icon_set_data['attachments'] ) ) { + $this->handle_icon_set_attachments( $icon_set_id, $icon_set_data['attachments'] ); + } + + Custom_Icons::clear_icon_list_option(); + + return $icon_set_id; + } + + private function handle_icon_set_attachments( $icon_set_id, $attachments_data ) { + $this->create_attachments_from_urls( $icon_set_id, $attachments_data ); + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export-customization/revert-runner.php b/modules/assets-manager/asset-types/icons/import-export-customization/revert-runner.php new file mode 100644 index 00000000..c76753b7 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export-customization/revert-runner.php @@ -0,0 +1,85 @@ +revert_imported_icon_sets( $metadata ); + + $this->revert_attachments( $data['session_id'] ); + + Custom_Icons::clear_icon_list_option(); + } + + private function revert_imported_icon_sets( $metadata ) { + $imported_icon_sets = $metadata['imported_icon_sets'] ?? []; + + foreach ( $imported_icon_sets as $icon_set ) { + $this->delete_icon_set_and_attachments( $icon_set['id'] ); + } + } + + private function revert_attachments( $session_id ) { + $attachments_query = new \WP_Query( [ + 'post_type' => 'attachment', + 'post_status' => 'inherit', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => static::META_KEY_ELEMENTOR_IMPORT_SESSION_ID, + 'value' => $session_id, + 'compare' => '=', + ], + ], + ] ); + + if ( ! $attachments_query->have_posts() ) { + return; + } + + foreach ( $attachments_query->posts as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + } + + private function delete_icon_set_and_attachments( $icon_set_id ) { + $icon_set_path = get_post_meta( $icon_set_id, '_elementor_icon_set_path', true ); + if ( $icon_set_path && is_dir( $icon_set_path ) ) { + Plugin::$instance->uploads_manager->remove_file_or_dir( $icon_set_path ); + } + + $attachments = get_attached_media( '', $icon_set_id ); + + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + wp_delete_post( $icon_set_id, true ); + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export/export-runner.php b/modules/assets-manager/asset-types/icons/import-export/export-runner.php new file mode 100644 index 00000000..4f1d9909 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export/export-runner.php @@ -0,0 +1,97 @@ +get_custom_icon_sets(); + + if ( empty( $icon_sets ) ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $icon_sets_data = []; + $manifest = []; + + foreach ( $icon_sets as $icon_set ) { + $icon_set_data = $this->prepare_icon_set_data( $icon_set ); + if ( $icon_set_data ) { + $icon_sets_data[] = $icon_set_data; + $manifest['custom-icons'][ $icon_set->ID ] = $icon_set_data; + } + } + + return [ + 'files' => [ + 'path' => Import_Export::FILE_NAME, + 'data' => $icon_sets_data, + ], + 'manifest' => [ + $manifest, + ], + ]; + } + + private function get_custom_icon_sets() { + return get_posts( [ + 'post_type' => Icons_Manager::CPT, + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + } + + private function prepare_icon_set_data( $icon_set ) { + $icon_set_config = Custom_Icons::get_icon_set_config( $icon_set->ID ); + $icon_set_path = get_post_meta( $icon_set->ID, '_elementor_icon_set_path', true ); + + $icon_type = ''; + if ( $icon_set_config ) { + $config_data = json_decode( $icon_set_config, true ); + $icon_type = $config_data['custom_icon_type'] ?? ''; + } + + $attachments = get_attached_media( '', $icon_set->ID ); + $attachments_data = []; + + foreach ( $attachments as $attachment ) { + $attachments_data[] = [ + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'url' => wp_get_attachment_url( $attachment->ID ), + ]; + } + + return [ + 'ID' => $icon_set->ID, + 'post_title' => $icon_set->post_title, + 'post_content' => $icon_set->post_content, + 'post_status' => $icon_set->post_status, + 'icon_set_config' => $icon_set_config, + 'icon_set_path' => $icon_set_path, + 'icon_type' => $icon_type, + 'attachments' => $attachments_data, + ]; + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export/import-export.php b/modules/assets-manager/asset-types/icons/import-export/import-export.php new file mode 100644 index 00000000..1568570d --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export/import-export.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export/import-kit', function ( Import $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export/revert-kit', function ( Revert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export/import-runner.php b/modules/assets-manager/asset-types/icons/import-export/import-runner.php new file mode 100644 index 00000000..33f46f24 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export/import-runner.php @@ -0,0 +1,133 @@ +session_id = $data['session_id']; + + $result = []; + + $custom_icons_file_path = $data['extracted_directory_path'] . Import_Export::FILE_NAME; + $icon_sets_data = ImportExportUtils::read_json_file( $custom_icons_file_path ); + + if ( empty( $icon_sets_data ) ) { + return $result; + } + + foreach ( $icon_sets_data as $icon_set_data ) { + $this->import_icon_set( $icon_set_data ); + } + + if ( empty( $this->imported_icon_sets ) ) { + return $result; + } + + $result['site-settings']['custom-icons'] = $this->imported_icon_sets; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_icon_sets' => $this->imported_icon_sets, + ]; + } + + private function import_icon_set( $icon_set_data ) { + $existing_icon_set = $this->get_existing_icon_set( $icon_set_data['post_title'] ); + + if ( $existing_icon_set ) { + return; + } + + $icon_set_id = $this->create_icon_set( $icon_set_data ); + + if ( $icon_set_id ) { + $this->imported_icon_sets[] = [ + 'id' => $icon_set_id, + 'title' => $icon_set_data['post_title'], + ]; + } + } + + private function get_existing_icon_set( $icon_set_title ) { + $icon_set_query = new \WP_Query( [ + 'post_type' => Icons_Manager::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $icon_set_title, + ] ); + + if ( $icon_set_query->have_posts() ) { + $icon_set_post = $icon_set_query->posts[0]; + return [ + 'id' => $icon_set_post->ID, + 'title' => $icon_set_post->post_title, + ]; + } + + return null; + } + + private function create_icon_set( $icon_set_data ) { + $icon_set_id = wp_insert_post( [ + 'post_title' => $icon_set_data['post_title'], + 'post_content' => $icon_set_data['post_content'], + 'post_status' => $icon_set_data['post_status'], + 'post_type' => Icons_Manager::CPT, + ] ); + + if ( is_wp_error( $icon_set_id ) ) { + return false; + } + + $this->set_session_post_meta( $icon_set_id, $this->session_id ); + + if ( ! empty( $icon_set_data['icon_set_config'] ) ) { + update_post_meta( $icon_set_id, Custom_Icons::META_KEY, $icon_set_data['icon_set_config'] ); + } + + if ( ! empty( $icon_set_data['icon_set_path'] ) ) { + update_post_meta( $icon_set_id, '_elementor_icon_set_path', $icon_set_data['icon_set_path'] ); + } + + if ( ! empty( $icon_set_data['attachments'] ) ) { + $this->handle_icon_set_attachments( $icon_set_id, $icon_set_data['attachments'] ); + } + + Custom_Icons::clear_icon_list_option(); + + return $icon_set_id; + } + + private function handle_icon_set_attachments( $icon_set_id, $attachments_data ) { + $this->create_attachments_from_urls( $icon_set_id, $attachments_data ); + } +} diff --git a/modules/assets-manager/asset-types/icons/import-export/revert-runner.php b/modules/assets-manager/asset-types/icons/import-export/revert-runner.php new file mode 100644 index 00000000..7be69759 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/import-export/revert-runner.php @@ -0,0 +1,85 @@ +revert_imported_icon_sets( $metadata ); + + $this->revert_attachments( $data['session_id'] ); + + Custom_Icons::clear_icon_list_option(); + } + + private function revert_imported_icon_sets( $metadata ) { + $imported_icon_sets = $metadata['imported_icon_sets'] ?? []; + + foreach ( $imported_icon_sets as $icon_set ) { + $this->delete_icon_set_and_attachments( $icon_set['id'] ); + } + } + + private function revert_attachments( $session_id ) { + $attachments_query = new \WP_Query( [ + 'post_type' => 'attachment', + 'post_status' => 'inherit', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => static::META_KEY_ELEMENTOR_IMPORT_SESSION_ID, + 'value' => $session_id, + 'compare' => '=', + ], + ], + ] ); + + if ( ! $attachments_query->have_posts() ) { + return; + } + + foreach ( $attachments_query->posts as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + } + + private function delete_icon_set_and_attachments( $icon_set_id ) { + $icon_set_path = get_post_meta( $icon_set_id, '_elementor_icon_set_path', true ); + if ( $icon_set_path && is_dir( $icon_set_path ) ) { + Plugin::$instance->uploads_manager->remove_file_or_dir( $icon_set_path ); + } + + $attachments = get_attached_media( '', $icon_set_id ); + + foreach ( $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + wp_delete_post( $icon_set_id, true ); + } +} diff --git a/modules/assets-manager/asset-types/icons/templates.php b/modules/assets-manager/asset-types/icons/templates.php new file mode 100644 index 00000000..bd4f8957 --- /dev/null +++ b/modules/assets-manager/asset-types/icons/templates.php @@ -0,0 +1,21 @@ + + + + + + diff --git a/modules/assets-manager/asset-types/import-export/traits/external-attachment-trait.php b/modules/assets-manager/asset-types/import-export/traits/external-attachment-trait.php new file mode 100644 index 00000000..3d16dd04 --- /dev/null +++ b/modules/assets-manager/asset-types/import-export/traits/external-attachment-trait.php @@ -0,0 +1,76 @@ +templates_manager->get_import_images_instance()->import_local_file( $local_file_path, $parent_id ); + } + + if ( $imported_attachment ) { + wp_update_post( [ + 'ID' => $imported_attachment['id'], + 'post_title' => $attachment_data['title'], + 'post_content' => '', + 'post_status' => 'inherit', + 'post_parent' => $parent_id, + 'post_mime_type' => 'application/octet-stream', + ] ); + + return $imported_attachment['id']; + } + + $attachment_id = wp_insert_attachment( [ + 'post_title' => $attachment_data['title'], + 'post_content' => '', + 'post_status' => 'inherit', + 'post_parent' => $parent_id, + 'post_mime_type' => 'application/octet-stream', + ], '' ); + + if ( is_wp_error( $attachment_id ) ) { + return false; + } + + update_post_meta( $attachment_id, '_external_url', $attachment_data['url'] ); + + $this->set_session_post_meta( $attachment_id, $this->session_id ); + + $this->add_external_url_filter(); + + return $attachment_id; + } + + public function add_external_url_filter() { + add_filter( 'wp_get_attachment_url', function( $url, $attachment_id ) { + $external_url = get_post_meta( $attachment_id, '_external_url', true ); + if ( $external_url ) { + return $external_url; + } + return $url; + }, 10, 2 ); + } + + public function create_attachments_from_urls( $parent_id, $attachments_data ): array { + $attachment_ids = []; + + foreach ( $attachments_data as $attachment_data ) { + $attachment_id = $this->create_attachment_from_url( $parent_id, $attachment_data ); + if ( $attachment_id ) { + $attachment_ids[] = $attachment_id; + } + } + + return $attachment_ids; + } +} diff --git a/modules/assets-manager/classes/assets-base.php b/modules/assets-manager/classes/assets-base.php new file mode 100644 index 00000000..58fcad7b --- /dev/null +++ b/modules/assets-manager/classes/assets-base.php @@ -0,0 +1,394 @@ + +
    + get_metabox_field_html( $field, $field['saved'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + endforeach; + ?> +
    + get_html_field( $field ); + + return $html; + break; + + case 'html_tag': + $html = $this->get_html_tag( $field ); + + return $html; + break; + + case 'toolbar': + $html = $this->get_repeater_tools( $field ); + break; + + case 'input': + $html = $this->get_input_field( $field, $saved ); + break; + + case 'select': + $html = $this->get_select_field( $field, $saved ); + break; + + case 'textarea': + $html = $this->get_textarea_field( $field, $saved ); + break; + + case 'file': + $html = $this->get_file_field( $field, $saved ); + break; + + case 'repeater': + $html = $this->get_repeater_field( $field, $saved ); + break; + + case 'dropzone': + $html = $this->get_dropzone_field( $field, $saved ); + break; + + case 'checkbox': + $html = $this->get_checkbox_field( $field, $saved ); + break; + + default: + $method = 'get_' . $field['field_type'] . 'field'; + if ( method_exists( $this, $method ) ) { + $html = call_user_func( [ $this, $method ], $field, $saved ); + } + break; + } + + return $this->get_field_row( $field, $html ); + } + + public function get_field_label( $field ) { + if ( ! isset( $field['label'] ) || false === $field['label'] ) { + return ''; + } + $id = $field['id']; + if ( 'file' === $field['field_type'] ) { + $id .= $field['field_type']; + } + + return ''; + } + + public function get_input_field( $attributes, $saved = '' ) { + if ( isset( $attributes['input_type'] ) ) { + $attributes['type'] = $attributes['input_type']; + unset( $attributes['input_type'], $attributes['field_type'] ); + } + + if ( 'checkbox' === $attributes['type'] && ! empty( $saved ) ) { + $attributes['checked'] = 'checked'; + } else { + if ( empty( $attributes['value'] ) && ! empty( $saved ) ) { + $attributes['value'] = $saved; + } + } + + if ( empty( $attributes['name'] ) ) { + $attributes['name'] = $attributes['id']; + } + + $input = 'get_attribute_string( $attributes ) . '>'; + + return $input; + } + + public function get_attribute_string( $attributes, $field = [] ) { + if ( isset( $field['extra_attributes'] ) && is_array( $field['extra_attributes'] ) ) { + $attributes = array_merge( $attributes, $field['extra_attributes'] ); + } + $attributes_array = []; + foreach ( $attributes as $name => $value ) { + $attributes_array[] = sprintf( '%s="%s"', $name, esc_attr( $value ) ); + } + + return implode( ' ', $attributes_array ); + } + + public function get_select_field( $field, $selected = '' ) { + $input = ''; + } + + public function get_textarea_field( $field, $html ) { + $input = ''; + + return $input; + } + + public function get_file_field( $field, $saved ) { + $value = [ + 'id' => '', + 'url' => '', + ]; + + if ( isset( $saved['id'] ) && isset( $saved['url'] ) ) { + $value = $saved; + } + + $html = '
      '; + $html .= $this->get_input_field( + [ + 'type' => 'hidden', + 'name' => $field['id'] . '[id]', + 'value' => $value['id'], + ] + ); + + $html .= $this->get_input_field( + [ + 'type' => 'text', + 'name' => $field['id'] . '[url]', + 'value' => $value['url'], + 'placeholder' => $field['description'], + 'class' => 'elementor-field-input', + ] + ); + + $html .= $this->get_input_field( + [ + 'type' => 'button', + 'class' => 'button elementor-upload-btn', + 'name' => $field['id'], + 'id' => $field['id'], + 'value' => '', + 'data-preview_anchor' => isset( $field['preview_anchor'] ) ? $field['preview_anchor'] : 'none', + 'data-mime_type' => isset( $field['mine'] ) ? $field['mine'] : '', + 'data-ext' => isset( $field['ext'] ) ? $field['ext'] : '', + 'data-upload_text' => esc_html__( 'Upload', 'elementor-pro' ), + 'data-remove_text' => esc_html__( 'Delete', 'elementor-pro' ), + 'data-box_title' => isset( $field['box_title'] ) ? $field['box_title'] : '', + 'data-box_action' => isset( $field['box_action'] ) ? $field['box_action'] : '', + ] + ); + + return $html; + } + + public function get_html_field( $field ) { + return $field['raw_html']; + } + + public function get_dropzone_field( $field ) { + ob_start(); + $input_attributes = [ + 'type' => 'file', + 'name' => $field['id'], + 'id' => $field['id'], + 'accept' => $field['accept'], + 'class' => 'box__file', + ]; + if ( ! empty( $field['multiple'] ) ) { + $input_attributes['multiple'] = true; + } + $input_html = $this->get_input_field( $input_attributes ); + $field['label'] = '

      ' . esc_html__( 'Drag & Drop to Upload', 'elementor-pro' ) . '

      '; + if ( ! empty( $field['sub-label'] ) ) { + $field['label'] .= '
      ' . $field['sub-label'] . '
      '; + } + ?> +
      +
      +
      + +
      + + get_field_label( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
      + +
      +
      +
      +
      +
      .
      +
      + 'row_label_' . $js_id, + 'class' => 'repeater-title hidden', + ]; + + if ( is_array( $row_label ) ) { + $label = $row_label['default']; + $row_label_html_args['data-default'] = $row_label['default']; + $row_label_html_args['data-selector'] = $row_label['selector']; + } else { + $label = $row_label; + $row_label_html_args['data-default'] = $row_label; + } + + $row_label_html = 'get_attribute_string( $row_label_html_args ) . '>' . $label . ''; + ob_start(); + ?> + + get_attribute_string( $row_label_html_args ) . '>' . $label . ''; + if ( is_array( $saved ) && count( $saved ) > 0 ) { + foreach ( (array) $saved as $key => $item ) { + echo '
      '; + echo $row_label_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $this->get_repeater_tools( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo ''; // end table + echo '
      '; + $counter++; + } + } + echo ''; + + return ob_get_clean(); + } + + public function get_checkbox_field( $field, $saved ) { + Utils::print_unescaped_internal_string( $this->get_field_row( $field, '' ) ); + + $html = '
      '; + + foreach ( $field['options'] as $checkbox_key => $label ) { + $name = $field['id'] . '_' . $checkbox_key; + + $checked = ! empty( $saved ) && in_array( $checkbox_key, $saved, true ) ? 'checked' : ''; + + $html .= '' . esc_html( $label ) . ''; + } + + $html .= '
      '; + + return $html; + } + + private function get_html_tag( $field ) { + $tag = isset( $field['tag'] ) ? $field['tag'] : 'div'; + if ( isset( $field['close'] ) && true === $field['close'] ) { + return ''; + } + + return '<' . $tag . ' ' . $this->get_attribute_string( $field['attributes'] ) . '>'; + } + + private function get_repeater_tools( $field ) { + $confirm = isset( $field['confirm'] ) ? $field['confirm'] : esc_html__( 'Are you sure?', 'elementor-pro' ); + $remove_title = isset( $field['remove_title'] ) ? $field['remove_title'] : esc_html__( 'Delete', 'elementor-pro' ); + $toggle_title = isset( $field['toggle_title'] ) ? $field['toggle_title'] : esc_html__( 'Edit', 'elementor-pro' ); + $close_title = isset( $field['close_title'] ) ? $field['close_title'] : esc_html__( 'Close', 'elementor-pro' ); + + return ' + ' . $close_title . ' + + + ' . $toggle_title . ' + + + ' . $remove_title . ' + '; + } + + public function get_field_row( $field, $field_html ) { + $description = ''; + $css_id = isset( $field['id'] ) ? ' ' . $field['id'] : ''; + + if ( isset( $field['real_id'] ) ) { + $css_id = ' ' . $field['real_id']; + } + + $css_id .= ' elementor-field-' . $field['field_type']; + + return '
      ' . $this->get_field_label( $field ) . $field_html . $description . '
      '; + } + + public function sanitize_text_field_recursive( $data ) { + if ( is_array( $data ) ) { + foreach ( $data as $key => $value ) { + $data[ $key ] = $this->sanitize_text_field_recursive( $value ); + } + + return $data; + } + + return sanitize_text_field( $data ); + } + + public function __construct() { + $this->actions(); + } +} diff --git a/modules/assets-manager/classes/font-base.php b/modules/assets-manager/classes/font-base.php new file mode 100644 index 00000000..12becab3 --- /dev/null +++ b/modules/assets-manager/classes/font-base.php @@ -0,0 +1,50 @@ +font_preview_phrase = esc_html__( 'PRO Elements Is Making the Web Beautiful', 'elementor-pro' ); + } + + public function get_name() { + return ''; + } + + public function get_type() { + return ''; + } + + public function handle_panel_request( array $data ) { + return []; + } + + public function get_fonts( $force = false ) {} + + public function enqueue_font( $font_family, $font_data, $post_css ) {} + + public function get_font_family_type( $post_id, $post_title ) {} + + public function get_font_data( $post_id, $post_title ) {} + + public function render_preview_column( $post_id ) {} + + public function render_type_column( $post_id ) {} + + public function get_font_variations_count( $post_id ) {} + + public function save_meta( $post_id, $data ) {} +} diff --git a/modules/assets-manager/module.php b/modules/assets-manager/module.php new file mode 100644 index 00000000..4c5465df --- /dev/null +++ b/modules/assets-manager/module.php @@ -0,0 +1,53 @@ +asset_managers[ $name ] = $instance; + } + + public function get_assets_manager( $id = null ) { + if ( $id ) { + if ( ! isset( $this->asset_managers[ $id ] ) ) { + return null; + } + + return $this->asset_managers[ $id ]; + } + + return $this->asset_managers; + } + + public function __construct() { + parent::__construct(); + + $this->add_asset_manager( 'font', new AssetTypes\Fonts_Manager() ); + $this->add_asset_manager( 'icon', new AssetTypes\Icons_Manager() ); + + $this->register_import_export(); + } + + private function register_import_export() { + ( new Fonts_Import_Export() )->register_hooks(); + ( new Fonts_Import_Export_Customization() )->register_hooks(); + ( new Icons_Import_Export() )->register_hooks(); + ( new Icons_Import_Export_Customization() )->register_hooks(); + } +} diff --git a/modules/attributes/module.php b/modules/attributes/module.php new file mode 100644 index 00000000..10ce6235 --- /dev/null +++ b/modules/attributes/module.php @@ -0,0 +1,77 @@ +is_attributes_active() ) { + add_filter( + 'elementor/atomic-widgets/controls', + fn( $element_controls, $atomic_element ) => $this->inject_attrs_control( $element_controls, $atomic_element ), + 10, + 2 + ); + } + } + + private function inject_attrs_control( $element_controls, $atomic_element ) { + $schema = $atomic_element::get_props_schema(); + if ( ! array_key_exists( 'attributes', $schema ) || ! class_exists( '\\Elementor\\Modules\\AtomicWidgets\\PropTypes\\Attributes_Prop_Type' ) ) { + return $element_controls; + } + + foreach ( $element_controls as $item ) { + if ( $item instanceof Section && $item->get_id() === 'settings' ) { + $control = Repeatable_Control::bind_to( 'attributes' ) + ->set_meta( [ 'topDivider' => true ] ) + ->set_repeaterLabel( __( 'Attributes', 'elementor-pro' ) ) + ->set_initialValues( + [ + 'key' => [ + '$$type' => 'string', + 'value' => '', + ], + 'value' => [ + '$$type' => 'string', + 'value' => '', + ], + ] + ) + ->set_child_control_props( (object) [] ) + ->set_patternLabel( '${value.key.value}="${value.value.value}"' ) + ->set_placeholder( 'Empty attribute' ) + ->set_child_control_type( 'attributes' ) + ->hide_duplicate() + ->hide_toggle(); + + if ( method_exists( $control, 'set_prop_key' ) ) { + $control->set_prop_key( 'attributes' ); + } + + $item->add_item( $control ); + break; + } + } + + return $element_controls; + } +} diff --git a/modules/blockquote/module.php b/modules/blockquote/module.php new file mode 100644 index 00000000..fa8faeca --- /dev/null +++ b/modules/blockquote/module.php @@ -0,0 +1,53 @@ +get_css_assets_url( 'widget-blockquote', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/blockquote/widgets/blockquote.php b/modules/blockquote/widgets/blockquote.php new file mode 100644 index 00000000..abce372b --- /dev/null +++ b/modules/blockquote/widgets/blockquote.php @@ -0,0 +1,1007 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_style_depends(): array { + $style_depends = [ 'widget-blockquote' ]; + + if ( Icons_Manager::is_migration_allowed() ) { + $style_depends[] = 'elementor-icons-fa-brands'; + } + + return $style_depends; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_blockquote_content', + [ + 'label' => esc_html__( 'Blockquote', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'blockquote_skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'border' => esc_html__( 'Border', 'elementor-pro' ), + 'quotation' => esc_html__( 'Quotation', 'elementor-pro' ), + 'boxed' => esc_html__( 'Boxed', 'elementor-pro' ), + 'clean' => esc_html__( 'Clean', 'elementor-pro' ), + ], + 'default' => 'border', + 'prefix_class' => 'elementor-blockquote--skin-', + 'separator' => 'after', + ] + ); + + $this->add_control( + 'blockquote_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ) . esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your quote', 'elementor-pro' ), + 'rows' => 10, + ] + ); + + $this->add_control( + 'author_name', + [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'John Doe', 'elementor-pro' ), + 'separator' => 'after', + ] + ); + + $this->add_control( + 'tweet_button', + [ + 'label' => esc_html__( 'Tweet Button', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'tweet_button_view', + [ + 'label' => esc_html__( 'View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'icon-text' => esc_html__( 'Icon & Text', 'elementor-pro' ), + 'icon' => esc_html__( 'Icon', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-blockquote--button-view-', + 'default' => 'icon-text', + 'render_type' => 'template', + 'condition' => [ + 'tweet_button' => 'yes', + ], + ] + ); + + $this->add_control( + 'tweet_button_skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'classic' => esc_html__( 'Classic', 'elementor-pro' ), + 'bubble' => esc_html__( 'Bubble', 'elementor-pro' ), + 'link' => esc_html__( 'Link', 'elementor-pro' ), + ], + 'default' => 'classic', + 'prefix_class' => 'elementor-blockquote--button-skin-', + 'condition' => [ + 'tweet_button' => 'yes', + ], + ] + ); + + $this->add_control( + 'tweet_button_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Tweet', 'elementor-pro' ), + 'condition' => [ + 'tweet_button' => 'yes', + 'tweet_button_view!' => 'icon', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'user_name', + [ + 'label' => esc_html__( 'Username', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => '@username', + 'condition' => [ + 'tweet_button' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'url_type', + [ + 'label' => esc_html__( 'Target URL', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'current_page' => esc_html__( 'Current Page', 'elementor-pro' ), + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'current_page', + 'condition' => [ + 'tweet_button' => 'yes', + ], + ] + ); + + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'input_type' => 'url', + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::POST_META_CATEGORY, + TagsModule::URL_CATEGORY, + ], + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'https://your-link.com', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'tweet_button' => 'yes', + 'url_type' => 'custom', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-blockquote--align-', + 'separator' => 'after', + ] + ); + + $this->add_control( + 'heading_content_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'content_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__content' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_typography', + 'selector' => '{{WRAPPER}} .elementor-blockquote__content', + ] + ); + + $this->add_responsive_control( + 'content_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__content +.e-q-footer' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_author_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'author_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__author' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'author_typography', + 'selector' => '{{WRAPPER}} .elementor-blockquote__author', + ] + ); + + $this->add_responsive_control( + 'author_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__author' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'alignment' => 'center', + 'tweet_button' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0.5, + 'max' => 2, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'font-size: calc({{SIZE}}{{UNIT}} * 10);', + ], + ] + ); + + $this->add_responsive_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'min' => 0, + 'max' => 5, + ], + 'rem' => [ + 'min' => 0, + 'max' => 5, + ], + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'background-color: {{VALUE}}', + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-left .elementor-blockquote__tweet-button:before' => 'border-right-color: {{VALUE}}; border-left-color: transparent', + 'body.rtl {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-right .elementor-blockquote__tweet-button:before' => 'border-left-color: {{VALUE}}; border-right-color: transparent', + ], + 'condition' => [ + 'tweet_button_skin!' => 'link', + ], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'color: {{VALUE}}', + '{{WRAPPER}} .elementor-blockquote__tweet-button svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button:hover' => 'background-color: {{VALUE}}', + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote__tweet-button:hover:before, body {{WRAPPER}}.elementor-blockquote--align-left .elementor-blockquote__tweet-button:hover:before' => 'border-right-color: {{VALUE}}; border-left-color: transparent', + 'body.rtl {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-right .elementor-blockquote__tweet-button:hover:before' => 'border-left-color: {{VALUE}}; border-right-color: transparent', + ], + 'condition' => [ + 'tweet_button_skin!' => 'link', + ], + ] + ); + + $this->add_control( + 'button_text_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button:hover' => 'color: {{VALUE}}', + '{{WRAPPER}} .elementor-blockquote__tweet-button:hover svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $default_fonts = Plugin::elementor()->kits_manager->get_current_settings( 'default_generic_fonts' ); + + if ( $default_fonts ) { + $default_fonts = ', ' . $default_fonts; + } + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .elementor-blockquote__tweet-button span, {{WRAPPER}} .elementor-blockquote__tweet-button i', + 'separator' => 'before', + 'fields_options' => [ + 'font_family' => [ + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__tweet-button' => 'font-family: "{{VALUE}}"' . $default_fonts . ';', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_border_style', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'blockquote_skin' => 'border', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_border_style' ); + + $this->start_controls_tab( + 'tab_border_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote' => 'border-left-width: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .elementor-blockquote' => 'border-right-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote' => 'padding-left: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .elementor-blockquote' => 'padding-right: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_border_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'border_color_hover', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote:hover' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_width_hover', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote:hover' => 'border-left-width: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .elementor-blockquote:hover' => 'border-right-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_gap_hover', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-blockquote:hover' => 'padding-left: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .elementor-blockquote:hover' => 'padding-right: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'border_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'border_vertical_padding', + [ + 'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + 'condition' => [ + 'blockquote_skin' => 'border', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_box_style', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'blockquote_skin!' => 'border', + ], + ] + ); + + $this->add_responsive_control( + 'box_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_box_style' ); + + $this->start_controls_tab( + 'tab_box_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'box_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'box_border', + 'selector' => '{{WRAPPER}} .elementor-blockquote', + ] + ); + + $this->add_responsive_control( + 'box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_box_shadow', + 'exclude' => [ + 'box_shadow_position', + ], + 'selector' => '{{WRAPPER}} .elementor-blockquote', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_box_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'box_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'box_border_hover', + 'selector' => '{{WRAPPER}} .elementor-blockquote:hover', + ] + ); + + $this->add_responsive_control( + 'box_border_radius_hover', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote:hover' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_box_shadow_hover', + 'exclude' => [ + 'box_shadow_position', + ], + 'selector' => '{{WRAPPER}} .elementor-blockquote:hover', + ] + ); + + $this->add_control( + 'box_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_quote_style', + [ + 'label' => esc_html__( 'Quote', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'blockquote_skin' => 'quotation', + ], + ] + ); + + $this->add_control( + 'quote_text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote:before' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'quote_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0.5, + 'max' => 2, + 'step' => 0.1, + ], + ], + 'default' => [ + 'size' => 1, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote:before' => 'font-size: calc({{SIZE}}{{UNIT}} * 100)', + ], + ] + ); + + $this->add_responsive_control( + 'quote_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-blockquote__content' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['blockquote_content'] ) && empty( $settings['author_name'] ) && 'yes' !== $settings['tweet_button'] ) { + return; + } + + $tweet_button_view = $settings['tweet_button_view']; + $share_link = 'https://twitter.com/intent/tweet'; + + $text = rawurlencode( $settings['blockquote_content'] ); + + if ( ! empty( $settings['author_name'] ) ) { + $text .= ' — ' . $settings['author_name']; + } + + $share_link = add_query_arg( 'text', $text, $share_link ); + + if ( 'current_page' === $settings['url_type'] ) { + $share_link = add_query_arg( 'url', rawurlencode( home_url() . add_query_arg( false, false ) ), $share_link ); + } elseif ( 'custom' === $settings['url_type'] ) { + $share_link = add_query_arg( 'url', rawurlencode( $settings['url'] ), $share_link ); + } + + if ( ! empty( $settings['user_name'] ) ) { + $user_name = $settings['user_name']; + if ( '@' === substr( $user_name, 0, 1 ) ) { + $user_name = substr( $user_name, 1 ); + } + $share_link = add_query_arg( 'via', rawurlencode( $user_name ), $share_link ); + } + + $this->add_render_attribute( [ + 'blockquote_content' => [ 'class' => 'elementor-blockquote__content' ], + 'author_name' => [ 'class' => 'elementor-blockquote__author' ], + 'tweet_button_label' => [ 'class' => 'elementor-blockquote__tweet-label' ], + ] ); + + $this->add_inline_editing_attributes( 'blockquote_content' ); + $this->add_inline_editing_attributes( 'author_name', 'none' ); + $this->add_inline_editing_attributes( 'tweet_button_label', 'none' ); + ?> +
      +

      print_render_attribute_string( 'blockquote_content' ); ?>> + +

      + + + +
      + + <# + if ( '' === settings.blockquote_content && '' === settings.author_name && 'yes' !== settings.tweet_button) { + return; + } + + var tweetButtonView = settings.tweet_button_view; + #> +
      +

      + {{ settings.blockquote_content }} +

      + <# if ( 'yes' === settings.tweet_button || settings.author_name ) { #> + + <# } #> +
      + breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-call-to-action', + Plugin::get_frontend_file_url( "widget-call-to-action{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + + wp_register_style( + 'e-transitions', + $this->get_css_assets_url( 'transitions', 'assets/css/conditionals/', true ), + [], + ELEMENTOR_PRO_VERSION + ); + + wp_register_style( + 'e-ribbon', + $this->get_css_assets_url( 'ribbon', 'assets/css/conditionals/', true ), + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function enqueue_preview_styles() { + wp_enqueue_style( 'e-ribbon' ); + } +} diff --git a/modules/call-to-action/widgets/call-to-action.php b/modules/call-to-action/widgets/call-to-action.php new file mode 100644 index 00000000..42b98392 --- /dev/null +++ b/modules/call-to-action/widgets/call-to-action.php @@ -0,0 +1,2041 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-call-to-action', 'e-transitions' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_main_image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'classic' => esc_html__( 'Classic', 'elementor-pro' ), + 'cover' => esc_html__( 'Cover', 'elementor-pro' ), + ], + 'render_type' => 'template', + 'prefix_class' => 'elementor-cta--skin-', + 'default' => 'classic', + ] + ); + + $this->add_responsive_control( + 'layout', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'above' => [ + 'title' => esc_html__( 'Above', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'below' => [ + 'title' => esc_html__( 'Below', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'prefix_class' => 'elementor-cta-%s-layout-image-', + 'condition' => [ + 'skin!' => 'cover', + ], + ] + ); + + $this->add_control( + 'bg_image', + [ + 'label' => esc_html__( 'Choose Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'bg_image', // Actually its `image_size` + 'label' => esc_html__( 'Image Resolution', 'elementor-pro' ), + 'default' => 'large', + 'condition' => [ + 'bg_image[id]!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'graphic_element', + [ + 'label' => esc_html__( 'Graphic Element', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'none' => [ + 'title' => esc_html__( 'None', 'elementor-pro' ), + 'icon' => 'eicon-ban', + ], + 'image' => [ + 'title' => esc_html__( 'Image', 'elementor-pro' ), + 'icon' => 'eicon-image-bold', + ], + 'icon' => [ + 'title' => esc_html__( 'Icon', 'elementor-pro' ), + 'icon' => 'eicon-star', + ], + ], + 'default' => 'none', + ] + ); + + $this->add_control( + 'graphic_image', + [ + 'label' => esc_html__( 'Choose Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + 'show_label' => false, + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'graphic_image', // Actually its `image_size` + 'default' => 'thumbnail', + 'condition' => [ + 'graphic_element' => 'image', + 'graphic_image[id]!' => '', + ], + ] + ); + + $this->add_control( + 'selected_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-star', + 'library' => 'fa-solid', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'This is the heading', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your title', 'elementor-pro' ), + 'label_block' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'h2', + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_control( + 'description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your description', 'elementor-pro' ), + 'separator' => 'before', + 'rows' => 5, + ] + ); + + $this->add_control( + 'description_tag', + [ + 'label' => esc_html__( 'Description HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'div', + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_control( + 'button', + [ + 'label' => esc_html__( 'Button Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Click Here', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'link_click', + [ + 'label' => esc_html__( 'Apply Link On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'box' => esc_html__( 'Whole Box', 'elementor-pro' ), + 'button' => esc_html__( 'Button Only', 'elementor-pro' ), + ], + 'default' => 'button', + 'condition' => [ + 'link[url]!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_ribbon', + [ + 'label' => esc_html__( 'Ribbon', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'ribbon_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'assets' => [ + 'styles' => [ + [ + 'name' => 'e-ribbon', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'ribbon_title', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'ribbon_horizontal_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'ribbon_title!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'box_style', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'min-height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'em' => [ + 'min' => 10, + 'max' => 100, + ], + 'rem' => [ + 'min' => 10, + 'max' => 100, + ], + 'vh' => [ + 'min' => 10, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__content' => 'min-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__content' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'prefix_class' => 'elementor-cta--valign-', + ] + ); + + $this->add_responsive_control( + 'padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_bg_image_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'condition' => [ + 'bg_image[url]!' => '', + 'skin' => 'classic', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'image_min_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 500, + ], + 'em' => [ + 'max' => 50, + ], + 'rem' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__bg-wrapper' => 'min-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'skin' => 'classic', + 'layout!' => 'above', + ], + ] + ); + + $this->add_responsive_control( + 'image_min_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 500, + ], + 'em' => [ + 'max' => 50, + ], + 'rem' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__bg-wrapper' => 'min-height: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'graphic_element_style', + [ + 'label' => esc_html__( 'Graphic Element', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'graphic_element!' => [ + 'none', + '', + ], + ], + ] + ); + + $this->add_control( + 'graphic_image_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__image' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'graphic_image_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 5, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__image img' => 'width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'graphic_image_border', + 'selector' => '{{WRAPPER}} .elementor-cta__image img', + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'graphic_image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__image img' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'icon_view', + [ + 'label' => esc_html__( 'View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + 'framed' => esc_html__( 'Framed', 'elementor-pro' ), + ], + 'default' => 'default', + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_shape', + [ + 'label' => esc_html__( 'Shape', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'circle' => esc_html__( 'Circle', 'elementor-pro' ), + 'square' => esc_html__( 'Square', 'elementor-pro' ), + ], + 'default' => 'circle', + 'condition' => [ + 'icon_view!' => 'default', + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-wrapper' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-view-stacked .elementor-icon' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon svg' => 'stroke: {{VALUE}}', + '{{WRAPPER}} .elementor-view-framed .elementor-icon, {{WRAPPER}} .elementor-view-default .elementor-icon' => 'color: {{VALUE}}; border-color: {{VALUE}}', + '{{WRAPPER}} .elementor-view-framed .elementor-icon, {{WRAPPER}} .elementor-view-default .elementor-icon svg' => 'fill: {{VALUE}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-view-framed .elementor-icon' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-view-framed .elementor-icon svg' => 'stroke: {{VALUE}};', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon svg' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 6, + 'max' => 300, + ], + 'em' => [ + 'min' => 0.6, + 'max' => 30, + ], + 'rem' => [ + 'min' => 0.6, + 'max' => 30, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'font-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_padding', + [ + 'label' => esc_html__( 'Icon Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'padding: {{SIZE}}{{UNIT}};', + ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'min' => 0, + 'max' => 5, + ], + 'rem' => [ + 'min' => 0, + 'max' => 5, + ], + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + ] + ); + + $this->add_control( + 'icon_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'border-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view' => 'framed', + ], + ] + ); + + $this->add_control( + 'icon_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'title', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'description', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'heading_style_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-cta__title', + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-cta__title', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'title_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-cta__title', + ] + ); + + $this->add_responsive_control( + 'title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__title:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_control( + 'heading_style_description', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-cta__description', + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'description_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__description:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_control( + 'heading_content_colors', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Colors', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'color_tabs' ); + + $this->start_controls_tab( 'colors_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'content_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__content' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Title Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__title' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_control( + 'description_color', + [ + 'label' => esc_html__( 'Description Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__description' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_control( + 'button_color', + [ + 'label' => esc_html__( 'Button Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'color: {{VALUE}}; border-color: {{VALUE}}', + ], + 'condition' => [ + 'button!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'colors_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'content_bg_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:hover .elementor-cta__content' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'title_color_hover', + [ + 'label' => esc_html__( 'Title Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:hover .elementor-cta__title' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'title!' => '', + ], + ] + ); + + $this->add_control( + 'description_color_hover', + [ + 'label' => esc_html__( 'Description Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:hover .elementor-cta__description' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'description!' => '', + ], + ] + ); + + $this->add_control( + 'button_color_hover', + [ + 'label' => esc_html__( 'Button Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:hover .elementor-cta__button' => 'color: {{VALUE}}; border-color: {{VALUE}}', + ], + 'condition' => [ + 'button!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'button!' => '', + ], + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'default' => 'sm', + 'condition' => [ + 'button_size!' => 'sm', // a workaround to hide the control, unless it's in use (not default). + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .elementor-cta__button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'button_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-cta__button', + ] + ); + + $this->start_controls_tabs( 'button_tabs' ); + + $this->start_controls_tab( 'button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'button-hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button:hover' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'border-width: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'button_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-cta__button', + ] + ); + + $this->add_responsive_control( + 'button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_ribbon_style', + [ + 'label' => esc_html__( 'Ribbon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'show_label' => false, + 'condition' => [ + 'ribbon_title!' => '', + ], + ] + ); + + $this->add_control( + 'ribbon_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'ribbon_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'color: {{VALUE}}', + ], + ] + ); + + $ribbon_distance_transform = is_rtl() ? 'translateY(-50%) translateX({{SIZE}}{{UNIT}}) rotate(-45deg)' : 'translateY(-50%) translateX(-50%) translateX({{SIZE}}{{UNIT}}) rotate(-45deg)'; + + $this->add_responsive_control( + 'ribbon_distance', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'em' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'margin-top: {{SIZE}}{{UNIT}}; transform: ' . $ribbon_distance_transform, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'ribbon_typography', + 'selector' => '{{WRAPPER}} .elementor-ribbon-inner', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .elementor-ribbon-inner', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'hover_effects', + [ + 'label' => esc_html__( 'Hover Effects', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'content_hover_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'condition' => [ + 'skin' => 'cover', + ], + ] + ); + + $this->add_control( + 'content_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => [ + [ + 'label' => esc_html__( 'None', 'elementor-pro' ), + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + ], + ], + [ + 'label' => esc_html__( 'Entrance', 'elementor-pro' ), + 'options' => [ + 'enter-from-right' => 'Slide In Right', + 'enter-from-left' => 'Slide In Left', + 'enter-from-top' => 'Slide In Up', + 'enter-from-bottom' => 'Slide In Down', + 'enter-zoom-in' => 'Zoom In', + 'enter-zoom-out' => 'Zoom Out', + 'fade-in' => 'Fade In', + ], + ], + [ + 'label' => esc_html__( 'Reaction', 'elementor-pro' ), + 'options' => [ + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'move-right' => 'Move Right', + 'move-left' => 'Move Left', + 'move-up' => 'Move Up', + 'move-down' => 'Move Down', + ], + ], + [ + 'label' => esc_html__( 'Exit', 'elementor-pro' ), + 'options' => [ + 'exit-to-right' => 'Slide Out Right', + 'exit-to-left' => 'Slide Out Left', + 'exit-to-top' => 'Slide Out Up', + 'exit-to-bottom' => 'Slide Out Down', + 'exit-zoom-in' => 'Zoom In', + 'exit-zoom-out' => 'Zoom Out', + 'fade-out' => 'Fade Out', + ], + ], + ], + 'default' => 'grow', + 'condition' => [ + 'skin' => 'cover', + ], + ] + ); + + /* + * + * Add class 'elementor-animated-content' to widget when assigned content animation + * + */ + $this->add_control( + 'animation_class', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => 'animated-content', + 'prefix_class' => 'elementor-', + 'condition' => [ + 'content_animation!' => '', + ], + ] + ); + + $this->add_control( + 'content_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'render_type' => 'template', + 'default' => [ + 'size' => 1000, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__content-item' => 'transition-duration: {{SIZE}}ms', + '{{WRAPPER}}.elementor-cta--sequenced-animation .elementor-cta__content-item:nth-child(2)' => 'transition-delay: calc( {{SIZE}}ms / 3 )', + '{{WRAPPER}}.elementor-cta--sequenced-animation .elementor-cta__content-item:nth-child(3)' => 'transition-delay: calc( ( {{SIZE}}ms / 3 ) * 2 )', + '{{WRAPPER}}.elementor-cta--sequenced-animation .elementor-cta__content-item:nth-child(4)' => 'transition-delay: calc( ( {{SIZE}}ms / 3 ) * 3 )', + ], + 'condition' => [ + 'content_animation!' => '', + 'skin' => 'cover', + ], + ] + ); + + $this->add_control( + 'sequenced_animation', + [ + 'label' => esc_html__( 'Sequenced Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'return_value' => 'elementor-cta--sequenced-animation', + 'prefix_class' => '', + 'condition' => [ + 'content_animation!' => '', + 'skin' => 'cover', + ], + ] + ); + + $this->add_control( + 'background_hover_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'skin' => 'cover', + ], + ] + ); + + $this->add_control( + 'transformation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => 'None', + 'zoom-in' => 'Zoom In', + 'zoom-out' => 'Zoom Out', + 'move-left' => 'Move Left', + 'move-right' => 'Move Right', + 'move-up' => 'Move Up', + 'move-down' => 'Move Down', + ], + 'default' => 'zoom-in', + 'prefix_class' => 'elementor-bg-transform elementor-bg-transform-', + ] + ); + + $this->start_controls_tabs( 'bg_effects_tabs' ); + + $this->start_controls_tab( 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'overlay_color', + [ + 'label' => esc_html__( 'Overlay Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:not(:hover) .elementor-cta__bg-overlay' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'bg_filters', + 'selector' => '{{WRAPPER}} .elementor-cta__bg', + ] + ); + + $this->add_control( + 'overlay_blend_mode', + [ + 'label' => esc_html__( 'Blend Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'multiply' => 'Multiply', + 'screen' => 'Screen', + 'overlay' => 'Overlay', + 'darken' => 'Darken', + 'lighten' => 'Lighten', + 'color-dodge' => 'Color Dodge', + 'color-burn' => 'Color Burn', + 'hue' => 'Hue', + 'saturation' => 'Saturation', + 'color' => 'Color', + 'exclusion' => 'Exclusion', + 'luminosity' => 'Luminosity', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta__bg-overlay' => 'mix-blend-mode: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'overlay_color_hover', + [ + 'label' => esc_html__( 'Overlay Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-cta:hover .elementor-cta__bg-overlay' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'bg_filters_hover', + 'selector' => '{{WRAPPER}} .elementor-cta:hover .elementor-cta__bg', + ] + ); + + $this->add_control( + 'effect_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'render_type' => 'template', + 'default' => [ + 'size' => 1500, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-cta .elementor-cta__bg, {{WRAPPER}} .elementor-cta .elementor-cta__bg-overlay' => 'transition-duration: {{SIZE}}ms', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + $wrapper_tag = 'div'; + $button_tag = 'a'; + $title_tag = Utils::validate_html_tag( $settings['title_tag'] ); + $description_tag = Utils::validate_html_tag( $settings['description_tag'] ); + $bg_image = ''; + $content_animation = $settings['content_animation']; + $animation_class = ''; + $print_bg = true; + $print_content = true; + + if ( ! empty( $settings['bg_image']['id'] ) ) { + $bg_image = Group_Control_Image_Size::get_attachment_image_src( $settings['bg_image']['id'], 'bg_image', $settings ); + } elseif ( ! empty( $settings['bg_image']['url'] ) ) { + $bg_image = $settings['bg_image']['url']; + } + + if ( empty( $bg_image ) && 'classic' == $settings['skin'] ) { + $print_bg = false; + } + + if ( empty( $settings['title'] ) && empty( $settings['description'] ) && empty( $settings['button'] ) && 'none' == $settings['graphic_element'] ) { + $print_content = false; + } + + $this->add_render_attribute( 'wrapper', 'class', 'elementor-cta' ); + + /*$this->add_render_attribute( 'background_image', 'style', [ + 'background-image: url(' . $bg_image . ');', + ] );*/ + + $this->add_render_attribute( + 'background_image', + [ + 'style' => 'background-image: url(' . esc_url( $bg_image ) . ');', + 'role' => 'img', + 'aria-label' => Control_Media::get_image_alt( $settings['bg_image'] ), + ] + ); + + $this->add_render_attribute( 'title', 'class', [ + 'elementor-cta__title', + 'elementor-cta__content-item', + 'elementor-content-item', + ] ); + + $this->add_render_attribute( 'description', 'class', [ + 'elementor-cta__description', + 'elementor-cta__content-item', + 'elementor-content-item', + ] ); + + $this->add_render_attribute( 'button', 'class', [ + 'elementor-cta__button', + 'elementor-button', + 'elementor-size-' . $settings['button_size'], + ] ); + + $this->add_render_attribute( 'graphic_element', 'class', + [ + 'elementor-content-item', + 'elementor-cta__content-item', + ] + ); + + if ( 'icon' === $settings['graphic_element'] ) { + $this->add_render_attribute( 'graphic_element', 'class', + [ + 'elementor-icon-wrapper', + 'elementor-cta__icon', + ] + ); + $this->add_render_attribute( 'graphic_element', 'class', 'elementor-view-' . $settings['icon_view'] ); + if ( 'default' != $settings['icon_view'] ) { + $this->add_render_attribute( 'graphic_element', 'class', 'elementor-shape-' . $settings['icon_shape'] ); + } + + if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) { + // add old default + $settings['icon'] = 'fa fa-star'; + } + + if ( ! empty( $settings['icon'] ) ) { + $this->add_render_attribute( 'icon', 'class', $settings['icon'] ); + } + } elseif ( 'image' === $settings['graphic_element'] && ! empty( $settings['graphic_image']['url'] ) ) { + $this->add_render_attribute( 'graphic_element', 'class', 'elementor-cta__image' ); + } + + if ( ! empty( $content_animation ) && 'cover' == $settings['skin'] ) { + + $animation_class = 'elementor-animated-item--' . $content_animation; + + $this->add_render_attribute( 'title', 'class', $animation_class ); + + $this->add_render_attribute( 'graphic_element', 'class', $animation_class ); + + $this->add_render_attribute( 'description', 'class', $animation_class ); + + } + + if ( ! empty( $settings['link']['url'] ) ) { + $link_element = 'button'; + + if ( 'box' === $settings['link_click'] ) { + $wrapper_tag = 'a'; + $button_tag = 'span'; + $link_element = 'wrapper'; + } + + $this->add_link_attributes( $link_element, $settings['link'] ); + } + + $this->add_inline_editing_attributes( 'title' ); + $this->add_inline_editing_attributes( 'description' ); + $this->add_inline_editing_attributes( 'button' ); + + $migrated = isset( $settings['__fa4_migrated']['selected_icon'] ); + $is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed(); + + ?> + < print_render_attribute_string( 'wrapper' ); ?>> + +
      +
      print_render_attribute_string( 'background_image' ); ?>>
      +
      +
      + + +
      + +
      print_render_attribute_string( 'graphic_element' ); ?>> + +
      + +
      print_render_attribute_string( 'graphic_element' ); ?>> +
      + 'true' ] ); + else : ?> + print_render_attribute_string( 'icon' ); ?>> + +
      +
      + + + + < print_render_attribute_string( 'title' ); ?>> + + > + + + + < print_render_attribute_string( 'description' ); ?>> + + > + + + +
      + < print_render_attribute_string( 'button' ); ?>> + + > +
      + +
      + + add_render_attribute( 'ribbon-wrapper', 'class', 'elementor-ribbon' ); + + if ( ! empty( $settings['ribbon_horizontal_position'] ) ) : + $this->add_render_attribute( 'ribbon-wrapper', 'class', 'elementor-ribbon-' . $settings['ribbon_horizontal_position'] ); + endif; + + $this->add_render_attribute( 'ribbon_title', 'class', 'elementor-ribbon-inner' ); + $this->add_inline_editing_attributes( 'ribbon_title' ); + ?> +
      print_render_attribute_string( 'ribbon-wrapper' ); ?>> +
      print_render_attribute_string( 'ribbon_title' ); ?>> + +
      +
      + + > + + <# + var wrapperTag = 'div', + buttonTag = 'a', + titleTag = elementor.helpers.validateHTMLTag( settings.title_tag ), + descriptionTag = elementor.helpers.validateHTMLTag( settings.description_tag ), + contentAnimation = settings.content_animation, + animationClass, + btnSizeClass = 'elementor-size-' + settings.button_size, + printBg = true, + printContent = true, + iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ), + migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ); + + if ( 'box' === settings.link_click ) { + wrapperTag = 'a'; + buttonTag = 'span'; + view.addRenderAttribute( 'wrapper', 'href', '#' ); + } + + if ( '' !== settings.bg_image.url ) { + var bg_image = { + id: settings.bg_image.id, + url: settings.bg_image.url, + size: settings.bg_image_size, + dimension: settings.bg_image_custom_dimension, + model: view.getEditModel() + }; + + var bgImageUrl = elementor.imagesManager.getImageUrl( bg_image ); + } + + if ( ! bg_image && 'classic' == settings.skin ) { + printBg = false; + } + + if ( ! settings.title && ! settings.description && ! settings.button && 'none' == settings.graphic_element ) { + printContent = false; + } + + if ( 'icon' === settings.graphic_element ) { + var iconWrapperClasses = 'elementor-icon-wrapper'; + iconWrapperClasses += ' elementor-cta__image'; + iconWrapperClasses += ' elementor-view-' + settings.icon_view; + if ( 'default' !== settings.icon_view ) { + iconWrapperClasses += ' elementor-shape-' + settings.icon_shape; + } + view.addRenderAttribute( 'graphic_element', 'class', iconWrapperClasses ); + + } else if ( 'image' === settings.graphic_element && '' !== settings.graphic_image.url ) { + var image = { + id: settings.graphic_image.id, + url: settings.graphic_image.url, + size: settings.graphic_image_size, + dimension: settings.graphic_image_custom_dimension, + model: view.getEditModel() + }; + + var imageUrl = elementor.imagesManager.getImageUrl( image ); + view.addRenderAttribute( 'graphic_element', 'class', 'elementor-cta__image' ); + } + + if ( contentAnimation && 'cover' === settings.skin ) { + + var animationClass = 'elementor-animated-item--' + contentAnimation; + + view.addRenderAttribute( 'title', 'class', animationClass ); + + view.addRenderAttribute( 'description', 'class', animationClass ); + + view.addRenderAttribute( 'graphic_element', 'class', animationClass ); + } + + view.addRenderAttribute( + 'background_image', + { + 'style': 'background-image: url(' + bgImageUrl + ');', + 'role': 'img', + 'aria-label': '', + } + ); + + view.addRenderAttribute( 'title', 'class', [ 'elementor-cta__title', 'elementor-cta__content-item', 'elementor-content-item' ] ); + view.addRenderAttribute( 'description', 'class', [ 'elementor-cta__description', 'elementor-cta__content-item', 'elementor-content-item' ] ); + view.addRenderAttribute( 'button', 'class', [ 'elementor-cta__button', 'elementor-button', btnSizeClass ] ); + view.addRenderAttribute( 'graphic_element', 'class', [ 'elementor-cta__content-item', 'elementor-content-item' ] ); + + view.addInlineEditingAttributes( 'title' ); + view.addInlineEditingAttributes( 'description' ); + view.addInlineEditingAttributes( 'button' ); + #> + + <{{ wrapperTag }} class="elementor-cta" {{{ view.getRenderAttributeString( 'wrapper' ) }}}> + + <# if ( printBg ) { #> +
      +
      +
      +
      + <# } #> + <# if ( printContent ) { #> +
      + <# if ( 'image' === settings.graphic_element && '' !== settings.graphic_image.url ) { #> +
      + +
      + <# } else if ( 'icon' === settings.graphic_element && ( settings.icon || settings.selected_icon ) ) { #> +
      +
      + <# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #> + {{{ iconHTML.value }}} + <# } else { #> + + <# } #> +
      +
      + <# } #> + <# if ( settings.title ) { #> + <{{ titleTag }} {{{ view.getRenderAttributeString( 'title' ) }}}>{{ settings.title }} + <# } #> + + <# if ( settings.description ) { #> + <{{ descriptionTag }} {{{ view.getRenderAttributeString( 'description' ) }}}>{{ settings.description }} + <# } #> + + <# if ( settings.button ) { #> +
      + <{{ buttonTag }} href="#" {{{ view.getRenderAttributeString( 'button' ) }}}>{{ settings.button }} +
      + <# } #> +
      + <# } #> + <# if ( settings.ribbon_title ) { + view.addRenderAttribute( 'ribbon', 'class', 'elementor-ribbon' ); + + if ( settings.ribbon_horizontal_position ) { + view.addRenderAttribute( 'ribbon', 'class', 'elementor-ribbon-' + settings.ribbon_horizontal_position ); + } + + view.addRenderAttribute( 'ribbon_title', 'class', 'elementor-ribbon-inner' ); + view.addInlineEditingAttributes( 'ribbon_title' ); + #> +
      +
      {{ settings.ribbon_title }}
      +
      + <# } #> + + get_widgets_style_list(); + $direction_suffix = is_rtl() ? '-rtl' : ''; + $has_custom_breakpoints = Plugin::elementor()->breakpoints->has_custom_breakpoints(); + + foreach ( $widgets as $widget_style_name => $widget_has_responsive_style ) { + $should_load_responsive_css = $widget_has_responsive_style ? $has_custom_breakpoints : false; + + wp_register_style( + $widget_style_name, + Plugin::get_frontend_file_url( "{$widget_style_name}{$direction_suffix}.min.css", $should_load_responsive_css ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + } + + private function get_widgets_style_list(): array { + return [ + 'widget-media-carousel' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-testimonial-carousel' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-reviews' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-carousel-module-base' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + ]; + } +} diff --git a/modules/carousel/widgets/base.php b/modules/carousel/widgets/base.php new file mode 100644 index 00000000..f04bbc01 --- /dev/null +++ b/modules/carousel/widgets/base.php @@ -0,0 +1,669 @@ +start_controls_section( + 'section_slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'slides_name', + [ + 'label' => esc_html__( 'Slides Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Slides', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $this->add_repeater_controls( $repeater ); + + $this->add_control( + 'slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => $this->get_repeater_defaults(), + 'separator' => 'after', + ] + ); + + $this->add_control( + 'effect', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Effect', 'elementor-pro' ), + 'default' => 'slide', + 'options' => [ + 'slide' => esc_html__( 'Slide', 'elementor-pro' ), + 'fade' => esc_html__( 'Fade', 'elementor-pro' ), + 'cube' => esc_html__( 'Cube', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $slides_per_view = range( 1, 10 ); + $slides_per_view = array_combine( $slides_per_view, $slides_per_view ); + + $this->add_responsive_control( + 'slides_per_view', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Slides Per View', 'elementor-pro' ), + 'options' => [ '' => esc_html__( 'Default', 'elementor-pro' ) ] + $slides_per_view, + 'inherit_placeholders' => false, + 'condition' => [ + 'effect' => 'slide', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'slides_to_scroll', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Slides to Scroll', 'elementor-pro' ), + 'description' => esc_html__( 'Set how many slides are scrolled per swipe.', 'elementor-pro' ), + 'options' => [ '' => esc_html__( 'Default', 'elementor-pro' ) ] + $slides_per_view, + 'inherit_placeholders' => false, + 'condition' => [ + 'effect' => 'slide', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'height', + [ + 'type' => Controls_Manager::SLIDER, + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'em' => [ + 'min' => 10, + 'max' => 100, + ], + 'rem' => [ + 'min' => 10, + 'max' => 100, + ], + 'vh' => [ + 'min' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'width', + [ + 'type' => Controls_Manager::SLIDER, + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1140, + ], + '%' => [ + 'min' => 50, + ], + ], + 'default' => [ + 'unit' => '%', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_arrows', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Arrows', 'elementor-pro' ), + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'prefix_class' => 'elementor-arrows-', + 'render_type' => 'template', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pagination', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'bullets', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'bullets' => esc_html__( 'Dots', 'elementor-pro' ), + 'fraction' => esc_html__( 'Fraction', 'elementor-pro' ), + 'progressbar' => esc_html__( 'Progress', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-pagination-type-', + 'render_type' => 'template', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'speed', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 500, + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay', + [ + 'label' => esc_html__( 'Autoplay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'separator' => 'before', + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay_speed', + [ + 'label' => esc_html__( 'Autoplay Speed', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5000, + 'condition' => [ + 'autoplay' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'loop', + [ + 'label' => esc_html__( 'Infinite Loop', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pause_on_hover', + [ + 'label' => esc_html__( 'Pause on Hover', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'autoplay' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pause_on_interaction', + [ + 'label' => esc_html__( 'Pause on Interaction', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'autoplay' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'image_size', + 'default' => 'full', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'lazyload', + [ + 'label' => esc_html__( 'Lazy Load', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_slides_style', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $space_between_config = [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 50, + ], + ], + 'render_type' => 'none', + 'frontend_available' => true, + ]; + + // TODO: Once Core 3.4.0 is out, get the active devices using Breakpoints/Manager::get_active_devices_list(). + $active_breakpoint_instances = Plugin::elementor()->breakpoints->get_active_breakpoints(); + // Devices need to be ordered from largest to smallest. + $active_devices = array_reverse( array_keys( $active_breakpoint_instances ) ); + + // Add desktop in the correct position. + if ( in_array( 'widescreen', $active_devices, true ) ) { + $active_devices = array_merge( array_slice( $active_devices, 0, 1 ), [ 'desktop' ], array_slice( $active_devices, 1 ) ); + } else { + $active_devices = array_merge( [ 'desktop' ], $active_devices ); + } + + foreach ( $active_devices as $active_device ) { + $space_between_config[ $active_device . '_default' ] = [ + 'size' => 10, + ]; + } + + $this->add_responsive_control( + 'space_between', + $space_between_config + ); + + $this->add_control( + 'slide_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper .swiper-slide' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'slide_border_size', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper .swiper-slide' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'slide_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + '%' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper .swiper-slide' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'slide_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper .swiper-slide' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'slide_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper .swiper-slide' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_navigation', + [ + 'label' => esc_html__( 'Navigation', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_arrows', + [ + 'label' => esc_html__( 'Arrows', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_responsive_control( + 'arrows_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-swiper-button' => 'font-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'arrows_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-swiper-button' => 'color: {{VALUE}}', + '{{WRAPPER}} .elementor-swiper-button svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_pagination', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'pagination!' => '', + ], + ] + ); + + $this->add_control( + 'pagination_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'outside', + 'options' => [ + 'outside' => esc_html__( 'Outside', 'elementor-pro' ), + 'inside' => esc_html__( 'Inside', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-pagination-position-', + 'condition' => [ + 'pagination!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'pagination_gap', + [ + 'label' => esc_html__( 'Space Between Dots', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet' => '--swiper-pagination-bullet-horizontal-gap: {{SIZE}}{{UNIT}}; --swiper-pagination-bullet-vertical-gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'pagination' => 'bullets', + ], + ] + ); + + $this->add_responsive_control( + 'pagination_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet' => 'height: {{SIZE}}{{UNIT}}; width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .swiper-horizontal .swiper-pagination-progressbar' => 'height: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'pagination!' => '', + ], + ] + ); + + $this->add_control( + 'pagination_color_inactive', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + // The opacity property will override the default inactive dot color which is opacity 0.2. + '{{WRAPPER}} .swiper-pagination-bullet:not(.swiper-pagination-bullet-active)' => 'background-color: {{VALUE}}; opacity: 1;', + ], + 'condition' => [ + 'pagination!' => '', + ], + ] + ); + + $this->add_control( + 'pagination_color', + [ + 'label' => esc_html__( 'Active Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet-active, {{WRAPPER}} .swiper-pagination-progressbar-fill' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .swiper-pagination-fraction' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'pagination!' => '', + ], + 'control_type' => 'content', + ] + ); + + $this->end_controls_section(); + } + + protected function print_slider( ?array $settings = null ) { + if ( null === $settings ) { + $settings = $this->get_settings_for_display(); + } + + $default_settings = [ + 'container_class' => 'elementor-main-swiper', + 'video_play_icon' => true, + ]; + + $settings = array_merge( $default_settings, $settings ); + + $slides_count = count( $settings['slides'] ); + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + + $this->add_render_attribute( [ + 'wrapper' => [ + 'class' => [ $settings['container_class'], 'swiper' ], + 'role' => 'region', + 'aria-roledescription' => 'carousel', + 'aria-label' => $settings['slides_name'], + ], + ] ); + ?> + +
      + +
      print_render_attribute_string( 'wrapper' ); ?>> +
      + $slide ) : + $this->slide_prints_count++; + ?> +
      + print_slide( $slide, $settings, 'slide-' . $index . '-' . $this->slide_prints_count ); ?> +
      + +
      + + +
      + render_swiper_button( 'previous' ); ?> +
      +
      + render_swiper_button( 'next' ); ?> +
      + + +
      + + +
      + +
      + + 'eicons', + 'value' => $icon_value, + ], [ 'aria-hidden' => 'true' ] ); + } +} diff --git a/modules/carousel/widgets/media-carousel.php b/modules/carousel/widgets/media-carousel.php new file mode 100644 index 00000000..f28d418e --- /dev/null +++ b/modules/carousel/widgets/media-carousel.php @@ -0,0 +1,865 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'e-swiper', 'widget-media-carousel', 'widget-carousel-module-base' ]; + } + + /** + * Get script dependencies. + * + * Retrieve the list of script dependencies the widget requires. + * + * @since 3.27.0 + * @access public + * + * @return array Widget script dependencies. + */ + public function get_script_depends(): array { + return [ 'swiper' ]; + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( $settings['overlay'] ) { + $this->add_render_attribute( 'image-overlay', 'class', [ + 'elementor-carousel-image-overlay', + 'e-overlay-animation-' . $settings['overlay_animation'], + ] ); + } + + $this->print_slider(); + + if ( 'slideshow' !== $settings['skin'] || count( $settings['slides'] ) <= 1 ) { + return; + } + + $settings['thumbs_slider'] = true; + $settings['container_class'] = 'elementor-thumbnails-swiper'; + $settings['show_arrows'] = false; + + $this->print_slider( $settings ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->start_controls_section( + 'section_lightbox_style', + [ + 'label' => esc_html__( 'Lightbox', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'lightbox_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '#elementor-lightbox-slideshow-{{ID}}' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'lightbox_ui_color', + [ + 'label' => esc_html__( 'UI Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '#elementor-lightbox-slideshow-{{ID}} .dialog-lightbox-close-button, #elementor-lightbox-slideshow-{{ID}} .elementor-swiper-button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'lightbox_ui_hover_color', + [ + 'label' => esc_html__( 'UI Hover Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '#elementor-lightbox-slideshow-{{ID}} .dialog-lightbox-close-button:hover, #elementor-lightbox-slideshow-{{ID}} .elementor-swiper-button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'lightbox_video_width', + [ + 'label' => esc_html__( 'Video Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 50, + ], + ], + 'selectors' => [ + '#elementor-lightbox-slideshow-{{ID}} .elementor-video-container' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->add_injections(); + + $this->update_controls(); + } + + protected function add_repeater_controls( Repeater $repeater ) { + $repeater->add_control( + 'type', + [ + 'type' => Controls_Manager::CHOOSE, + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'default' => 'image', + 'options' => [ + 'image' => [ + 'title' => esc_html__( 'Image', 'elementor-pro' ), + 'icon' => 'eicon-image-bold', + ], + 'video' => [ + 'title' => esc_html__( 'Video', 'elementor-pro' ), + 'icon' => 'eicon-video-camera', + ], + ], + 'toggle' => false, + ] + ); + + $repeater->add_control( + 'image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'image_link_to_type', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'file' => esc_html__( 'Media File', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom URL', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => 'image', + ], + ] + ); + + $repeater->add_control( + 'image_link_to', + [ + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'show_external' => 'true', + 'condition' => [ + 'type' => 'image', + 'image_link_to_type' => 'custom', + ], + 'show_label' => false, + ] + ); + + $repeater->add_control( + 'video', + [ + 'label' => esc_html__( 'Video Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Enter your video link', 'elementor-pro' ), + 'description' => esc_html__( 'YouTube or Vimeo link', 'elementor-pro' ), + 'options' => false, + 'condition' => [ + 'type' => 'video', + ], + ] + ); + } + + protected function get_default_slides_count() { + return 5; + } + + protected function get_repeater_defaults() { + $placeholder_image_src = Utils::get_placeholder_image_src(); + + return array_fill( 0, $this->get_default_slides_count(), [ + 'image' => [ + 'url' => $placeholder_image_src, + ], + ] ); + } + + protected function get_image_caption( $slide ) { + $caption_type = $this->get_settings( 'caption' ); + + if ( empty( $caption_type ) ) { + return ''; + } + + $attachment_post = get_post( $slide['image']['id'] ); + + if ( ProUtils::has_invalid_post_permissions( $attachment_post ) ) { + return ''; + } + + if ( 'caption' === $caption_type ) { + return $attachment_post->post_excerpt; + } + + if ( 'title' === $caption_type ) { + return $attachment_post->post_title; + } + + return $attachment_post->post_content; + } + + protected function get_image_link_to( $slide ) { + if ( ! empty( $slide['video']['url'] ) ) { + return $slide['image']['url'] ? $slide['image']['url'] : '#'; + } + + if ( ! $slide['image_link_to_type'] ) { + return ''; + } + + if ( 'custom' === $slide['image_link_to_type'] ) { + return $slide['image_link_to']['url']; + } + + return $slide['image']['url']; + } + + protected function print_slider( ?array $settings = null ) { + $this->lightbox_slide_index = 0; + + parent::print_slider( $settings ); + } + + protected function print_slide( array $slide, array $settings, $element_key ) { + if ( ! empty( $settings['thumbs_slider'] ) ) { + $settings['video_play_icon'] = false; + } + + $this->add_render_attribute( $element_key . '-image', [ + 'class' => 'elementor-carousel-image', + 'role' => 'img', + 'aria-label' => Control_Media::get_image_alt( $slide['image'] ), + ] ); + + $img_src = $this->get_slide_image_url( $slide, $settings ); + + if ( 'yes' === $settings['lazyload'] ) { + $img_attribute['class'] = 'swiper-lazy'; + $img_attribute['data-background'] = $img_src; + } else { + $img_attribute['style'] = "background-image: url('" . $img_src . "')"; + } + + $this->add_render_attribute( $element_key . '-image', $img_attribute ); + + $image_link_to = $this->get_image_link_to( $slide ); + + if ( $image_link_to && empty( $settings['thumbs_slider'] ) ) { + if ( 'custom' === $slide['image_link_to_type'] ) { + $this->add_link_attributes( $element_key . '_link', $slide['image_link_to'] ); + } else { + $this->add_render_attribute( $element_key . '_link', 'href', esc_url( $image_link_to ) ); + + $this->add_lightbox_data_attributes( $element_key . '_link', $slide['image']['id'], 'yes', $this->get_id() ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + $this->add_render_attribute( $element_key . '_link', 'class', 'elementor-clickable' ); + } + + $this->lightbox_slide_index++; + } + + if ( 'video' === $slide['type'] && $slide['video']['url'] ) { + $embed_url_params = [ + 'autoplay' => 1, + 'rel' => 0, + 'controls' => 0, + ]; + + $this->add_render_attribute( $element_key . '_link', 'data-elementor-lightbox-video', Embed::get_embed_url( $slide['video']['url'], $embed_url_params ) ); + } + + // PHPCS - the method get_render_attribute_string is safe. + echo 'get_render_attribute_string( $element_key . '_link' ) . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + $this->print_slide_image( $slide, $element_key, $settings ); + + if ( $image_link_to ) { + echo ''; + } + } + + protected function print_slide_image( array $slide, $element_key, array $settings ) { + ?> +
      print_render_attribute_string( $element_key . '-image' ); ?>> + + +
      + + + +
      + 'eicons', + 'value' => 'eicon-play', + ], [ 'aria-hidden' => 'true' ] ); + ?> + +
      + +
      + +
      print_render_attribute_string( 'image-overlay' ); ?>> + get_image_caption( $slide ) ); + } else { + $this->render_overlay_icon( $settings['icon'] ); + } + ?> +
      + start_injection( [ + 'type' => 'section', + 'at' => 'start', + 'of' => 'section_slides', + ] ); + + $this->add_control( + 'skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'carousel', + 'options' => [ + 'carousel' => esc_html__( 'Carousel', 'elementor-pro' ), + 'slideshow' => esc_html__( 'Slideshow', 'elementor-pro' ), + 'coverflow' => esc_html__( 'Coverflow', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-skin-', + 'render_type' => 'template', + 'frontend_available' => true, + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'of' => 'image_size_custom_dimension', + ] ); + + $this->add_control( + 'image_fit', + [ + 'label' => esc_html__( 'Image Fit', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Cover', 'elementor-pro' ), + 'contain' => esc_html__( 'Contain', 'elementor-pro' ), + 'auto' => esc_html__( 'Auto', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper:not(.elementor-thumbnails-swiper) .elementor-carousel-image' => 'background-size: {{VALUE}}', + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'of' => 'pagination_color', + ] ); + + $this->add_control( + 'play_icon_title', + [ + 'label' => esc_html__( 'Play Icon', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'play_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-custom-embed-play i' => 'color: {{VALUE}}', + '{{WRAPPER}} .elementor-custom-embed-play svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'play_icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 20, + 'max' => 150, + ], + 'em' => [ + 'min' => 2, + 'max' => 15, + ], + 'rem' => [ + 'min' => 2, + 'max' => 15, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-custom-embed-play i' => 'font-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'play_icon_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-custom-embed-play i', + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html__( 'Shadow', 'elementor-pro' ), + ], + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'of' => 'pause_on_interaction', + ] ); + + $this->add_control( + 'overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + 'icon' => esc_html__( 'Icon', 'elementor-pro' ), + ], + 'condition' => [ + 'skin!' => 'slideshow', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'caption', + [ + 'label' => esc_html__( 'Caption', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'title', + 'options' => [ + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'caption' => esc_html__( 'Caption', 'elementor-pro' ), + 'description' => esc_html__( 'Description', 'elementor-pro' ), + ], + 'condition' => [ + 'skin!' => 'slideshow', + 'overlay' => 'text', + ], + ] + ); + + $this->add_control( + 'icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'search-plus', + 'options' => [ + 'search-plus' => [ + 'icon' => 'eicon-search-bold', + ], + 'plus-circle' => [ + 'icon' => 'eicon-plus-circle', + ], + 'eye' => [ + 'icon' => 'eicon-preview-medium', + ], + 'link' => [ + 'icon' => 'eicon-link', + ], + ], + 'condition' => [ + 'skin!' => 'slideshow', + 'overlay' => 'icon', + ], + ] + ); + + $this->add_control( + 'overlay_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'slide-up' => 'Slide Up', + 'slide-down' => 'Slide Down', + 'slide-right' => 'Slide Right', + 'slide-left' => 'Slide Left', + 'zoom-in' => 'Zoom In', + ], + 'condition' => [ + 'skin!' => 'slideshow', + 'overlay!' => '', + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'type' => 'section', + 'of' => 'section_navigation', + ] ); + + $this->start_controls_section( + 'section_overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'skin!' => 'slideshow', + 'overlay!' => '', + ], + ] + ); + + $this->add_control( + 'overlay_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-carousel-image-overlay' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'overlay_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-carousel-image-overlay' => '--e-carousel-image-overlay-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'caption_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-carousel-image-overlay', + 'condition' => [ + 'overlay' => 'text', + ], + ] + ); + + $this->add_control( + 'icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-carousel-image-overlay' => '--e-carousel-image-overlay-icon-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'overlay' => 'icon', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + + // Slideshow + + $this->start_injection( [ + 'of' => 'effect', + ] ); + + $this->add_responsive_control( + 'slideshow_height', + [ + 'type' => Controls_Manager::SLIDER, + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 20, + 'max' => 1000, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-main-swiper:not(.elementor-thumbnails-swiper)' => 'height: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'skin' => 'slideshow', + ], + ] + ); + + $this->add_control( + 'thumbs_title', + [ + 'label' => esc_html__( 'Thumbnails', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'skin' => 'slideshow', + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'of' => 'slides_per_view', + ] ); + + $this->add_control( + 'thumbs_ratio', + [ + 'label' => esc_html__( 'Ratio', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '169' => '16:9', + '219' => '21:9', + '43' => '4:3', + '11' => '1:1', + ], + 'selectors_dictionary' => [ + '169' => '16 / 9', + '219' => '21 / 9', + '43' => '4 / 3', + '11' => '1 / 1', + ], + 'default' => '219', + 'condition' => [ + 'skin' => 'slideshow', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-thumbnails-swiper .elementor-carousel-image' => 'aspect-ratio: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'centered_slides', + [ + 'label' => esc_html__( 'Centered Slides', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'skin' => 'slideshow', + ], + 'frontend_available' => true, + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'of' => 'slides_per_view', + ] ); + + $slides_per_view = range( 1, 10 ); + + $slides_per_view = array_combine( $slides_per_view, $slides_per_view ); + + $this->add_responsive_control( + 'slideshow_slides_per_view', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Slides Per View', 'elementor-pro' ), + 'options' => [ '' => esc_html__( 'Default', 'elementor-pro' ) ] + $slides_per_view, + 'condition' => [ + 'skin' => 'slideshow', + ], + 'frontend_available' => true, + ] + ); + + $this->end_injection(); + } + + private function update_controls() { + $carousel_controls = [ + 'slides_to_scroll', + 'pagination', + 'heading_pagination', + 'pagination_gap', + 'pagination_size', + 'pagination_position', + 'pagination_color', + ]; + + $carousel_responsive_controls = [ + 'width', + 'height', + 'slides_per_view', + ]; + + foreach ( $carousel_controls as $control_id ) { + $this->update_control( + $control_id, + [ + 'condition' => [ + 'skin!' => 'slideshow', + ], + ], + [ 'recursive' => true ] + ); + } + + foreach ( $carousel_responsive_controls as $control_id ) { + $this->update_responsive_control( + $control_id, + [ + 'condition' => [ + 'skin!' => 'slideshow', + ], + ], + [ 'recursive' => true ] + ); + } + + $this->update_responsive_control( + 'space_between', + [ + 'selectors' => [ + '{{WRAPPER}}.elementor-skin-slideshow .elementor-main-swiper:not(.elementor-thumbnails-swiper)' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'render_type' => 'ui', + ] + ); + + $this->update_control( + 'effect', + [ + 'condition' => [ + 'skin!' => 'coverflow', + ], + ] + ); + } + + public function get_group_name() { + return 'carousel'; + } + + private function render_overlay_icon( $icon_name ) { + $icon_value = 'fas fa-' . $icon_name; + + $icon = [ + 'library' => 'fa-solid', + 'value' => $icon_value, + ]; + + Icons_Manager::render_icon( $icon ); + } +} diff --git a/modules/carousel/widgets/reviews.php b/modules/carousel/widgets/reviews.php new file mode 100644 index 00000000..fe98ac4b --- /dev/null +++ b/modules/carousel/widgets/reviews.php @@ -0,0 +1,921 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'e-swiper', 'widget-testimonial-carousel', 'widget-reviews', 'widget-star-rating', 'widget-carousel-module-base' ]; + } + + /** + * Get script dependencies. + * + * Retrieve the list of script dependencies the widget requires. + * + * @since 3.27.0 + * @access public + * + * @return array Widget script dependencies. + */ + public function get_script_depends(): array { + return [ 'swiper' ]; + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'slide_padding', + [ + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__header' => 'padding-top: {{TOP}}{{UNIT}}; padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .elementor-testimonial__content' => 'padding-bottom: {{BOTTOM}}{{UNIT}}; padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};', + ], + ] + ); + + $this->start_injection( [ + 'of' => 'slide_padding', + ] ); + + $this->add_control( + 'heading_header', + [ + 'label' => esc_html__( 'Header', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'header_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__header' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'content_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__header' => 'padding-block-end: calc( {{SIZE}}{{UNIT}} / 2 )', + '{{WRAPPER}} .elementor-testimonial__content' => 'padding-block-start: calc( {{SIZE}}{{UNIT}} / 2 )', + ], + ] + ); + + $this->add_control( + 'show_separator', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'has-separator', + 'return_value' => 'has-separator', + 'prefix_class' => 'elementor-review--', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'separator_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__header' => 'border-block-end-color: {{VALUE}}', + ], + 'condition' => [ + 'show_separator!' => '', + ], + ] + ); + + $this->add_control( + 'separator_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'condition' => [ + 'show_separator!' => '', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__header' => 'border-block-end-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'section_navigation', + ] ); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'name_title_style', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'name_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__name' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'name_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__header, {{WRAPPER}} .elementor-testimonial__name', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_control( + 'heading_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__title' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__title', + ] + ); + + $this->add_control( + 'heading_review_style', + [ + 'label' => esc_html__( 'Review', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'content_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__text' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__text', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'image_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'image_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image + cite' => 'margin-inline-start: {{SIZE}}{{UNIT}}; margin-inline-end: 0;', + ], + ] + ); + + $this->add_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_icon_style', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'default', + 'options' => [ + 'default' => esc_html__( 'Official', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'icon_custom_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + 'icon_color' => 'custom', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__icon:not(.elementor-testimonial__rating)' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-testimonial__icon:not(.elementor-testimonial__rating) svg' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__icon' => 'font-size: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-testimonial__icon svg' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_rating_style', + [ + 'label' => esc_html__( 'Rating', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'star_style', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'star_fontawesome' => 'Font Awesome', + 'star_unicode' => 'Unicode', + ], + 'default' => 'star_fontawesome', + 'render_type' => 'template', + 'prefix_class' => 'elementor--star-style-', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'unmarked_star_style', + [ + 'label' => esc_html__( 'Unmarked Style', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'solid' => [ + 'title' => esc_html__( 'Solid', 'elementor-pro' ), + 'icon' => 'eicon-star', + ], + 'outline' => [ + 'title' => esc_html__( 'Outline', 'elementor-pro' ), + 'icon' => 'eicon-star-o', + ], + ], + 'default' => 'solid', + ] + ); + + $this->add_control( + 'star_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-star-rating' => 'font-size: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'star_space', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-star-rating i:not(:last-of-type)' => 'margin-inline-end: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'stars_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-star-rating i:before' => 'color: {{VALUE}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'stars_unmarked_color', + [ + 'label' => esc_html__( 'Unmarked Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-star-rating i' => 'color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + + $this->update_responsive_control( + 'width', + [ + 'selectors' => [ + '{{WRAPPER}}.elementor-arrows-yes .elementor-main-swiper' => 'width: calc( {{SIZE}}{{UNIT}} - 40px )', + '{{WRAPPER}} .elementor-main-swiper' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->update_responsive_control( + 'slides_per_view', + [ + 'condition' => null, + ] + ); + + $this->update_control( + 'slides_to_scroll', + [ + 'condition' => null, + ] + ); + + $this->remove_control( 'effect' ); + $this->remove_responsive_control( 'height' ); + $this->remove_control( 'pagination_position' ); + } + + protected function add_repeater_controls( Repeater $repeater ) { + $repeater->add_control( + 'image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'name', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'John Doe', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '@username', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'rating', + [ + 'label' => esc_html__( 'Rating', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 0, + 'max' => 5, + 'step' => 0.1, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'selected_social_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'social_icon', + 'default' => [ + 'value' => 'fab fa-twitter', + 'library' => 'fa-brands', + ], + 'recommended' => [ + 'fa-solid' => [ + 'rss', + 'shopping-cart', + 'thumbtack', + ], + 'fa-brands' => [ + 'android', + 'apple', + 'behance', + 'bitbucket', + 'codepen', + 'delicious', + 'digg', + 'dribbble', + 'envelope', + 'facebook', + 'flickr', + 'foursquare', + 'github', + 'google-plus', + 'houzz', + 'instagram', + 'jsfiddle', + 'linkedin', + 'medium', + 'meetup', + 'mix', + 'mixcloud', + 'odnoklassniki', + 'pinterest', + 'product-hunt', + 'reddit', + 'skype', + 'slideshare', + 'snapchat', + 'soundcloud', + 'spotify', + 'stack-overflow', + 'steam', + 'telegram', + 'threads', + 'tripadvisor', + 'tumblr', + 'twitch', + 'twitter', + 'vimeo', + 'fa-vk', + 'weibo', + 'weixin', + 'whatsapp', + 'wordpress', + 'x-twitter', + 'xing', + 'yelp', + 'youtube', + '500px', + ], + ], + ] + ); + + $repeater->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'content', + [ + 'label' => esc_html__( 'Review', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + } + + protected function get_repeater_defaults() { + $placeholder_image_src = Utils::get_placeholder_image_src(); + + return [ + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => '@username', + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => '@username', + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => '@username', + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + ]; + } + + private function print_cite( $slide, $settings ) { + if ( empty( $slide['name'] ) && empty( $slide['title'] ) ) { + return ''; + } + + $html = ''; + + if ( ! empty( $slide['name'] ) ) { + $html .= '' . $slide['name'] . ''; + } + + if ( ! empty( $slide['rating'] ) ) { + $html .= $this->render_stars( $slide, $settings ); + } + + if ( ! empty( $slide['title'] ) ) { + $html .= '' . $slide['title'] . ''; + } + $html .= ''; + + echo wp_kses_post( $html ); + } + + protected function render_stars( $slide, $settings ) { + $icon = ''; + + if ( 'star_fontawesome' === $settings['star_style'] ) { + if ( 'outline' === $settings['unmarked_star_style'] ) { + $icon = ''; + } + } elseif ( 'star_unicode' === $settings['star_style'] ) { + $icon = '★'; + + if ( 'outline' === $settings['unmarked_star_style'] ) { + $icon = '☆'; + } + } + + $rating = (float) $slide['rating'] > 5 ? 5 : $slide['rating']; + $floored_rating = (int) $rating; + $stars_html = ''; + + for ( $stars = 1; $stars <= 5; $stars++ ) { + if ( $stars <= $floored_rating ) { + $stars_html .= '' . $icon . ''; + } elseif ( $floored_rating + 1 === $stars && $rating !== $floored_rating ) { + $stars_html .= '' . $icon . ''; + } else { + $stars_html .= '' . $icon . ''; + } + } + + return '
      ' . $stars_html . '
      '; + } + + private function print_icon( $slide, $element_key ) { + $migration_allowed = Icons_Manager::is_migration_allowed(); + if ( ! isset( $slide['social_icon'] ) && ! $migration_allowed ) { + // add old default + $slide['social_icon'] = 'fa fa-twitter'; + } + + if ( empty( $slide['social_icon'] ) && empty( $slide['selected_social_icon'] ) ) { + return ''; + } + + $migrated = isset( $slide['__fa4_migrated']['selected_social_icon'] ); + $is_new = empty( $slide['social_icon'] ) && $migration_allowed; + $social = ''; + + if ( $is_new || $migrated ) { + ob_start(); + Icons_Manager::render_icon( $slide['selected_social_icon'], [ 'aria-hidden' => 'true' ] ); + $icon = ob_get_clean(); + } else { + $icon = ''; + } + + if ( ! empty( $slide['social_icon'] ) ) { + $social = str_replace( 'fa fa-', '', $slide['social_icon'] ); + } + + if ( ( $is_new || $migrated ) && 'svg' !== $slide['selected_social_icon']['library'] ) { + $social = explode( ' ', $slide['selected_social_icon']['value'], 2 ); + if ( empty( $social[1] ) ) { + $social = ''; + } else { + $social = str_replace( 'fa-', '', $social[1] ); + } + } + if ( 'svg' === $slide['selected_social_icon']['library'] ) { + $social = ''; + } + + $this->add_render_attribute( 'icon_wrapper_' . $element_key, 'class', 'elementor-testimonial__icon elementor-icon' ); + $this->add_render_attribute( 'icon_wrapper_' . $element_key, 'class', 'elementor-icon-' . $social ); + $this->add_render_attribute( 'icon_wrapper_' . $element_key, 'aria-label', esc_attr__( 'Read More', 'elementor-pro' ) ); + + // Icon is escaped above, get_render_attribute_string() is safe + echo '
      get_render_attribute_string( 'icon_wrapper_' . $element_key ) . '>' . $icon . '
      '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + protected function print_slide( array $slide, array $settings, $element_key ) { + $lazyload = 'yes' === $this->get_settings( 'lazyload' ); + + $this->add_render_attribute( $element_key . '-testimonial', [ + 'class' => 'elementor-testimonial', + ] ); + + $this->add_render_attribute( $element_key . '-testimonial', [ + 'class' => 'elementor-repeater-item-' . $slide['_id'], + ] ); + + if ( ! empty( $slide['image']['url'] ) ) { + $img_src = $this->get_slide_image_url( $slide, $settings ); + + if ( $lazyload ) { + $img_attribute['class'] = 'swiper-lazy'; + $img_attribute['data-src'] = $img_src; + } else { + $img_attribute['src'] = $img_src; + } + + $img_attribute['alt'] = $this->get_slide_image_alt_attribute( $slide ); + + $this->add_render_attribute( $element_key . '-image', $img_attribute ); + } + + ?> +
      print_render_attribute_string( $element_key . '-testimonial' ); ?>> + add_render_attribute( $header_element, 'class', 'elementor-testimonial__header' ); + + if ( ! empty( $link_url ) ) { + $this->add_link_attributes( $header_element, $slide['link'] ); + } + ?> + < print_render_attribute_string( $header_element ); ?>> + +
      + print_render_attribute_string( $element_key . '-image' ); ?>> + +
      + +
      + + print_cite( $slide, $settings ); ?> + print_icon( $slide, $element_key ); ?> + > + + +
      +
      + +
      +
      + +
      + print_slider(); + } + + public function get_group_name() { + return 'carousel'; + } +} diff --git a/modules/carousel/widgets/testimonial-carousel.php b/modules/carousel/widgets/testimonial-carousel.php new file mode 100644 index 00000000..cf839184 --- /dev/null +++ b/modules/carousel/widgets/testimonial-carousel.php @@ -0,0 +1,752 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'e-swiper', 'widget-testimonial-carousel', 'widget-carousel-module-base' ]; + } + + /** + * Get script dependencies. + * + * Retrieve the list of script dependencies the widget requires. + * + * @since 3.27.0 + * @access public + * + * @return array Widget script dependencies. + */ + public function get_script_depends(): array { + return [ 'swiper' ]; + } + + protected function register_controls() { + parent::register_controls(); + + $this->start_injection( [ + 'of' => 'slides', + ] ); + + $this->add_control( + 'skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'default', + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'bubble' => esc_html__( 'Bubble', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-testimonial--skin-', + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'image_inline', + 'options' => [ + 'image_inline' => esc_html__( 'Image Inline', 'elementor-pro' ), + 'image_stacked' => esc_html__( 'Image Stacked', 'elementor-pro' ), + 'image_above' => esc_html__( 'Image Above', 'elementor-pro' ), + 'image_left' => esc_html__( 'Image Left', 'elementor-pro' ), + 'image_right' => esc_html__( 'Image Right', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-testimonial--layout-', + 'render_type' => 'template', + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-testimonial-%s-align-', + ] + ); + + $this->end_injection(); + + $this->start_controls_section( + 'section_skin_style', + [ + 'label' => esc_html__( 'Bubble', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'skin' => 'bubble', + ], + ] + ); + + $this->add_control( + 'background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'alpha' => false, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content, {{WRAPPER}} .elementor-testimonial__content:after' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'text_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'top' => '20', + 'bottom' => '20', + 'left' => '20', + 'right' => '20', + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_left .elementor-testimonial__footer, + {{WRAPPER}}.elementor-testimonial--layout-image_right .elementor-testimonial__footer' => 'padding-top: {{TOP}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_above .elementor-testimonial__footer, + {{WRAPPER}}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer, + {{WRAPPER}}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer' => 'padding: 0 {{RIGHT}}{{UNIT}} 0 {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'border', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content, {{WRAPPER}} .elementor-testimonial__content:after' => 'border-style: solid', + ], + ] + ); + + $this->add_control( + 'border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#000', + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content' => 'border-color: {{VALUE}}', + '{{WRAPPER}} .elementor-testimonial__content:after' => 'border-color: transparent {{VALUE}} {{VALUE}} transparent', + ], + 'condition' => [ + 'border' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__content, {{WRAPPER}} .elementor-testimonial__content:after' => 'border-width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_stacked .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_inline .elementor-testimonial__content:after' => 'margin-top: -{{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_above .elementor-testimonial__content:after' => 'margin-bottom: -{{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'border' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'section_navigation', + ] ); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'content_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-testimonial--layout-image_inline .elementor-testimonial__footer, + {{WRAPPER}}.elementor-testimonial--layout-image_stacked .elementor-testimonial__footer' => 'margin-top: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_above .elementor-testimonial__footer' => 'margin-bottom: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_left .elementor-testimonial__footer' => 'padding-right: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_right .elementor-testimonial__footer' => 'padding-left: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'content_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__text' => 'color: {{VALUE}}', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__text', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-testimonial__text', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'content_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-testimonial__text', + ] + ); + + $this->add_control( + 'name_title_style', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'name_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__name' => 'color: {{VALUE}}', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'name_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__name', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_control( + 'heading_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__title' => 'color: {{VALUE}}', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'selector' => '{{WRAPPER}} .elementor-testimonial__title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'image_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-testimonial--layout-image_left .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_right .elementor-testimonial__content:after' => 'top: calc( {{text_padding.TOP}}{{text_padding.UNIT}} + ({{SIZE}}{{UNIT}} / 2) - 8px );', + + 'body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_stacked:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-right) .elementor-testimonial__content:after, + body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_inline:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-right) .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-left .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__content:after' => 'left: calc( {{text_padding.LEFT}}{{text_padding.UNIT}} + ({{SIZE}}{{UNIT}} / 2) - 8px ); right:auto;', + + 'body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_stacked:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-left) .elementor-testimonial__content:after, + body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_inline:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-left) .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_stacked.elementor-testimonial--align-right .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__content:after' => 'right: calc( {{text_padding.RIGHT}}{{text_padding.UNIT}} + ({{SIZE}}{{UNIT}} / 2) - 8px ); left:auto;', + + 'body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_above:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-right) .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__content:after' => 'left: calc( {{text_padding.LEFT}}{{text_padding.UNIT}} + ({{SIZE}}{{UNIT}} / 2) - 8px ); right:auto;', + + 'body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_above:not(.elementor-testimonial--align-center):not(.elementor-testimonial--align-left) .elementor-testimonial__content:after, + {{WRAPPER}}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__content:after' => 'right: calc( {{text_padding.RIGHT}}{{text_padding.UNIT}} + ({{SIZE}}{{UNIT}} / 2) - 8px ); left:auto;', + ], + ] + ); + + $this->add_responsive_control( + 'image_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_inline.elementor-testimonial--align-left .elementor-testimonial__image + cite, + body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_above.elementor-testimonial--align-left .elementor-testimonial__image + cite, + body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_inline .elementor-testimonial__image + cite, + body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_above .elementor-testimonial__image + cite' => 'margin-left: {{SIZE}}{{UNIT}}; margin-right: 0;', + + 'body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_inline.elementor-testimonial--align-right .elementor-testimonial__image + cite, + body:not(.rtl) {{WRAPPER}}.elementor-testimonial--layout-image_above.elementor-testimonial--align-right .elementor-testimonial__image + cite, + body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_inline .elementor-testimonial__image + cite, + body.rtl {{WRAPPER}}.elementor-testimonial--layout-image_above .elementor-testimonial__image + cite' => 'margin-right: {{SIZE}}{{UNIT}}; margin-left:0;', + + '{{WRAPPER}}.elementor-testimonial--layout-image_stacked .elementor-testimonial__image + cite, + {{WRAPPER}}.elementor-testimonial--layout-image_left .elementor-testimonial__image + cite, + {{WRAPPER}}.elementor-testimonial--layout-image_right .elementor-testimonial__image + cite' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'image_border', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'border-style: solid', + ], + ] + ); + + $this->add_control( + 'image_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#000', + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'image_border' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'image_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'border-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'image_border' => 'yes', + ], + ] + ); + + $this->add_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-testimonial__image img' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + + $this->update_responsive_control( + 'width', + [ + 'selectors' => [ + '{{WRAPPER}}.elementor-arrows-yes .elementor-main-swiper' => 'width: calc( {{SIZE}}{{UNIT}} - 40px )', + '{{WRAPPER}} .elementor-main-swiper' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->update_responsive_control( + 'slides_per_view', + [ + 'condition' => null, + ] + ); + + $this->update_responsive_control( + 'slides_to_scroll', + [ + 'condition' => null, + ] + ); + + $this->remove_control( 'effect' ); + $this->remove_responsive_control( 'height' ); + $this->remove_control( 'pagination_position' ); + } + + protected function add_repeater_controls( Repeater $repeater ) { + $repeater->add_control( + 'content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'name', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'John Doe', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'CEO', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + } + + protected function get_repeater_defaults() { + $placeholder_image_src = Utils::get_placeholder_image_src(); + + return [ + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => esc_html__( 'CEO', 'elementor-pro' ), + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => esc_html__( 'CEO', 'elementor-pro' ), + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + [ + 'content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'name' => esc_html__( 'John Doe', 'elementor-pro' ), + 'title' => esc_html__( 'CEO', 'elementor-pro' ), + 'image' => [ + 'url' => $placeholder_image_src, + ], + ], + ]; + } + + private function print_cite( $slide, $location ) { + if ( empty( $slide['name'] ) && empty( $slide['title'] ) ) { + return ''; + } + + $skin = $this->get_settings( 'skin' ); + $layout = 'bubble' === $skin ? 'image_inline' : $this->get_settings( 'layout' ); + $locations_outside = [ 'image_above', 'image_right', 'image_left' ]; + $locations_inside = [ 'image_inline', 'image_stacked' ]; + + $print_outside = ( 'outside' === $location && in_array( $layout, $locations_outside ) ); + $print_inside = ( 'inside' === $location && in_array( $layout, $locations_inside ) ); + + $html = ''; + if ( $print_outside || $print_inside ) { + $html = ''; + if ( ! empty( $slide['name'] ) ) { + $html .= '' . $slide['name'] . ''; + } + if ( ! empty( $slide['title'] ) ) { + $html .= '' . $slide['title'] . ''; + } + $html .= ''; + } + + // PHPCS - the main text of a widget should not be escaped. + echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + protected function print_slide( array $slide, array $settings, $element_key ) { + $lazyload = 'yes' === $this->get_settings( 'lazyload' ); + + $this->add_render_attribute( $element_key . '-testimonial', [ + 'class' => 'elementor-testimonial', + ] ); + + if ( ! empty( $slide['image']['url'] ) ) { + $img_src = $this->get_slide_image_url( $slide, $settings ); + + if ( $lazyload ) { + $img_attribute['class'] = 'swiper-lazy'; + $img_attribute['data-src'] = $img_src; + } else { + $img_attribute['src'] = $img_src; + } + + $img_attribute['alt'] = ! empty( $slide['image']['alt'] ) ? $slide['image']['alt'] : $slide['name']; + + $this->add_render_attribute( $element_key . '-image', $img_attribute ); + } + + ?> +
      print_render_attribute_string( $element_key . '-testimonial' ); ?>> + +
      +
      + +
      + print_cite( $slide, 'outside' ); ?> +
      + + +
      + print_slider(); + } + + public function get_group_name() { + return 'carousel'; + } +} diff --git a/modules/checklist/module.php b/modules/checklist/module.php new file mode 100644 index 00000000..6c4ab627 --- /dev/null +++ b/modules/checklist/module.php @@ -0,0 +1,54 @@ +module = \Elementor\Modules\Checklist\Module::instance(); + $this->wordpress_adapter = $wordpress_adapter; + $this->kit_adapter = $kit_adapter; + + add_filter( 'elementor/checklist/steps', [ $this, 'replace_steps' ], 1 ); + } + + public function get_name() : string { + return 'e-checklist'; + } + + /** + * @param array $steps + * @return \Elementor\Modules\Checklist\Steps\Step_Base[] + */ + public function replace_steps( array $steps ) : array { + $formatted_steps = []; + + foreach ( $steps as $step_id => $step ) { + if ( \Elementor\Modules\Checklist\Steps\Setup_Header::STEP_ID !== $step_id ) { + $formatted_steps[ $step_id ] = $step; + continue; + } + + $header_step = new \ElementorPro\Modules\Checklist\Steps\Setup_Header( $this->module, $this->wordpress_adapter, $this->kit_adapter ); + $formatted_steps[ $header_step->get_id() ] = $header_step; + } + + return $formatted_steps; + } +} diff --git a/modules/checklist/steps/setup-header.php b/modules/checklist/steps/setup-header.php new file mode 100644 index 00000000..d9514d3e --- /dev/null +++ b/modules/checklist/steps/setup-header.php @@ -0,0 +1,44 @@ +does_license_support_header() + ? [ + 'url' => 'http://go.elementor.com/app-website-checklist-header-article', + 'text' => esc_html__( 'Upgrade Now', 'elementor-pro' ), + 'icon' => 'default', + ] + : null; + + parent::__construct( $module, $wordpress_adapter, $kit_adapter, $promotion_data ); + } + + public function get_id() : string { + return self::STEP_ID; + } + + public function is_visible() : bool { + return true; + } + + public function get_cta_url() : string { + $base_create_url = Plugin::elementor()->documents->get_create_new_post_url( 'elementor_library' ); + + return add_query_arg( [ 'template_type' => 'header' ], $base_create_url ); + } + + private function does_license_support_header() : bool { + return API::is_licence_has_feature( 'theme-builder' ); + } +} diff --git a/modules/cloud-library/module.php b/modules/cloud-library/module.php new file mode 100644 index 00000000..571f01ca --- /dev/null +++ b/modules/cloud-library/module.php @@ -0,0 +1,54 @@ +set_cloud_library_settings(); + }, 13 /** after elementor core */ ); + } + + private function set_cloud_library_settings() { + if ( ! Plugin::elementor()->common ) { + return; + } + + /** @var ConnectModule $connect */ + $connect = Plugin::elementor()->common->get_component( 'connect' ); + + /** @var Activate $activate */ + $activate = $connect->get_app( 'activate' ); + + if ( ! $activate ) { + return; + } + + Plugin::elementor()->app->set_settings( 'cloud-library', [ + 'library_connect_url' => esc_url( $activate->get_admin_url( 'authorize', [ + 'utm_source' => 'template-library', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + 'utm_content' => 'cloud-library', + 'source' => 'cloud-library', + ] ) ), + 'library_connect_title_copy' => esc_html__( 'Connect to your Elementor account', 'elementor-pro' ), + 'library_connect_sub_title_copy' => esc_html__( 'This includes purchasing and activating your Elementor Pro license on a specific site.', 'elementor-pro' ) . '
      ' . esc_html__( 'Then you can find all your templates in one convenient library.', 'elementor-pro' ), + 'library_connect_button_copy' => esc_html__( 'Connect & Activate', 'elementor-pro' ), + ] ); + } +} diff --git a/modules/code-highlight/module.php b/modules/code-highlight/module.php new file mode 100644 index 00000000..c9db0430 --- /dev/null +++ b/modules/code-highlight/module.php @@ -0,0 +1,65 @@ +get_css_assets_url( 'widget-code-highlight', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + public function register_frontend_scripts() { + $base_url = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0'; + wp_register_script( 'prismjs_core', $base_url . '/components/prism-core.min.js', [], '1.23.0', true ); + wp_register_script( 'prismjs_loader', $base_url . '/plugins/autoloader/prism-autoloader.min.js', [ 'prismjs_core' ], '1.23.0', true ); + wp_register_script( 'prismjs_normalize', $base_url . '/plugins/normalize-whitespace/prism-normalize-whitespace.min.js', [ 'prismjs_core' ], '1.23.0', true ); + wp_register_script( 'prismjs_line_numbers', $base_url . '/plugins/line-numbers/prism-line-numbers.min.js', [ 'prismjs_normalize' ], '1.23.0', true ); + wp_register_script( 'prismjs_line_highlight', $base_url . '/plugins/line-highlight/prism-line-highlight.min.js', [ 'prismjs_normalize' ], '1.23.0', true ); + wp_register_script( 'prismjs_toolbar', $base_url . '/plugins/toolbar/prism-toolbar.min.js', [ 'prismjs_normalize' ], '1.23.0', true ); + wp_register_script( 'prismjs_copy_to_clipboard', $base_url . '/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js', [ 'prismjs_toolbar' ], '1.23.0', true ); + } +} diff --git a/modules/code-highlight/widgets/code-highlight.php b/modules/code-highlight/widgets/code-highlight.php new file mode 100644 index 00000000..fb2b1120 --- /dev/null +++ b/modules/code-highlight/widgets/code-highlight.php @@ -0,0 +1,316 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_script_depends() { + $depends = [ + 'prismjs_core' => true, + 'prismjs_loader' => true, + 'prismjs_normalize' => true, + 'highlight_handler' => true, + 'prismjs_line_numbers' => true, + 'prismjs_line_highlight' => true, + 'prismjs_copy_to_clipboard' => true, + ]; + + if ( ! Plugin::elementor()->preview->is_preview_mode() ) { + $settings = $this->get_settings_for_display(); + + if ( ! $settings['line_numbers'] ) { + unset( $depends['prismjs_line_numbers'] ); + } + + if ( ! $settings['highlight_lines'] ) { + unset( $depends['prismjs_line_highlight'] ); + } + + if ( ! $settings['copy_to_clipboard'] ) { + unset( $depends['prismjs_copy_to_clipboard'] ); + } + } + + return array_keys( $depends ); + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Code Highlight', 'elementor-pro' ), + ] + ); + + $language_option = [ + 'markup' => 'Markup', + 'html' => 'HTML', + 'css' => 'CSS', + 'sass' => 'Sass (Sass)', + 'scss' => 'Sass (Scss)', + 'less' => 'Less', + 'javascript' => 'JavaScript', + 'typescript' => 'TypeScript', + 'jsx' => 'React JSX', + 'tsx' => 'React TSX', + 'php' => 'PHP', + 'ruby' => 'Ruby', + 'json' => 'JSON + Web App Manifest', + 'http' => 'HTTP', + 'xml' => 'XML', + 'svg' => 'SVG', + 'rust' => 'Rust', + 'csharp' => 'C#', + 'dart' => 'Dart', + 'git' => 'Git', + 'java' => 'Java', + 'sql' => 'SQL', + 'go' => 'Go', + 'kotlin' => 'Kotlin + Kotlin Script', + 'julia' => 'Julia', + 'python' => 'Python', + 'swift' => 'Swift', + 'bash' => 'Bash + Shell', + 'scala' => 'Scala', + 'haskell' => 'Haskell', + 'perl' => 'Perl', + 'objectivec' => 'Objective-C', + 'visual-basic,' => 'Visual Basic + VBA', + 'r' => 'R', + 'c' => 'C', + 'cpp' => 'C++', + 'aspnet' => 'ASP.NET (C#)', + ]; + + /** + * Code highlight languages. + * + * Filters the available programming languages in the code highlight. + * + * By default supports a code list of programming languages. This hook + * allows developers to add or remove languages. + * + * @param array $language_option An array of languages. + */ + $language_option = apply_filters( 'elementor_pro/code_highlight/languages', $language_option ); + + $this->add_control( + 'language', + [ + 'label' => esc_html__( 'Language', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => false, + 'options' => $language_option, + 'default' => 'javascript', + ] + ); + + $this->add_control( + 'code', + [ + 'label' => esc_html__( 'Code', 'elementor-pro' ), + 'type' => Controls_Manager::CODE, + 'default' => 'console.log( \'Code is Poetry\' );', + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::TEXT_CATEGORY, + ], + ], + ] + ); + + $this->add_control( + 'line_numbers', + [ + 'label' => esc_html__( 'Line Numbers', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'line-numbers', + 'default' => 'line-numbers', + ] + ); + + $this->add_control( + 'copy_to_clipboard', + [ + 'label' => esc_html__( 'Copy to Clipboard', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'return_value' => 'copy-to-clipboard', + 'default' => 'copy-to-clipboard', + ] + ); + + $this->add_control( + 'highlight_lines', + [ + 'label' => esc_html__( 'Highlight Lines', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'placeholder' => '1, 3-6', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'word_wrap', + [ + 'label' => esc_html__( 'Word Wrap', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'return_value' => 'word-wrap', + 'default' => '', + ] + ); + + $this->add_control( + 'theme', + [ + 'label' => esc_html__( 'Theme', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'default', + 'options' => [ + 'default' => 'Solid', + 'dark' => 'Dark', + 'okaidia' => 'Okaidia', + 'solarizedlight' => 'Solarizedlight', + 'tomorrow' => 'Tomorrow', + 'twilight' => 'Twilight', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 115, + 'max' => 1000, + ], + 'em' => [ + 'min' => 6, + 'max' => 50, + ], + 'rem' => [ + 'min' => 6, + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .highlight-height' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'font_size', + [ + 'label' => esc_html__( 'Font Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + 'vw' => [ + 'min' => 0.1, + 'max' => 10, + 'step' => 0.1, + ], + ], + 'responsive' => true, + 'selectors' => [ + '{{WRAPPER}} pre, {{WRAPPER}} code, {{WRAPPER}} .line-numbers .line-numbers-rows' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['code'] ) ) { + return; + } + ?> +
      +
      +				
      +					<?php $this->print_unescaped_setting( 'code' ); ?>
      +				
      +			
      +
      + + <# + if ( '' === settings.code ) { + return; + } + #> +
      +
      +				
      +					{{{ settings.code }}}
      +				
      +			
      +
      + add_component( 'compatibility-tag-pro-handler', new Compatibility_Tag_Component() ); + } +} diff --git a/modules/countdown/module.php b/modules/countdown/module.php new file mode 100644 index 00000000..08d7d409 --- /dev/null +++ b/modules/countdown/module.php @@ -0,0 +1,53 @@ +get_css_assets_url( 'widget-countdown', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/countdown/widgets/countdown.php b/modules/countdown/widgets/countdown.php new file mode 100644 index 00000000..0258eb2b --- /dev/null +++ b/modules/countdown/widgets/countdown.php @@ -0,0 +1,878 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-countdown' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_countdown', + [ + 'label' => esc_html__( 'Countdown', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'countdown_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'due_date' => esc_html__( 'Due Date', 'elementor-pro' ), + 'evergreen' => esc_html__( 'Evergreen Timer', 'elementor-pro' ), + ], + 'default' => 'due_date', + ] + ); + + $this->add_control( + 'due_date', + [ + 'label' => esc_html__( 'Due Date', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'default' => gmdate( 'Y-m-d H:i', strtotime( '+1 month' ) + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ), + /* translators: %s: Time zone. */ + 'description' => sprintf( esc_html__( 'Date set according to your timezone: %s.', 'elementor-pro' ), Utils::get_timezone_string() ), + 'condition' => [ + 'countdown_type' => 'due_date', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'evergreen_counter_hours', + [ + 'label' => esc_html__( 'Hours', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 47, + 'placeholder' => esc_html__( 'Hours', 'elementor-pro' ), + 'condition' => [ + 'countdown_type' => 'evergreen', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'evergreen_counter_minutes', + [ + 'label' => esc_html__( 'Minutes', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 59, + 'placeholder' => esc_html__( 'Minutes', 'elementor-pro' ), + 'condition' => [ + 'countdown_type' => 'evergreen', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'show_days', + [ + 'label' => esc_html__( 'Days', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_hours', + [ + 'label' => esc_html__( 'Hours', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_minutes', + [ + 'label' => esc_html__( 'Minutes', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_seconds', + [ + 'label' => esc_html__( 'Seconds', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_labels', + [ + 'label' => esc_html__( 'Show Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'custom_labels', + [ + 'label' => esc_html__( 'Custom Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_control( + 'label_days', + [ + 'label' => esc_html__( 'Days', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Days', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Days', 'elementor-pro' ), + 'condition' => [ + 'show_labels!' => '', + 'custom_labels!' => '', + 'show_days' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'label_hours', + [ + 'label' => esc_html__( 'Hours', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Hours', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Hours', 'elementor-pro' ), + 'condition' => [ + 'show_labels!' => '', + 'custom_labels!' => '', + 'show_hours' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'label_minutes', + [ + 'label' => esc_html__( 'Minutes', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Minutes', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Minutes', 'elementor-pro' ), + 'condition' => [ + 'show_labels!' => '', + 'custom_labels!' => '', + 'show_minutes' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'label_seconds', + [ + 'label' => esc_html__( 'Seconds', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Seconds', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Seconds', 'elementor-pro' ), + 'condition' => [ + 'show_labels!' => '', + 'custom_labels!' => '', + 'show_seconds' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'expire_actions', + [ + 'label' => esc_html__( 'Actions After Expire', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => [ + 'redirect' => esc_html__( 'Redirect', 'elementor-pro' ), + 'hide' => esc_html__( 'Hide', 'elementor-pro' ), + 'message' => esc_html__( 'Show Message', 'elementor-pro' ), + ], + 'label_block' => true, + 'separator' => 'before', + 'render_type' => 'none', + 'multiple' => true, + ] + ); + + $this->add_control( + 'message_after_expire', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'expire_actions' => 'message', + ], + ] + ); + + $this->add_control( + 'expire_redirect_url', + [ + 'label' => esc_html__( 'Redirect URL', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'separator' => 'before', + 'options' => false, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'expire_actions' => 'redirect', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_countdown_style', + [ + 'label' => esc_html__( 'Countdown', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_container', + [ + 'label' => esc_html__( 'Container', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'label_display', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'block' => [ + 'title' => esc_html__( 'Block', 'elementor-pro' ), + 'icon' => 'eicon-grow', + ], + 'inline' => [ + 'title' => esc_html__( 'Inline', 'elementor-pro' ), + 'icon' => 'eicon-shrink', + ], + ], + 'default' => 'block', + 'prefix_class' => 'elementor-countdown--label-', + ] + ); + + $this->add_responsive_control( + 'container_width', + [ + 'label' => esc_html__( 'Container Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + 'size' => 100, + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + 'px' => [ + 'max' => 2000, + ], + 'em' => [ + 'max' => 200, + ], + 'rem' => [ + 'max' => 200, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-wrapper' => 'max-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'label_display' => 'block', + ], + ] + ); + + $this->add_control( + 'boxes_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-wrapper' => 'text-align: {{VALUE}};', + ], + 'condition' => [ + 'label_display' => 'inline', + ], + ] + ); + + $this->add_responsive_control( + 'box_spacing', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-countdown-item:not(:first-of-type)' => 'margin-left: calc( {{SIZE}}{{UNIT}}/2 );', + 'body:not(.rtl) {{WRAPPER}} .elementor-countdown-item:not(:last-of-type)' => 'margin-right: calc( {{SIZE}}{{UNIT}}/2 );', + 'body.rtl {{WRAPPER}} .elementor-countdown-item:not(:first-of-type)' => 'margin-right: calc( {{SIZE}}{{UNIT}}/2 );', + 'body.rtl {{WRAPPER}} .elementor-countdown-item:not(:last-of-type)' => 'margin-left: calc( {{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_control( + 'heading_boxes', + [ + 'label' => esc_html__( 'Boxes', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'box_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'box_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-item' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'box_border', + 'selector' => '{{WRAPPER}} .elementor-countdown-item', + ] + ); + + $this->add_control( + 'box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .elementor-countdown-item', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_digits', + [ + 'label' => esc_html__( 'Digits', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'digits_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-digits' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'digits_typography', + 'selector' => '{{WRAPPER}} .elementor-countdown-digits', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'digits_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-countdown-digits', + ] + ); + + $this->add_control( + 'heading_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_control( + 'label_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-label' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'label_typography', + 'selector' => '{{WRAPPER}} .elementor-countdown-label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'label_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-countdown-label', + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-countdown-label', + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_expire_message_style', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'expire_actions' => 'message', + ], + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-expire--message' => 'text-align: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-expire--message' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-countdown-expire--message', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'message_text_shadow', + 'selector' => '{{WRAPPER}} .elementor-countdown-expire--message', + ] + ); + + $this->add_responsive_control( + 'message_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-countdown-expire--message' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + private function get_strftime( $instance ) { + $string = ''; + if ( $instance['show_days'] ) { + $string .= $this->render_countdown_item( $instance, 'label_days', 'elementor-countdown-days' ); + } + if ( $instance['show_hours'] ) { + $string .= $this->render_countdown_item( $instance, 'label_hours', 'elementor-countdown-hours' ); + } + if ( $instance['show_minutes'] ) { + $string .= $this->render_countdown_item( $instance, 'label_minutes', 'elementor-countdown-minutes' ); + } + if ( $instance['show_seconds'] ) { + $string .= $this->render_countdown_item( $instance, 'label_seconds', 'elementor-countdown-seconds' ); + } + + return $string; + } + + private $_default_countdown_labels; + + private function init_default_countdown_labels() { + $this->_default_countdown_labels = [ + 'label_months' => esc_html__( 'Months', 'elementor-pro' ), + 'label_weeks' => esc_html__( 'Weeks', 'elementor-pro' ), + 'label_days' => esc_html__( 'Days', 'elementor-pro' ), + 'label_hours' => esc_html__( 'Hours', 'elementor-pro' ), + 'label_minutes' => esc_html__( 'Minutes', 'elementor-pro' ), + 'label_seconds' => esc_html__( 'Seconds', 'elementor-pro' ), + ]; + } + + public function get_default_countdown_labels() { + if ( ! $this->_default_countdown_labels ) { + $this->init_default_countdown_labels(); + } + + return $this->_default_countdown_labels; + } + + private function render_countdown_item( $instance, $label, $part_class ) { + $string = '
      '; + + if ( $instance['show_labels'] ) { + $default_labels = $this->get_default_countdown_labels(); + $label = ( $instance['custom_labels'] ) ? $instance[ $label ] : $default_labels[ $label ]; + $string .= ' ' . $label . ''; + } + + $string .= '
      '; + + return $string; + } + + private function get_evergreen_interval( $instance ) { + $hours = empty( $instance['evergreen_counter_hours'] ) ? 0 : ( $instance['evergreen_counter_hours'] * HOUR_IN_SECONDS ); + $minutes = empty( $instance['evergreen_counter_minutes'] ) ? 0 : ( $instance['evergreen_counter_minutes'] * MINUTE_IN_SECONDS ); + $evergreen_interval = $hours + $minutes; + + return $evergreen_interval; + } + + private function get_actions( $settings ) { + if ( empty( $settings['expire_actions'] ) || ! is_array( $settings['expire_actions'] ) ) { + return false; + } + + $actions = []; + + foreach ( $settings['expire_actions'] as $action ) { + $action_to_run = [ 'type' => $action ]; + if ( 'redirect' === $action ) { + if ( empty( $settings['expire_redirect_url']['url'] ) ) { + continue; + } + $action_to_run['redirect_url'] = esc_url( $settings['expire_redirect_url']['url'] ); + } + $actions[] = $action_to_run; + } + + return $actions; + } + + private function is_valid_url( $url ) { + return ! preg_match( '/\bjavascript\b/i', $url ) && filter_var( $url, FILTER_VALIDATE_URL ); + } + + private function sanitize_action( $key, $value ) { + if ( 'redirect_url' === $key && is_string( $value ) ) { + return $this->is_valid_url( $value ) ? esc_url( $value ) : null; + } + + return esc_html( $value ); + } + + private function map_sanitized_action( $action ) { + $sanitized_action = []; + + foreach ( $action as $key => $value ) { + $sanitized_action[ $key ] = $this->sanitize_action( $key, $value ); + } + + return $sanitized_action; + } + + private function sanitize_redirect_url( $actions ) { + return array_map( function ( $action ) { + return $this->map_sanitized_action( $action ); + }, $actions ); + } + + + protected function render() { + $instance = $this->get_settings_for_display(); + $due_date = $instance['due_date']; + $string = $this->get_strftime( $instance ); + + if ( 'evergreen' === $instance['countdown_type'] ) { + $this->add_render_attribute( 'div', 'data-evergreen-interval', $this->get_evergreen_interval( $instance ) ); + } else { + $wp_timezone = new \DateTimeZone( wp_timezone_string() ); + $due_date = new \DateTime( $due_date, $wp_timezone ); + $due_date = $due_date->getTimestamp(); + } + + $actions = false; + + if ( ! Plugin::elementor()->editor->is_edit_mode() ) { + $actions = $this->get_actions( $instance ); + } + + if ( $actions ) { + $sanitized_actions = $this->sanitize_redirect_url( $actions ); + + $this->add_render_attribute( 'div', 'data-expire-actions', wp_json_encode( $sanitized_actions ) ); + } + + $this->add_render_attribute( 'div', [ + 'class' => 'elementor-countdown-wrapper', + 'data-date' => $due_date, + ] ); + + ?> +
      print_render_attribute_string( 'div' ); ?>> + +
      + +
      + +
      + add_actions(); + } + + public function get_name() { + return 'custom-attributes'; + } + + private function get_black_list_attributes() { + static $black_list = null; + + if ( null === $black_list ) { + $black_list = [ 'id', 'class', 'data-id', 'data-settings', 'data-element_type', 'data-widget_type', 'data-model-cid' ]; + + /** + * Elementor attributes black list. + * + * Filters the attributes that won't be rendered in the wrapper element. + * + * By default Elementor doesn't render some attributes to prevent things + * from breaking down. This hook allows developers to alter this list of + * attributes. + * + * @since 2.2.0 + * + * @param array $black_list A black list of attributes. + */ + $black_list = apply_filters( 'elementor_pro/element/attributes/black_list', $black_list ); + } + + return $black_list; + } + + /** + * @param Element_Base $element + */ + public function replace_go_pro_custom_attributes_controls( Element_Base $element ) { + $old_section = Plugin::elementor()->controls_manager->get_control_from_stack( + $element->get_unique_name(), + 'section_custom_attributes_pro' + ); + + Plugin::elementor()->controls_manager->remove_control_from_stack( $element->get_unique_name(), [ 'section_custom_attributes_pro', 'custom_attributes_pro' ] ); + + $this->register_custom_attributes_controls( $element, $old_section['tab'] ); + } + + public function register_custom_attributes_controls( Element_Base $element, $tab ) { + $element_name = $element->get_name(); + + $element->start_controls_section( + '_section_attributes', + [ + 'label' => esc_html__( 'Attributes', 'elementor-pro' ), + 'tab' => $tab, + ] + ); + + $element->add_control( + '_attributes', + [ + 'label' => esc_html__( 'Custom Attributes', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'key|value', 'elementor-pro' ), + 'description' => sprintf( + /* translators: %s: The `|` separate char. */ + esc_html__( 'Set custom attributes for the wrapper element. Each attribute in a separate line. Separate attribute key from the value using %s character.', 'elementor-pro' ), + '|' + ), + 'classes' => 'elementor-control-direction-ltr', + ] + ); + + $element->end_controls_section(); + } + + /** + * @param $element Controls_Stack + * @param $section_id string + */ + public function register_controls( Controls_Stack $element, $section_id ) { + if ( ! $element instanceof Element_Base ) { + return; + } + + // Remove Custom CSS Banner (From free version) + if ( 'section_custom_attributes_pro' !== $section_id ) { + return; + } + + if ( ! API::is_licence_has_feature( self::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->replace_controls_with_upgrade_promotion( $element ); + return; + } + + $this->replace_go_pro_custom_attributes_controls( $element ); + } + + /** + * @param $element Element_Base + */ + public function render_attributes( Element_Base $element ) { + $settings = $element->get_settings_for_display(); + + if ( ! empty( $settings['_attributes'] ) ) { + $attributes = Utils::parse_custom_attributes( $settings['_attributes'], "\n" ); + + $black_list = $this->get_black_list_attributes(); + + foreach ( $attributes as $attribute => $value ) { + if ( ! in_array( $attribute, $black_list, true ) ) { + $element->add_render_attribute( '_wrapper', $attribute, $value ); + } + } + } + } + + protected function add_actions() { + add_action( 'elementor/element/after_section_end', [ $this, 'register_controls' ], 10, 2 ); + + if ( API::is_licence_has_feature( static::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + add_action( 'elementor/element/after_add_attributes', [ $this, 'render_attributes' ] ); + } + } + + private function replace_controls_with_upgrade_promotion( Element_Base $element ) { + $old_section = Plugin::elementor()->controls_manager->get_control_from_stack( + $element->get_unique_name(), + 'section_custom_attributes_pro' + ); + Plugin::elementor()->controls_manager->remove_control_from_stack( $element->get_unique_name(), [ 'section_custom_attributes_pro', 'section_custom_attributes_pro' ] ); + + $element->start_controls_section( + 'section_custom_attributes_promotion', + [ + 'label' => esc_html__( 'Attributes', 'elementor-pro' ), + 'tab' => $old_section['tab'], + ] + ); + + $element->add_control( + 'custom_attributes_promotion', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Tiers::get_promotion_template( [ + 'title' => esc_html__( 'Meet Our Attributes', 'elementor-pro' ), + 'messages' => [ + esc_html__( 'Add custom HTML attributes to any element.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-attributes/', + ] ), + ] + ); + + $element->end_controls_section(); + } +} diff --git a/modules/custom-code/admin-menu-items/custom-code-menu-item.php b/modules/custom-code/admin-menu-items/custom-code-menu-item.php new file mode 100644 index 00000000..09f539cc --- /dev/null +++ b/modules/custom-code/admin-menu-items/custom-code-menu-item.php @@ -0,0 +1,36 @@ +' . $label . '

      '; + } + + return $label; + } + + public function get_location_labels() { + return [ + self::OPTION_LOCATION_HEAD => esc_html__( 'Head', 'elementor-pro' ), + self::OPTION_LOCATION_BODY_START => esc_html__( 'Body Start', 'elementor-pro' ), + self::OPTION_LOCATION_BODY_END => esc_html__( 'Body End', 'elementor-pro' ), + ]; + } + + public function get_location_options() { + return [ + self::OPTION_LOCATION_HEAD => '', + self::OPTION_LOCATION_BODY_START => sprintf( + /* translators: %s: Body opening tag. */ + esc_html__( '%s - Start', 'elementor-pro' ), + '' + ), + self::OPTION_LOCATION_BODY_END => sprintf( + /* translators: %s: Body closing tag. */ + esc_html__( '%s - End', 'elementor-pro' ), + '' + ), + ]; + } + + public function get_priority_options() { + $start = 1; + $result = range( $start, self::OPTION_PRIORITY_LENGTH ); + + $result = array_combine( $result, $result ); + + return $result; + } + + /** + * Add script integrity. + * + * This is method is public, since its has to remove its own filter. + * + * @param string $html + * @param mixed $handle + * + * @return string + */ + public function add_script_integrity( $html, $handle ) { + if ( 'jshint' === $handle ) { + $html = str_replace( '>', ' integrity="sha512-qcoitUjhkmNyPmbIOlUV/zd8MJvrVcKrNqnveMWS3C6MYOl5+HLwliRKUm/Ae/dfIok6+E54hjgVrAeS+sBAGA==" crossorigin="anonymous">', $html ); + + remove_filter( 'script_loader_tag', [ $this, 'add_script_integrity' ] ); + } + + return $html; + } + + protected function actions() { + add_action( 'add_meta_boxes_' . Module::CPT, function () { + $this->add_meta_boxes(); + } ); + + add_action( 'save_post_' . Module::CPT, function( $post_id, $post, $update ) { + return $this->save_post_meta( $post_id, $post ); + }, 10, 3 ); + + add_action('post_submitbox_misc_actions', function ( $post ) { + $this->add_meta_publish_options( $post ); + } ); + } + + private function get_fields() { + return [ + [ + 'id' => 'open-div-meta-box', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-meta-box', + ], + ], + [ + 'id' => 'open-div-panel', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-panel', + ], + ], + [ + 'id' => 'open-div-placement', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-panel-placement', + ], + ], + [ + 'id' => self::FIELD_LOCATION, + 'field_type' => 'select', + 'label' => esc_html__( 'Location', 'elementor-pro' ) . ':', + 'options' => $this->get_location_options(), + 'info' => esc_html__( 'Define where the Custom Code will appear', 'elementor-pro' ), + ], + [ + 'id' => 'open-div-placement', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-options-placement', + ], + ], + [ + 'id' => self::FILED_EXTRA_OPTIONS, + 'field_type' => 'checkbox', + 'options' => [ + self::INPUT_OPTION_ENSURE_JQUERY => esc_html__( 'Always load jQuery', 'elementor-pro' ), + ], + 'info' => esc_html__( 'If your snippet includes jQuery, this will ensure it will work for all visitors. It may have a minor impact on loading speed.', 'elementor-pro' ), + ], + [ + 'id' => 'close-div-placement', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => self::FIELD_PRIORITY, + 'field_type' => 'select', + 'label' => esc_html__( 'Priority', 'elementor-pro' ) . ':', + 'options' => $this->get_priority_options(), + 'info' => esc_html__( 'Define in which order the Custom Code will appear', 'elementor-pro' ), + ], + [ + 'id' => 'close-div-placement', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'close-div-panel', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'close-div-meta-box', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'open-div-code-mirror-holder', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-codemirror-holder', + ], + ], + [ + 'id' => 'open-div-code-mirror', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'elementor-custom-code-codemirror', + ], + ], + [ + 'id' => self::FIELD_CODE, + 'field_type' => 'textarea', + 'label' => '', + 'extra_attributes' => [ + 'class' => 'hidden', + ], + ], + [ + 'id' => 'close-div-code-mirror', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + [ + 'id' => 'close-div-code-mirror-holder', + 'field_type' => 'html_tag', + 'label' => false, + 'tag' => 'div', + 'close' => true, + ], + ]; + } + + private function get_code_editor_settings() { + // TODO: Handle `enqueue_code_editor_scripts` to work with `lint => 'true'`. + return [ + 'type' => 'text/html', + 'codemirror' => [ + 'indentUnit' => 2, + 'tabSize' => 2, + 'gutters' => [ 'CodeMirror-lint-markers' ], + ], + ]; + } + + private function enqueue_code_editor_scripts( $field_code_id ) { + // Add integrity attribute to jshint. + add_filter( 'script_loader_tag', [ $this, 'add_script_integrity' ], 10, 2 ); + + wp_enqueue_script( 'htmlhint' ); + wp_enqueue_script( 'csslint' ); + + wp_deregister_script( 'jshint' ); + + wp_enqueue_script( 'jshint', + 'https://cdnjs.cloudflare.com/ajax/libs/jshint/2.12.0/jshint.min.js', + [], + '2.12.0' + ); + + /** + * Some of the plugins may load 'code-editor' for their needs and change the default behavior, so it should + * re-initialize the code editor with 'custom code' settings. + */ + if ( wp_script_is( 'code-editor' ) ) { + wp_add_inline_script( 'custom-code-metabox', sprintf( 'wp.codeEditor.initialize( jQuery( "#%s"), %s );', $field_code_id, wp_json_encode( wp_get_code_editor_settings( $this->get_code_editor_settings() ) ) ) ); + } else { + wp_enqueue_code_editor( $this->get_code_editor_settings() ); + + wp_add_inline_script( 'code-editor', sprintf( 'wp.codeEditor.initialize( jQuery( "#%s") );', $field_code_id ) ); + } + } + + private function render_meta_box() { + $fields = $this->get_fields(); + + if ( ! empty( $_REQUEST['action'] ) && 'edit' == $_REQUEST['action'] ) { + $post = get_post( \ElementorPro\Core\Utils::_unstable_get_super_global_value( $_REQUEST, 'post' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here. + foreach ( self::INPUT_FIELDS as $input_field ) { + $field_meta = get_post_meta( $post->ID, "_elementor_$input_field", true ); + + if ( ! empty( $field_meta ) ) { + $key = array_search( $input_field, array_column( $fields, 'id' ) ); + if ( false !== $key ) { + $fields[ $key ]['saved'] = $field_meta; + } + } + } + } + + // The method, support fields only. + $this->print_metabox( $fields ); + + /** + * Elementor metabox render. + * + * Fires before custom scripts are enqueued, since enqueue depends on + * render handlers. + * + * @param Custom_Code_Metabox $this An instance of custom code metabox. + * @param int|false $id The ID of the current WordPress post. + * False if post is not set. + */ + do_action( 'elementor-pro/metabox/render', $this, get_the_ID() ); + + // Init codemirror. + $this->enqueue_code_editor_scripts( self::FIELD_CODE ); + } + + private function save_post_meta( $post_id, $post ) { + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return $post_id; + } + + // Check the user's permissions. + if ( ! current_user_can( 'edit_post', $post_id ) ) { + return $post_id; + } + + if ( get_post_status( $post->ID ) === 'auto-draft' ) { + return $post_id; + } + + // PHPCS - Should not validate for nonce (already done in WordPress save_post). + $post_data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing + + foreach ( self::INPUT_FIELDS as $field ) { + if ( isset( $post_data[ $field ] ) && ! Utils::is_empty( $post_data[ $field ] ) ) { + if ( self::FIELD_CODE === $field ) { + $post_meta = $post_data[ $field ]; + } else { + $post_meta = sanitize_text_field( $post_data[ $field ] ); + } + + if ( ! current_user_can( 'unfiltered_html' ) ) { + $post_meta = wp_kses_post( $post_meta ); + } + update_post_meta( $post->ID, "_elementor_$field", $post_meta ); + + /** @var \ElementorPro\Modules\ThemeBuilder\Module $theme_builder */ + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + $theme_builder->get_conditions_manager()->get_cache()->regenerate(); + } elseif ( self::FILED_EXTRA_OPTIONS === $field ) { + $input_options = []; + + foreach ( self::INPUT_OPTIONS as $input_option ) { + $key = self::FILED_EXTRA_OPTIONS . '_' . $input_option; + $input_option_value = \ElementorPro\Core\Utils::_unstable_get_super_global_value( $post_data, $key ); + + if ( 'on' === $input_option_value ) { + $input_options [] = $input_option; + } + } + + update_post_meta( $post->ID, "_elementor_$field", $input_options ); + } + } + + // Temporary workaround for applying conditions for draft custom code post. + if ( ! empty( $post_data['_conditions'] ) ) { + $conditions = (array) json_decode( wp_unslash( $post_data['_conditions'] ) ); + + foreach ( $conditions as $key => $item ) { + $item_assoc_array = (array) $item; + + $conditions[ $key ] = [ + $item_assoc_array['type'], + $item_assoc_array['name'], + $item_assoc_array['sub'], + $item_assoc_array['subId'], + ]; + } + + /** @var \ElementorPro\Modules\ThemeBuilder\Module $theme_builder */ + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + + $theme_builder->get_conditions_manager()->save_conditions( $post_id, $conditions ); + } + } + + private function add_meta_boxes() { + add_meta_box( + 'elementor-custom-code', + __( 'Custom code', 'elementor-pro' ), + function() { + $this->render_meta_box(); + }, + module::CPT, + 'normal', + 'default' + ); + } + + private function add_meta_publish_options( $post ) { + if ( Module::CPT === $post->post_type ) { + ?> +
      + + + +
      + post->ID, '_elementor_' . Custom_Code_Metabox::FIELD_CODE, true ) . PHP_EOL; + $user_has_permission = current_user_can( Module::CAPABILITY ); + + $this->apply_snippet_options( get_post_meta( $this->get_id(), '_elementor_' . Custom_Code_Metabox::FILED_EXTRA_OPTIONS, true ) ); + + if ( $user_has_permission ) { + $this->print_snippet_with_elementor_comment( $content ); + } else { + // PHPCS - the main content of custom code + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + public static function get_create_url() { + $query_args = [ + 'post_type' => Module::CPT, + ]; + + return add_query_arg( $query_args, admin_url( 'post-new.php' ) ); + } + + private function print_snippet_with_elementor_comment( $content ) { + echo implode( PHP_EOL, [ + '', + '', + '', + ] ); + + // PHPCS - the main content of custom code + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + echo PHP_EOL . '' . PHP_EOL; + } + + private function apply_snippet_options( $options ) { + if ( ! is_array( $options ) || ! count( $options ) ) { + return; + } + + foreach ( $options as $option ) { + if ( ! empty( self::$applied_options[ $option ] ) ) { + continue; + } + + switch ( $option ) { + case Custom_Code_Metabox::INPUT_OPTION_ENSURE_JQUERY: + wp_enqueue_script( 'jquery' ); + + // Ensure jQuery will be first in order. + if ( 'wp_footer' === current_filter() ) { + wp_print_footer_scripts(); + } + break; + } + + self::$applied_options[ $option ] = true; + } + } +} diff --git a/modules/custom-code/import-export-customization/export-runner.php b/modules/custom-code/import-export-customization/export-runner.php new file mode 100644 index 00000000..d02da231 --- /dev/null +++ b/modules/custom-code/import-export-customization/export-runner.php @@ -0,0 +1,79 @@ +get_custom_code_snippets(); + $include_custom_code = $data['customization']['settings']['customCode'] ?? true; + + if ( empty( $code_snippets ) || ! $include_custom_code ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $snippets_data = []; + $manifest = []; + + foreach ( $code_snippets as $snippet ) { + $data = $this->prepare_snippet_data( $snippet ); + $snippets_data[] = $data; + $manifest['custom-code'][ $snippet->ID ] = $data; + } + + return [ + 'files' => [ + 'path' => Import_Export_Customization::FILE_NAME, + 'data' => $snippets_data, + ], + 'manifest' => [ + $manifest, + ], + ]; + } + + private function get_custom_code_snippets() { + return get_posts( [ + 'post_type' => Custom_Code_Module::CPT, + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + } + + private function prepare_snippet_data( $snippet ) { + $location = get_post_meta( $snippet->ID, '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, true ); + $priority = get_post_meta( $snippet->ID, '_elementor_' . Custom_Code_Metabox::FIELD_PRIORITY, true ); + $conditions = get_post_meta( $snippet->ID, '_elementor_conditions', true ); + + return [ + 'ID' => $snippet->ID, + 'post_title' => $snippet->post_title, + 'post_content' => $snippet->post_content, + 'post_status' => $snippet->post_status, + 'location' => $location, + 'priority' => $priority, + 'conditions' => $conditions, + ]; + } +} diff --git a/modules/custom-code/import-export-customization/import-export-customization.php b/modules/custom-code/import-export-customization/import-export-customization.php new file mode 100644 index 00000000..7365277d --- /dev/null +++ b/modules/custom-code/import-export-customization/import-export-customization.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/import-kit', function ( CustomizationImport $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export-customization/revert-kit', function ( CustomizationRevert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/custom-code/import-export-customization/import-runner.php b/modules/custom-code/import-export-customization/import-runner.php new file mode 100644 index 00000000..f35d3377 --- /dev/null +++ b/modules/custom-code/import-export-customization/import-runner.php @@ -0,0 +1,140 @@ +session_id = $data['session_id']; + $include_custom_code = $data['customization']['settings']['customCode'] ?? true; + + $custom_code_file_path = $data['extracted_directory_path'] . Import_Export_Customization::FILE_NAME; + $snippets_data = ImportExportUtils::read_json_file( $custom_code_file_path ); + + $result = []; + if ( empty( $snippets_data ) || ! $include_custom_code ) { + return $result; + } + + foreach ( $snippets_data as $snippet_data ) { + $this->import_snippet( $snippet_data ); + } + + if ( empty( $this->imported_snippets ) ) { + return $result; + } + + $result['site-settings']['custom-code'] = $this->imported_snippets; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_snippets' => $this->imported_snippets, + ]; + } + + private function import_snippet( $snippet_data ) { + $existing_snippet = $this->get_existing_snippet( $snippet_data['post_title'] ); + + if ( $existing_snippet ) { + return; + } + + $snippet_id = $this->create_snippet( $snippet_data ); + + if ( $snippet_id ) { + $this->imported_snippets[] = [ + 'id' => $snippet_id, + 'title' => $snippet_data['post_title'], + ]; + } + } + + private function get_existing_snippet( $snippet_title ) { + $snippet_query = new \WP_Query( [ + 'post_type' => Custom_Code_Module::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $snippet_title, + ] ); + + if ( $snippet_query->have_posts() ) { + $snippet_post = $snippet_query->posts[0]; + return [ + 'id' => $snippet_post->ID, + 'title' => $snippet_post->post_title, + ]; + } + + return null; + } + + private function create_snippet( $snippet_data ) { + $snippet_id = wp_insert_post( [ + 'post_title' => $snippet_data['post_title'], + 'post_content' => $snippet_data['post_content'], + 'post_status' => $snippet_data['post_status'], + 'post_type' => Custom_Code_Module::CPT, + ] ); + + if ( is_wp_error( $snippet_id ) ) { + return false; + } + + $this->set_session_post_meta( $snippet_id, $this->session_id ); + + if ( ! empty( $snippet_data['location'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, $snippet_data['location'] ); + } + + if ( ! empty( $snippet_data['device_mode'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_DEVICE_MODE, $snippet_data['device_mode'] ); + } + + if ( ! empty( $snippet_data['user_roles'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_USER_ROLES, $snippet_data['user_roles'] ); + } + + if ( ! empty( $snippet_data['site_languages'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_SITE_LANGUAGES, $snippet_data['site_languages'] ); + } + + if ( ! empty( $snippet_data['url_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_URL_CONDITIONS, $snippet_data['url_conditions'] ); + } + + if ( ! empty( $snippet_data['date_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_DATE_CONDITIONS, $snippet_data['date_conditions'] ); + } + + if ( ! empty( $snippet_data['time_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_TIME_CONDITIONS, $snippet_data['time_conditions'] ); + } + + return $snippet_id; + } +} diff --git a/modules/custom-code/import-export-customization/revert-runner.php b/modules/custom-code/import-export-customization/revert-runner.php new file mode 100644 index 00000000..36d3927c --- /dev/null +++ b/modules/custom-code/import-export-customization/revert-runner.php @@ -0,0 +1,37 @@ +revert_imported_snippets( $metadata ); + } + + private function revert_imported_snippets( $metadata ) { + $imported_snippets = $metadata['imported_snippets'] ?? []; + + foreach ( $imported_snippets as $snippet ) { + wp_delete_post( $snippet['id'], true ); + } + } +} diff --git a/modules/custom-code/import-export/export-runner.php b/modules/custom-code/import-export/export-runner.php new file mode 100644 index 00000000..916b5bd2 --- /dev/null +++ b/modules/custom-code/import-export/export-runner.php @@ -0,0 +1,78 @@ +get_custom_code_snippets(); + + if ( empty( $code_snippets ) ) { + return [ + 'manifest' => [], + 'files' => [], + ]; + } + + $snippets_data = []; + $manifest = []; + + foreach ( $code_snippets as $snippet ) { + $data = $this->prepare_snippet_data( $snippet ); + $snippets_data[] = $data; + $manifest['custom-code'][ $snippet->ID ] = $data; + } + + return [ + 'files' => [ + 'path' => Import_Export::FILE_NAME, + 'data' => $snippets_data, + ], + 'manifest' => [ + $manifest, + ], + ]; + } + + private function get_custom_code_snippets() { + return get_posts( [ + 'post_type' => Custom_Code_Module::CPT, + 'posts_per_page' => -1, + 'post_status' => 'publish', + ] ); + } + + private function prepare_snippet_data( $snippet ) { + $location = get_post_meta( $snippet->ID, '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, true ); + $priority = get_post_meta( $snippet->ID, '_elementor_' . Custom_Code_Metabox::FIELD_PRIORITY, true ); + $conditions = get_post_meta( $snippet->ID, '_elementor_conditions', true ); + + return [ + 'ID' => $snippet->ID, + 'post_title' => $snippet->post_title, + 'post_content' => $snippet->post_content, + 'post_status' => $snippet->post_status, + 'location' => $location, + 'priority' => $priority, + 'conditions' => $conditions, + ]; + } +} diff --git a/modules/custom-code/import-export/import-export.php b/modules/custom-code/import-export/import-export.php new file mode 100644 index 00000000..99d35bbc --- /dev/null +++ b/modules/custom-code/import-export/import-export.php @@ -0,0 +1,25 @@ +register( new Export_Runner() ); + } ); + + add_action( 'elementor/import-export/import-kit', function ( Import $import ) { + $import->register( new Import_Runner() ); + } ); + + add_action( 'elementor/import-export/revert-kit', function ( Revert $revert ) { + $revert->register( new Revert_Runner() ); + } ); + } +} diff --git a/modules/custom-code/import-export/import-runner.php b/modules/custom-code/import-export/import-runner.php new file mode 100644 index 00000000..0fc0caaa --- /dev/null +++ b/modules/custom-code/import-export/import-runner.php @@ -0,0 +1,139 @@ +session_id = $data['session_id']; + + $custom_code_file_path = $data['extracted_directory_path'] . Import_Export::FILE_NAME; + $snippets_data = ImportExportUtils::read_json_file( $custom_code_file_path ); + + $result = []; + if ( empty( $snippets_data ) ) { + return $result; + } + + foreach ( $snippets_data as $snippet_data ) { + $this->import_snippet( $snippet_data ); + } + + if ( empty( $this->imported_snippets ) ) { + return $result; + } + + $result['site-settings']['custom-code'] = $this->imported_snippets; + + return $result; + } + + public function get_import_session_metadata(): array { + return [ + 'imported_snippets' => $this->imported_snippets, + ]; + } + + private function import_snippet( $snippet_data ) { + $existing_snippet = $this->get_existing_snippet( $snippet_data['post_title'] ); + + if ( $existing_snippet ) { + return; + } + + $snippet_id = $this->create_snippet( $snippet_data ); + + if ( $snippet_id ) { + $this->imported_snippets[] = [ + 'id' => $snippet_id, + 'title' => $snippet_data['post_title'], + ]; + } + } + + private function get_existing_snippet( $snippet_title ) { + $snippet_query = new \WP_Query( [ + 'post_type' => Custom_Code_Module::CPT, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'title' => $snippet_title, + ] ); + + if ( $snippet_query->have_posts() ) { + $snippet_post = $snippet_query->posts[0]; + return [ + 'id' => $snippet_post->ID, + 'title' => $snippet_post->post_title, + ]; + } + + return null; + } + + private function create_snippet( $snippet_data ) { + $snippet_id = wp_insert_post( [ + 'post_title' => $snippet_data['post_title'], + 'post_content' => $snippet_data['post_content'], + 'post_status' => $snippet_data['post_status'], + 'post_type' => Custom_Code_Module::CPT, + ] ); + + if ( is_wp_error( $snippet_id ) ) { + return false; + } + + $this->set_session_post_meta( $snippet_id, $this->session_id ); + + if ( ! empty( $snippet_data['location'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, $snippet_data['location'] ); + } + + if ( ! empty( $snippet_data['device_mode'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_DEVICE_MODE, $snippet_data['device_mode'] ); + } + + if ( ! empty( $snippet_data['user_roles'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_USER_ROLES, $snippet_data['user_roles'] ); + } + + if ( ! empty( $snippet_data['site_languages'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_SITE_LANGUAGES, $snippet_data['site_languages'] ); + } + + if ( ! empty( $snippet_data['url_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_URL_CONDITIONS, $snippet_data['url_conditions'] ); + } + + if ( ! empty( $snippet_data['date_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_DATE_CONDITIONS, $snippet_data['date_conditions'] ); + } + + if ( ! empty( $snippet_data['time_conditions'] ) ) { + update_post_meta( $snippet_id, '_elementor_' . Custom_Code_Metabox::FIELD_TIME_CONDITIONS, $snippet_data['time_conditions'] ); + } + + return $snippet_id; + } +} diff --git a/modules/custom-code/import-export/revert-runner.php b/modules/custom-code/import-export/revert-runner.php new file mode 100644 index 00000000..1947f45d --- /dev/null +++ b/modules/custom-code/import-export/revert-runner.php @@ -0,0 +1,38 @@ +revert_imported_snippets( $metadata ); + } + + private function revert_imported_snippets( $metadata ) { + $imported_snippets = $metadata['imported_snippets'] ?? []; + + foreach ( $imported_snippets as $snippet ) { + wp_delete_post( $snippet['id'], true ); + } + } +} diff --git a/modules/custom-code/module.php b/modules/custom-code/module.php new file mode 100644 index 00000000..5acd8b3d --- /dev/null +++ b/modules/custom-code/module.php @@ -0,0 +1,538 @@ +meta_box = new Custom_Code_Metabox(); + + $this->actions(); + + if ( $this->can_use_custom_code() ) { + $this->register_custom_post_type(); + $this->register_metabox(); + } + + $this->register_import_export(); + } + + public function get_name() { + return 'custom-code'; + } + + private function actions() { + if ( $this->can_use_custom_code() ) { + add_action( 'elementor/documents/register', function ( $documents_manager ) { + return $this->register_documents( $documents_manager ); + } ); + + add_action( 'elementor/theme/register_locations', function ( $location_manager ) { + return $this->register_location( $location_manager ); + } ); + + add_action( 'init', function () { + $this->register_rest_meta_fields(); + } ); + } + + add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu_manager ) { + $this->add_admin_menu( $admin_menu_manager ); + } ); + + // TODO: BC - Remove after `Admin_Menu_Manager` will be the standard. + add_action( 'admin_menu', function () { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + $menu_title = esc_html__( 'Custom Code', 'elementor-pro' ); + add_submenu_page( + Settings::PAGE_ID, + $menu_title, + $menu_title, + self::CAPABILITY, + static::MENU_SLUG + ); + }, /* After custom icons */ 51 ); + + add_action( 'current_screen', function () { + if ( ! is_admin() ) { + return; + } + + $current_screen = get_current_screen(); + + if ( 'edit-' . self::CPT === $current_screen->id ) { + $this->admin_ui_actions(); + } elseif ( self::CPT === $current_screen->id ) { + // Enqueue assets. + add_action( 'admin_enqueue_scripts', function () { + $this->enqueue_assets(); + }, 0 /* elementor-app-base styles should be loaded in early stages */ ); + } + } ); + + $this->frontend_actions(); + } + + private function admin_ui_actions() { + // Show blank 'custom code' snippets list. + add_action( 'manage_posts_extra_tablenav', function ( $which ) { + return $this->maybe_render_blank_state( $which ); + } ); + + // Mange post columns. + add_filter( 'manage_posts_columns', function ( $columns ) { + return $this->manage_posts_columns( $columns ); + } ); + + add_action( 'manage_posts_custom_column', function ( $column_name, $post_id ) { + return $this->manage_posts_custom_column( $column_name, $post_id ); + }, 10, 2 ); + } + + private function frontend_actions() { + // Print snippets. + add_action( 'wp_head', function () { + $this->print_snippets( Custom_Code_Metabox::OPTION_LOCATION_HEAD ); + } ); + + add_action( 'wp_body_open', function () { + $this->print_snippets( Custom_Code_Metabox::OPTION_LOCATION_BODY_START ); + } ); + + add_action( 'wp_footer', function () { + $this->print_snippets( Custom_Code_Metabox::OPTION_LOCATION_BODY_END ); + }, 21 /* After 'wp_print_footer_scripts' */ ); + } + + private function register_custom_post_type() { + $labels = [ + 'name' => esc_html__( 'Custom Code', 'elementor-pro' ), + 'singular_name' => esc_html__( 'Custom Code', 'elementor-pro' ), + 'add_new' => esc_html__( 'Add new', 'elementor-pro' ), + 'add_new_item' => esc_html__( 'New code', 'elementor-pro' ), + 'edit_item' => esc_html__( 'Edit code', 'elementor-pro' ), + ]; + + register_post_type( self::CPT, [ + 'labels' => $labels, + 'public' => false, + 'rewrite' => false, + 'show_ui' => true, + 'show_in_menu' => false, + 'show_in_nav_menus' => false, + 'exclude_from_search' => true, + 'show_in_rest' => true, + 'capability_type' => 'post', + 'hierarchical' => false, + 'supports' => [ 'title', 'author', 'custom-fields' ], + 'capabilities' => [ + 'publish_posts' => 'manage_options', + 'edit_posts' => 'manage_options', + 'edit_others_posts' => 'manage_options', + 'delete_posts' => 'manage_options', + 'delete_others_posts' => 'manage_options', + 'read_private_posts' => 'manage_options', + 'edit_post' => 'manage_options', + 'delete_post' => 'manage_options', + 'read_post' => 'manage_options', + ], + ] ); + + // Handling custom post type messages. + add_filter( 'post_updated_messages', function( $messages ) { + if ( self::CPT === get_post_type() ) { + $post = get_post(); + + // Thanks 'WooCommerce' for the example. + $messages[ self::CPT ] = [ + '', // Not in use. + __( 'Custom code updated.', 'elementor-pro' ), + __( 'Custom field updated.', 'elementor-pro' ), + __( 'Custom field deleted.', 'elementor-pro' ), + __( 'Custom code updated.', 'elementor-pro' ), + __( 'Revision restored.', 'elementor-pro' ), + __( 'Custom code published.', 'elementor-pro' ), + __( 'Custom code saved.', 'elementor-pro' ), + __( 'Custom code submitted.', 'elementor-pro' ), + sprintf( + /* translators: %s: The scheduled date. */ + __( 'Custom code scheduled for %s.', 'elementor-pro' ), + '' . date_i18n( esc_html__( 'M j, Y @ G:i', 'elementor-pro' ), strtotime( $post->post_date ) ) . '' + ), + __( 'Custom code draft updated.', 'elementor-pro' ), + ]; + } + + return $messages; + } ); + + add_filter( 'bulk_post_updated_messages', function ( $messages, $counters ) { + $current_screen = get_current_screen(); + + if ( $current_screen && self::CPT === $current_screen->post_type ) { + $messages[ self::CPT ] = [ + 'updated' => _n( '%s custom code updated.', '%s custom codes updated.', $counters['updated'], 'elementor-pro' ), + 'locked' => _n( '%s custom code cannot be not updated, someone else is editing it.', '%s custom codes cannot be not updated, someone else is editing them.', $counters['locked'], 'elementor-pro' ), + 'deleted' => _n( '%s custom code permanently deleted.', '%s custom codes permanently deleted.', $counters['deleted'], 'elementor-pro' ), + 'trashed' => _n( '%s custom code moved to trash.', '%s custom codes moved to trash.', $counters['trashed'], 'elementor-pro' ), + 'untrashed' => _n( '%s custom code restored.', '%s custom code restored.', $counters['untrashed'], 'elementor-pro' ), + ]; + } + + return $messages; + }, 10, 12 ); + } + + /** + * Function register metabox. + * + * Add meta box for custom-code post. + */ + private function register_metabox() { + if ( ! is_admin() ) { + return; + } + // Remove 'author' meta_box from 'add-new.php', 'author' is required only in list ( enabled via 'supports' arg ). + add_action( 'add_meta_boxes_' . self::CPT, function () { + remove_meta_box( 'authordiv', self::CPT, 'normal' ); + } ); + } + + private function enqueue_assets() { + wp_enqueue_style( 'elementor-app-base', $this->get_css_assets_url( 'app-base', null, 'default', true ), [ + 'elementor-icons', + 'select2', + ], ELEMENTOR_VERSION ); + + wp_register_style( + 'select2', + $this->get_css_assets_url( 'e-select2', 'assets/lib/e-select2/css/' ), + [], + '4.0.6-rc.1' + ); + + wp_register_script( + 'select2', + $this->get_js_assets_url( 'e-select2.full', 'assets/lib/e-select2/js/' ), + [ + 'jquery', + ], + '4.0.6-rc.1', + true + ); + + wp_register_style( + 'elementor-icons', + $this->get_css_assets_url( 'elementor-icons', 'assets/lib/eicons/css/' ), + [], + Icons_Manager::ELEMENTOR_ICONS_VERSION + ); + + wp_enqueue_script( 'react' ); + wp_enqueue_script( 'react-dom' ); + + wp_enqueue_script( + 'elementor-app-packages', + $this->get_js_assets_url( 'app-packages' ), + [ + 'wp-i18n', + 'react', + ], + ELEMENTOR_VERSION, + true + ); + + add_action( 'elementor-pro/metabox/render', function ( $metabox, $post_id ) { + $min_suffix = Utils::is_script_debug() ? '' : '.min'; + + wp_enqueue_script( + 'tipsy', + ELEMENTOR_ASSETS_URL . 'lib/tipsy/tipsy' . $min_suffix . '.js', + [ + 'jquery', + ], + '1.0.0', + true + ); + + wp_enqueue_style( + 'custom-code', + ELEMENTOR_PRO_ASSETS_URL . 'css/modules/custom-code' . $min_suffix . '.css', + [ + 'elementor-app-base', + ], + ELEMENTOR_PRO_VERSION + ); + + // Load 'admin.js` module JS entry. + wp_enqueue_script( + 'custom-code-metabox', + ELEMENTOR_PRO_ASSETS_URL . 'js/custom-code' . $min_suffix . '.js', + [ + 'elementor-v2-ui', + 'elementor-v2-icons', + 'react', + 'select2', + // Temporary dependency until we will have a better way to load AI app in the admin. + 'elementor-ai-admin', + ], + ELEMENTOR_PRO_VERSION + ); + + $post = [ + 'ID' => $post_id, + 'post_status' => get_post_status( $post_id ), + ]; + + wp_add_inline_script( 'custom-code-metabox', sprintf( 'elementorProAdmin.customCode.post = %s;', wp_json_encode( $post ) ) ); + }, 10, 2 ); + } + + private function add_admin_menu( Admin_Menu_Manager $admin_menu_manager ) { + if ( $this->can_use_custom_code() ) { + $admin_menu_manager->register( static::MENU_SLUG, new Custom_Code_Menu_Item() ); + } + } + + private function can_use_custom_code() { + return ( API::is_license_active() && API::is_licence_has_feature( static::MODULE_NAME, API::BC_VALIDATION_CALLBACK ) || $this->has_custom_code_snippets() ); + } + + private function has_custom_code_snippets() { + $existing_snippets = get_posts( [ + 'posts_per_page' => 1, // Avoid fetching too much data + 'post_type' => static::CPT, + ] ); + + return ! empty( $existing_snippets ); + } + + private function register_documents( Documents_Manager $documents_manager ) { + $documents_manager->register_document_type( self::DOCUMENT_TYPE, Document::get_class_full_name() ); + } + + private function register_location( Locations_Manager $location_manager ) { + foreach ( array_keys( $this->meta_box->get_location_options() ) as $location ) { + $location_manager->register_location( $location, [ + 'multiple' => true, + 'public' => false, + 'edit_in_content' => false, + ] ); + } + } + + private function maybe_render_blank_state( $which ) { + $counts = (array) wp_count_posts( self::CPT ); + unset( $counts['auto-draft'] ); + + if ( ! array_sum( $counts ) ) { + /** @var Source_Local $source */ + $source = Plugin::elementor()->templates_manager->get_source( 'local' ); + + $source->maybe_render_blank_state( $which, [ + 'post_type' => self::DOCUMENT_TYPE, + 'cpt' => self::CPT, + 'description' => esc_html__( 'Add pixels, meta tags and any other scripts to your site.', 'elementor-pro' ) . sprintf( '
      %s', esc_html__( 'Learn more about adding custom code', 'elementor-pro' ) ), + 'href' => esc_url( admin_url( '/post-new.php?post_type=' . self::CPT ) ), + ] ); + } + } + + private function manage_posts_columns( $columns ) { + $new = [ + self::ADDITIONAL_COLUMN_INSTANCES => esc_html__( 'Instances', 'elementor-pro' ), + Custom_Code_Metabox::FIELD_LOCATION => esc_html__( 'Location', 'elementor-pro' ), + Custom_Code_Metabox::FIELD_PRIORITY => esc_html__( 'Priority', 'elementor-pro' ), + ]; + + // Insert after 'author'. + $keys = array_keys( $columns ); + $pos = array_search( 'author', $keys ) + 1; + $columns = array_merge( array_slice( $columns, 0, $pos ), $new, array_slice( $columns, $pos ) ); + + return $columns; + } + + private function manage_posts_custom_column( $column_name, $post_id ) { + if ( in_array( $column_name, Custom_Code_Metabox::INPUT_FIELDS ) ) { + $value = get_post_meta( $post_id, '_elementor_' . $column_name, true ); + + if ( Custom_Code_Metabox::FIELD_LOCATION === $column_name ) { + $location_labels = $this->meta_box->get_location_labels(); + + if ( isset( $location_labels[ $value ] ) ) { + $value = $location_labels[ $value ]; + } + } + + echo esc_html( $value ); + } elseif ( self::ADDITIONAL_COLUMN_INSTANCES === $column_name ) { + /** @var Conditions_Manager $conditions_manager */ + $conditions_manager = Plugin::instance()->modules_manager->get_modules( 'theme-builder' )->get_conditions_manager(); + + echo esc_html( implode( ', ', $conditions_manager->get_document_instances( $post_id ) ) ); + } + } + + private function get_snippets_by_location( $location ) { + return get_posts( [ + 'numberposts' => -1, + 'post_type' => self::CPT, + 'meta_query' => [ + [ + 'key' => '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, + 'value' => $location, + ], + ], + // Order. + 'order' => 'ASC', + 'orderby' => 'meta_value_num', + 'meta_key' => '_elementor_' . Custom_Code_Metabox::FIELD_PRIORITY, + ] ); + } + + private function print_snippets( $location ) { + // Do not print snippets on safe mode. + if ( isset( $_REQUEST['elementor-mode'] ) && 'safe' === $_REQUEST['elementor-mode'] ) { + return; + } + + $snippets = $this->get_snippets_by_location( $location ); + + /** @var \ElementorPro\Modules\ThemeBuilder\Module $theme_builder */ + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + $documents_by_conditions = $theme_builder->get_conditions_manager()->get_documents_for_location( $location ); + $location_manager = $theme_builder->get_locations_manager(); + + foreach ( $snippets as $snippet ) { + // Add snippet to location. + // Also handling situation without conditions, bind current snippet id with current location. + if ( isset( $documents_by_conditions[ $snippet->ID ] ) || ! get_post_meta( $snippet->ID, '_elementor_conditions', true ) ) { + $location_manager->add_doc_to_location( $location, $snippet->ID ); + } + } + + elementor_theme_do_location( $location ); + } + + private function register_rest_meta_fields() { + $this->register_rest_meta_location(); + $this->register_rest_meta_priority(); + $this->register_rest_meta_code(); + } + + private function register_rest_meta_location() { + $enum = [ + Custom_Code_Metabox::OPTION_LOCATION_HEAD, + Custom_Code_Metabox::OPTION_LOCATION_BODY_START, + Custom_Code_Metabox::OPTION_LOCATION_BODY_END, + ]; + register_meta( 'post', '_elementor_' . Custom_Code_Metabox::FIELD_LOCATION, [ + 'object_subtype' => self::CPT, + 'show_in_rest' => [ + 'schema' => [ + 'type' => 'string', + 'enum' => $enum, + ], + ], + 'single' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'auth_callback' => function( $allowed, $meta_key, $object_id ) { + $post = get_post( $object_id ); + if ( ! $post || self::CPT !== $post->post_type ) { + return false; + } + return current_user_can( self::CAPABILITY ); + }, + 'default' => Custom_Code_Metabox::DEFAULT_LOCATION, + ] ); + } + + private function register_rest_meta_priority() { + register_meta( 'post', '_elementor_' . Custom_Code_Metabox::FIELD_PRIORITY, [ + 'object_subtype' => self::CPT, + 'show_in_rest' => [ + 'schema' => [ 'type' => 'integer' ], + ], + 'single' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'auth_callback' => function( $allowed, $meta_key, $object_id ) { + $post = get_post( $object_id ); + if ( ! $post || self::CPT !== $post->post_type ) { + return false; + } + return current_user_can( self::CAPABILITY ); + }, + 'default' => Custom_Code_Metabox::DEFAULT_PRIORITY, + ] ); + } + + private function register_rest_meta_code() { + register_meta( 'post', '_elementor_' . Custom_Code_Metabox::FIELD_CODE, [ + 'object_subtype' => self::CPT, + 'show_in_rest' => [ + 'schema' => [ 'type' => 'string' ], + ], + 'single' => true, + 'type' => 'string', + 'auth_callback' => function( $allowed, $meta_key, $object_id ) { + $post = get_post( $object_id ); + if ( ! $post || self::CPT !== $post->post_type ) { + return false; + } + return current_user_can( self::CAPABILITY ); + }, + 'sanitize_callback' => function( $value ) { + if ( ! current_user_can( 'unfiltered_html' ) ) { + return wp_kses_post( $value ); + } + return $value; + }, + ] ); + } + + private function register_import_export() { + ( new Custom_Code_Import_Export() )->register_hooks(); + ( new Custom_Code_Import_Export_Customization() )->register_hooks(); + } +} diff --git a/modules/custom-css/admin-menu-items/settings-custom-css-pro.php b/modules/custom-css/admin-menu-items/settings-custom-css-pro.php new file mode 100644 index 00000000..0aa78ac0 --- /dev/null +++ b/modules/custom-css/admin-menu-items/settings-custom-css-pro.php @@ -0,0 +1,24 @@ + esc_html__( 'Meet Our Custom CSS', 'elementor-pro' ), + 'messages' => [ + esc_html__( 'Apply CSS globally across your site to elevate your designs.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-global-css/', + ]; + + $promotion_data = Filtered_Promotions_Manager::get_filtered_promotion_data( $promotion_data, 'elementor-pro/advanced-custom-css-promotion-pro-settings/promotion', 'link' ); + $template = Tiers::get_promotion_template( $promotion_data ); + + Custom_Css::instance()->replace_controls_with_upgrade_promotion( $this->parent, $this->get_id(), $template ); + } +} diff --git a/modules/custom-css/module.php b/modules/custom-css/module.php new file mode 100644 index 00000000..7c3d8732 --- /dev/null +++ b/modules/custom-css/module.php @@ -0,0 +1,185 @@ +add_actions(); + } + + public function get_name() { + return 'custom-css'; + } + + /** + * @param $element Controls_Stack + * @param $section_id string + */ + public function register_controls( Controls_Stack $element, $section_id ) { + // Remove Custom CSS Banner (From free version) + if ( 'section_custom_css_pro' !== $section_id ) { + return; + } + + $old_section = Plugin::elementor()->controls_manager->get_control_from_stack( $element->get_unique_name(), 'section_custom_css_pro' ); + + if ( ! API::is_licence_has_feature( static::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $promotion_data = [ + 'title' => esc_html__( 'Meet Our Custom CSS', 'elementor-pro' ), + 'messages' => [ + esc_html__( 'Apply CSS to any widget and elevate any element with Custom CSS.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-custom-css/', + ]; + + $promotion_data = Filtered_Promotions_Manager::get_filtered_promotion_data( $promotion_data, 'elementor-pro/advanced-custom-css-promotion-pro-widget/promotion', 'link' ); + $template = Tiers::get_promotion_template( $promotion_data ); + $this->replace_controls_with_upgrade_promotion( $element, $old_section['tab'], $template ); + return; + } + + $this->replace_go_pro_custom_css_controls( $element ); + } + + /** + * @param $post_css Post + * @param $element Element_Base + */ + public function add_post_css( $post_css, $element ) { + if ( $post_css instanceof Dynamic_CSS ) { + return; + } + + $element_settings = $element->get_settings(); + + if ( empty( $element_settings['custom_css'] ) ) { + return; + } + + $css = trim( $element_settings['custom_css'] ); + + if ( empty( $css ) ) { + return; + } + $css = str_replace( 'selector', $post_css->get_element_unique_selector( $element ), $css ); + + // Add a css comment + $css = sprintf( '/* Start custom CSS for %s, class: %s */', $element->get_name(), $element->get_unique_selector() ) . $css . '/* End custom CSS */'; + + $post_css->get_stylesheet()->add_raw_css( $css ); + } + + /** + * @param $post_css Post + */ + public function add_page_settings_css( $post_css ) { + $document = Plugin::elementor()->documents->get( $post_css->get_post_id() ); + $custom_css = $document->get_settings( 'custom_css' ) ?? ''; + + $custom_css = trim( $custom_css ); + + if ( empty( $custom_css ) ) { + return; + } + + $custom_css = str_replace( 'selector', $document->get_css_wrapper_selector(), $custom_css ); + + // Add a css comment + $custom_css = '/* Start custom CSS */' . $custom_css . '/* End custom CSS */'; + + $post_css->get_stylesheet()->add_raw_css( $custom_css ); + } + + /** + * @param Controls_Stack $controls_stack + */ + public function replace_go_pro_custom_css_controls( $controls_stack ) { + $old_section = Plugin::elementor()->controls_manager->get_control_from_stack( $controls_stack->get_unique_name(), 'section_custom_css_pro' ); + + Plugin::elementor()->controls_manager->remove_control_from_stack( $controls_stack->get_unique_name(), [ 'section_custom_css_pro', 'custom_css_pro' ] ); + + $controls_stack->start_controls_section( + 'section_custom_css', + [ + 'label' => esc_html__( 'Custom CSS', 'elementor-pro' ), + 'tab' => $old_section['tab'], + ] + ); + + $controls_stack->add_control( + 'custom_css', + [ + 'label' => esc_html__( 'Add your own custom CSS', 'elementor-pro' ), + 'type' => Controls_Manager::CODE, + 'description' => sprintf( + /* translators: 1: Link opening tag, 2: Link opening tag, 3: Link closing tag. */ + esc_html__( 'Use %1$scustom CSS%3$s to style your content or add %2$sthe "selector" prefix%3$s to target specific elements.', 'elementor-pro' ), + '', + '', + '' + ), + 'language' => 'css', + 'render_type' => 'ui', + ] + ); + + $controls_stack->end_controls_section(); + } + + protected function add_actions() { + add_action( 'elementor/element/after_section_end', [ $this, 'register_controls' ], 10, 2 ); + add_action( 'elementor/element/parse_css', [ $this, 'add_post_css' ], 10, 2 ); + add_action( 'elementor/css-file/post/parse', [ $this, 'add_page_settings_css' ] ); + + // Check license for site settings tabs + if ( ! API::is_licence_has_feature( static::LICENSE_FEATURE_NAME_GLOBAL, API::BC_VALIDATION_CALLBACK ) ) { + add_action( 'elementor/kit/register_tabs', function ( Kit $kit ) { + $kit->register_tab( 'settings-custom-css', Settings_Custom_CSS_Pro::class ); + }, 100 ); + } + } + + public function replace_controls_with_upgrade_promotion( Controls_Stack $controls_stack, $tab, $template ) { + Plugin::elementor()->controls_manager->remove_control_from_stack( $controls_stack->get_unique_name(), [ 'section_custom_css_pro', 'custom_css_pro' ] ); + + $controls_stack->start_controls_section( + 'section_custom_css_promotion', + [ + 'label' => esc_html__( 'Custom CSS', 'elementor-pro' ), + 'tab' => $tab, + ] + ); + + $controls_stack->add_control( + 'custom_css_promotion', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => $template, + ] + ); + + $controls_stack->end_controls_section(); + } +} diff --git a/modules/display-conditions/classes/and-condition.php b/modules/display-conditions/classes/and-condition.php new file mode 100644 index 00000000..ea6f6f8f --- /dev/null +++ b/modules/display-conditions/classes/and-condition.php @@ -0,0 +1,49 @@ +conditions_manager = $conditions_manager; + $this->conditions = $conditions; + } + + public function check() { + foreach ( $this->conditions as $condition_options ) { + $condition_result = $this->is_condition_passing_check( $condition_options ); + + if ( ! $condition_result ) { + return false; + } + } + + return true; + } + + private function is_condition_passing_check( $condition_options ) { + $condition_instance = $this->get_condition_instance( $condition_options ); + + return $condition_instance + ? $condition_instance->check( $condition_options ) + : true; + } + + private function get_condition_instance( $condition ) { + if ( ! isset( $condition['condition'] ) ) { + return false; + } + + return $this->conditions_manager->get_condition( $condition['condition'] ); + } +} diff --git a/modules/display-conditions/classes/cache-notice.php b/modules/display-conditions/classes/cache-notice.php new file mode 100644 index 00000000..82dbdc50 --- /dev/null +++ b/modules/display-conditions/classes/cache-notice.php @@ -0,0 +1,22 @@ + $value_to_check; + case Comparator_Provider::COMPARATOR_IS_AFTER_INCLUSIVE: + return $set_value <= $value_to_check; + case Comparator_Provider::COMPARATOR_IS_BEFORE_INCLUSIVE: + return $set_value >= $value_to_check; + default: + return false; + } + } + + public static function check_array_contains( string $comparator, array $expected_values, array $array_of_values ): bool { + $is_contained = ! empty( array_intersect( $expected_values, $array_of_values ) ); + switch ( $comparator ) { + case Comparator_Provider::COMPARATOR_IS: + case Comparator_Provider::COMPARATOR_IS_ONE_OF: + return $is_contained; + + case Comparator_Provider::COMPARATOR_IS_NOT: + case Comparator_Provider::COMPARATOR_IS_NONE_OF: + return ! $is_contained; + + default: + return false; + } + } + + public static function check_string_contains( string $comparator, string $expected_value, string $actual_value ): bool { + $expected_value = strtolower( $expected_value ); + $actual_value = strtolower( $actual_value ); + + switch ( $comparator ) { + case Comparator_Provider::COMPARATOR_IS: + return $expected_value === $actual_value; + + case Comparator_Provider::COMPARATOR_IS_NOT: + return $expected_value !== $actual_value; + + case Comparator_Provider::COMPARATOR_CONTAINS: + return str_contains( $actual_value, $expected_value ); + + case Comparator_Provider::COMPARATOR_NOT_CONTAIN: + return ! str_contains( $actual_value, $expected_value ); + + default: + return false; + } + } + + public static function check_string_contains_and_empty( string $comparator, string $expected_value, string $actual_value ): bool { + if ( self::check_string_contains( $comparator, $expected_value, $actual_value ) ) { + return true; + } + + switch ( $comparator ) { + case Comparator_Provider::COMPARATOR_IS_EMPTY: + return empty( $actual_value ); + + case Comparator_Provider::COMPARATOR_IS_NOT_EMPTY: + return ! empty( $actual_value ); + + default: + return false; + } + } + + public static function check_equality( string $comparator, string $value, string $compare_to ): bool { + switch ( $comparator ) { + case Comparator_Provider::COMPARATOR_IS: + return $value === $compare_to; + + case Comparator_Provider::COMPARATOR_IS_NOT: + return $value !== $compare_to; + + default: + return false; + } + } + + /** + * @param string $comparator + * @param int $value + * @param int $compare_to + * + * @return bool + */ + public static function check_numeric_constraints( string $comparator, int $value, int $compare_to ): bool { + switch ( $comparator ) { + case Comparator_Provider::COMPARATOR_IS: + return $compare_to === $value; + case Comparator_Provider::COMPARATOR_IS_NOT: + return $compare_to !== $value; + case Comparator_Provider::COMPARATOR_IS_LESS_THAN_INCLUSIVE: + return $compare_to <= $value; + case Comparator_Provider::COMPARATOR_IS_GREATER_THAN_INCLUSIVE: + return $compare_to >= $value; + default: + return false; + } + } +} diff --git a/modules/display-conditions/classes/conditions-manager.php b/modules/display-conditions/classes/conditions-manager.php new file mode 100644 index 00000000..da0dba85 --- /dev/null +++ b/modules/display-conditions/classes/conditions-manager.php @@ -0,0 +1,203 @@ +display_conditions_module = $display_conditions_module; + $this->register_conditions(); + } + + private function init_groups() { + $this->groups = [ + 'page' => [ + 'label' => esc_html__( 'Page', 'elementor-pro' ), + ], + 'post' => [ + 'label' => esc_html__( 'Post', 'elementor-pro' ), + ], + 'user' => [ + 'label' => esc_html__( 'User', 'elementor-pro' ), + ], + 'date' => [ + 'label' => esc_html__( 'Date and Time', 'elementor-pro' ), + ], + 'archive' => [ + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + ], + ]; + + /** + * Registration of a group for the display conditions. + * + * Fires when a new display condition groups is registered. This hook allows developers + * to register new display conditions groups using add_group(). + * + * @param Conditions_Manager $this An instance of conditions manager. + */ + do_action( 'elementor/display_conditions/register_groups', $this ); + + $this->groups['other'] = [ 'label' => esc_html__( 'Other', 'elementor-pro' ) ]; + } + + private function register_condition( $id, $args = [] ) { + if ( isset( $this->conditions[ $id ] ) ) { + return; + } + + $args[] = new Wordpress_Adapter(); + $class_name = '\\ElementorPro\\Modules\\DisplayConditions\\Conditions\\' . $id; + + /** @var Condition_Base $condition */ + $condition = new $class_name( $args ); + + $this->register_condition_instance( $condition ); + } + + /** + * @param Condition_Base $instance + * @return false|void + */ + public function register_condition_instance( Condition_Base $instance ) { + $id = $instance->get_name(); + $is_exist = $this->get_condition( $id ); + + if ( false !== $is_exist ) { + return false; // Already registered. + } + + $this->conditions[ $id ] = $instance; + } + + /** + * Add condition group. + * + * Register new group for the condition. + * + * @access public + * + * @param string $group_name Group name. + * @param array $group_properties Group properties. + */ + public function add_group( $group_name, $group_properties ) { + if ( null === $this->groups ) { + $this->get_groups(); + } + + if ( ! isset( $this->groups[ $group_name ] ) ) { + $this->groups[ $group_name ] = $group_properties; + } + } + + /** + * Get condition groups. + * + * Retrieve the list of groups for the conditions. + * + * @access private + * + * @return array Condition groups. + */ + private function get_groups() { + if ( null === $this->groups ) { + $this->init_groups(); + } + + return $this->groups; + } + + /** + * @param $id + * + * @return Condition_Base|bool + */ + public function get_condition( $id ) { + return isset( $this->conditions[ $id ] ) ? $this->conditions[ $id ] : false; + } + + public function get_conditions_config() { + $config = []; + + $config['conditions'] = []; + + foreach ( $this->conditions as $condition ) { + $config['conditions'][ $condition->get_name() ] = $condition->get_config(); + } + + $config['groups'] = $this->get_groups(); + $config['show_cache_notice'] = $this->display_conditions_module->get_component( 'cache_notice' )->should_show_notice(); + + return $config; + } + + public function register_conditions() { + $conditions = self::CONDITIONS; + + foreach ( $conditions as $condition ) { + $this->register_condition( $condition ); + } + + /** + * Elementor display conditions registration. + * + * Fires when a new display condition is registered. This hook allows developers + * to register new display conditions using register_condition_instance(). + * + * @param Conditions_Manager $this An instance of conditions manager. + */ + do_action( 'elementor/display_conditions/register', $this ); + } +} diff --git a/modules/display-conditions/classes/dynamic-tags/custom-fields-data-provider.php b/modules/display-conditions/classes/dynamic-tags/custom-fields-data-provider.php new file mode 100644 index 00000000..8725a09a --- /dev/null +++ b/modules/display-conditions/classes/dynamic-tags/custom-fields-data-provider.php @@ -0,0 +1,81 @@ +get_custom_fields_options(), $this->get_acf_options() ); + + if ( empty( $combined_options ) ) { + return []; + } + + return $this->get_control_groups() + $combined_options; + } + + private function get_custom_fields_options(): array { + global $wpdb; + + $keys = $wpdb->get_col( + $wpdb->prepare( + "SELECT DISTINCT meta_key + FROM $wpdb->postmeta + WHERE meta_key NOT BETWEEN '_' AND '_z' + HAVING meta_key NOT LIKE %s + ORDER BY meta_key + LIMIT %d", + $wpdb->esc_like( '_' ) . '%', + apply_filters( 'elementor_pro/display_conditions/dynamic_tags/custom_fields_meta_limit', static::CUSTOM_FIELDS_META_LIMIT ) + ) + ); + + return array_combine( $keys, $keys ); + } + + private function get_acf_options(): array { + global $wpdb; + + $acf_keys = $wpdb->get_col( + $wpdb->prepare( + "SELECT post_excerpt + FROM {$wpdb->posts} + WHERE post_type = 'acf-field' AND post_status = %s", + Post_Status::PUBLISH + ) + ); + + return array_combine( $acf_keys, $acf_keys ); + } + + /** + * @param array $args + * + * @return string | bool + */ + public function get_value( array $args ) { + if ( ! metadata_exists( 'post', get_the_ID(), $args['dynamic_tag'] ) ) { + return false; + } + + return get_post_meta( get_the_ID(), $args['dynamic_tag'], true ); + } + + private function get_control_groups(): array { + return [ + 'custom_field' => [ + 'label' => esc_html__( 'Custom Field', 'elementor-pro' ), + 'type' => 'group', + ], + ]; + } +} diff --git a/modules/display-conditions/classes/dynamic-tags/data-provider.php b/modules/display-conditions/classes/dynamic-tags/data-provider.php new file mode 100644 index 00000000..db6feba8 --- /dev/null +++ b/modules/display-conditions/classes/dynamic-tags/data-provider.php @@ -0,0 +1,14 @@ +get_dynamic_tags_options(); + + foreach ( $this->get_control_groups() as $group_key => $group_name ) { + $result[ $group_key ] = [ + 'label' => $group_name, + 'type' => 'group', + ]; + + $group_items = array_filter( $dynamic_tags_options, function( $item ) use ( $group_key ) { + return $group_key === $item['group']; + } ); + + $group_items = array_map( function( $item ) { + return $item['label']; + }, $group_items ); + + $result = $result + $group_items; + } + + return $result; + } + + public function get_default_control_option(): string { + return array_key_first( $this->get_dynamic_tags_options() ); + } + + /** + * @param string $key + * @return array + */ + public function get_dynamic_tag_options( string $key ): array { + $dt_config = $this->get_dynamic_tags_options(); + + return ! empty( $dt_config[ $key ] ) ? $dt_config[ $key ] : []; + } + + /** + * @return array + */ + public function get_dynamic_tags_options(): array { + if ( ! empty( $this->dynamic_tags_options ) ) { + return $this->dynamic_tags_options; + } + + $dynamic_tags_config = Plugin::elementor()->dynamic_tags->get_config(); + + foreach ( $dynamic_tags_config['tags'] as $dynamic_tag_config ) { + if ( empty( $dynamic_tag_config['display_conditions'] ) ) { + continue; + } + + $new_options = array_map( function( $item ) use ( $dynamic_tag_config ) { + return $item + [ 'dynamic_tag_name' => $dynamic_tag_config['name'] ]; + }, $dynamic_tag_config['display_conditions'] ); + + $this->dynamic_tags_options = $this->dynamic_tags_options + $new_options; + } + + return $this->dynamic_tags_options; + } + + /** + * @param array $args + * @return string | bool + */ + public function get_value( array $args ) { + $dt_options = $this->get_dynamic_tag_options( $args['dynamic_tag'] ); + + if ( empty( $dt_options ) ) { + return false; + } + + return Plugin::elementor()->dynamic_tags->get_tag_data_content( null, $dt_options['dynamic_tag_name'], $dt_options['settings'] ) ?? false; + } + + private function get_control_groups(): array { + return [ + 'archive' => esc_html__( 'Archive', 'elementor-pro' ), + 'featured_image' => esc_html__( 'Featured Image', 'elementor-pro' ), + 'author' => esc_html__( 'Author', 'elementor-pro' ), + ]; + } +} diff --git a/modules/display-conditions/classes/or-condition.php b/modules/display-conditions/classes/or-condition.php new file mode 100644 index 00000000..0f0072a1 --- /dev/null +++ b/modules/display-conditions/classes/or-condition.php @@ -0,0 +1,40 @@ +conditions_manager = $conditions_manager; + $this->set_and_conditions( $sets ); + } + + public function check() { + if ( empty( $this->and_conditions ) ) { + return true; + } + + foreach ( $this->and_conditions as $condition ) { + if ( $condition->check() ) { + return true; + } + } + + return false; + } + + private function set_and_conditions( $groups ) { + $this->and_conditions = array_map( function ( $condition ) { + return new And_Condition( $this->conditions_manager, $condition ); + }, $groups ); + } +} diff --git a/modules/display-conditions/conditions/archive-of-author-condition.php b/modules/display-conditions/conditions/archive-of-author-condition.php new file mode 100644 index 00000000..4364b614 --- /dev/null +++ b/modules/display-conditions/conditions/archive-of-author-condition.php @@ -0,0 +1,77 @@ +wordpress_adapter->is_author( $author_ids ); + + case Comparator_Provider::COMPARATOR_IS_NOT: + return ! $this->wordpress_adapter->is_author( $author_ids ); + + default: + return false; + } + + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'authors', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_AUTHOR, + ], + 'multiple' => true, + 'required' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + ] + ); + } +} diff --git a/modules/display-conditions/conditions/archive-of-category-condition.php b/modules/display-conditions/conditions/archive-of-category-condition.php new file mode 100644 index 00000000..4c46b7a5 --- /dev/null +++ b/modules/display-conditions/conditions/archive-of-category-condition.php @@ -0,0 +1,36 @@ +condition_key = $condition_key; + + parent::__construct(); + } + + abstract public function get_name(); + + abstract public function get_label(); + + abstract protected function get_taxonomy(); + + public function get_group(): string { + return 'archive'; + } + + abstract protected function is_of_taxonomy( $args ): bool; + + protected function check_is_of_taxonomy( $args ) { + switch ( $args['comparator'] ) { + case Comparator_Provider::COMPARATOR_IS: + return $this->is_of_taxonomy( $args ); + case Comparator_Provider::COMPARATOR_IS_NOT: + return ! $this->is_of_taxonomy( $args ); + default: + return false; + } + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] ); + $taxonomy = $this->get_taxonomy(); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + $this->condition_key, + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_TAX, + 'query' => [ + 'taxonomy' => $taxonomy, + ], + ], + 'multiple' => true, + 'required' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + ] + ); + } +} diff --git a/modules/display-conditions/conditions/base/condition-base.php b/modules/display-conditions/conditions/base/condition-base.php new file mode 100644 index 00000000..a4b11d06 --- /dev/null +++ b/modules/display-conditions/conditions/base/condition-base.php @@ -0,0 +1,53 @@ +wordpress_adapter = array_pop( $data ); + parent::__construct( $data ); + } + + abstract public function get_label(); + + abstract public function get_options(); + + public function get_group() { + return 'other'; + } + + public function check( $args ) : bool { + return true; + } + + protected function register_controls() { + $this->start_controls_section( + '__settings' + ); + + $this->get_options(); + + $this->end_controls_section(); + } + + protected function get_initial_config() { + $config = parent::get_initial_config(); + + $config['label'] = $this->get_label(); + $config['group'] = $this->get_group(); + + return $config; + } +} diff --git a/modules/display-conditions/conditions/base/date-condition-base.php b/modules/display-conditions/conditions/base/date-condition-base.php new file mode 100644 index 00000000..1e198383 --- /dev/null +++ b/modules/display-conditions/conditions/base/date-condition-base.php @@ -0,0 +1,94 @@ +condition_key = $condition_key; + $this->group_key = $group_key; + } + + public function get_group() { + return $this->group_key; + } + + /** + * @return array + */ + public static function get_time_options(): array { + return [ + self::OPTION_SERVER => esc_html__( 'Server Time', 'elementor-pro' ), + self::OPTION_CLIENT => esc_html__( 'Visitor Time', 'elementor-pro' ), + ]; + } + + protected function check_date( $args, $date_to_check ): bool { + $comparator = $args[ self::COMPARATOR_KEY ]; + $date_string = $args[ $this->condition_key ]; + $set_date = date_create_from_format( self::DATE_FORMAT, $date_string ); + + if ( ! $set_date || ! $date_to_check || ! $comparator || $set_date->format( self::DATE_FORMAT ) !== $date_string ) { + return false; + } + + return Comparators_Checker::check_date_time( $comparator, $date_to_check, $set_date ); + } + + public function get_options() { + $this->add_control( + self::COMPARATOR_KEY, + [ + 'type' => Controls_Manager::SELECT, + 'options' => Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + Comparator_Provider::COMPARATOR_IS_BEFORE, + Comparator_Provider::COMPARATOR_IS_AFTER, + Comparator_Provider::COMPARATOR_IS_BEFORE_INCLUSIVE, + Comparator_Provider::COMPARATOR_IS_AFTER_INCLUSIVE, + ] + ), + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + $this->condition_key, + [ + 'type' => Controls_Manager::DATE_TIME, + 'label' => $this::get_label(), + 'variant' => 'date', + 'required' => true, + ] + ); + + $this->add_control( + self::OPTION_KEY, + [ + 'type' => Controls_Manager::SELECT, + 'options' => self::get_time_options(), + 'default' => self::OPTION_SERVER, + 'disabled_options' => [ self::OPTION_CLIENT ], + ] + ); + } +} diff --git a/modules/display-conditions/conditions/base/title-condition-base.php b/modules/display-conditions/conditions/base/title-condition-base.php new file mode 100644 index 00000000..d0e965d7 --- /dev/null +++ b/modules/display-conditions/conditions/base/title-condition-base.php @@ -0,0 +1,53 @@ +add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'titles', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_POST, + 'query' => $this->get_query(), + ], + 'multiple' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + 'required' => true, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/current-date-condition.php b/modules/display-conditions/conditions/current-date-condition.php new file mode 100644 index 00000000..a8a202ad --- /dev/null +++ b/modules/display-conditions/conditions/current-date-condition.php @@ -0,0 +1,37 @@ +get_current_date() ); + } + + /** + * @return \DateTime|false + */ + private function get_current_date() { + return date_create_from_format( self::DATE_FORMAT, gmdate( self::DATE_FORMAT ) ); + } +} diff --git a/modules/display-conditions/conditions/date-of-modification-condition.php b/modules/display-conditions/conditions/date-of-modification-condition.php new file mode 100644 index 00000000..6ee91766 --- /dev/null +++ b/modules/display-conditions/conditions/date-of-modification-condition.php @@ -0,0 +1,41 @@ +get_modification_date() ); + } + + private function get_modification_date() { + return date_create_from_format( + self::DATE_FORMAT, + get_the_modified_date( self::DATE_FORMAT, get_the_ID() ) + ); + } +} diff --git a/modules/display-conditions/conditions/date-of-publish-condition.php b/modules/display-conditions/conditions/date-of-publish-condition.php new file mode 100644 index 00000000..04d540c3 --- /dev/null +++ b/modules/display-conditions/conditions/date-of-publish-condition.php @@ -0,0 +1,40 @@ +get_post_date() ); + } + + private function get_post_date() { + return date_create_from_format( + self::DATE_FORMAT, + get_the_date( self::DATE_FORMAT, get_the_ID() ) + ); + } +} diff --git a/modules/display-conditions/conditions/day-of-the-week-condition.php b/modules/display-conditions/conditions/day-of-the-week-condition.php new file mode 100644 index 00000000..4a0813ac --- /dev/null +++ b/modules/display-conditions/conditions/day-of-the-week-condition.php @@ -0,0 +1,78 @@ +add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS_ONE_OF, + ] + ); + + $this->add_control( + self::CONDITION_KEY, + [ + 'type' => Controls_Manager::SELECT2, + 'options' => [ + 'monday' => esc_html__( 'Monday', 'elementor-pro' ), + 'tuesday' => esc_html__( 'Tuesday', 'elementor-pro' ), + 'wednesday' => esc_html__( 'Wednesday', 'elementor-pro' ), + 'thursday' => esc_html__( 'Thursday', 'elementor-pro' ), + 'friday' => esc_html__( 'Friday', 'elementor-pro' ), + 'saturday' => esc_html__( 'Saturday', 'elementor-pro' ), + 'sunday' => esc_html__( 'Sunday', 'elementor-pro' ), + ], + 'multiple' => true, + 'required' => true, + ] + ); + + $this->add_control( + 'time_type', + [ + 'type' => Controls_Manager::SELECT, + 'options' => Date_Condition_Base::get_time_options(), + 'default' => Date_Condition_Base::OPTION_SERVER, + 'disabled_options' => [ Date_Condition_Base::OPTION_CLIENT ], + ] + ); + } +} diff --git a/modules/display-conditions/conditions/dynamic-tags-condition.php b/modules/display-conditions/conditions/dynamic-tags-condition.php new file mode 100644 index 00000000..22991c9b --- /dev/null +++ b/modules/display-conditions/conditions/dynamic-tags-condition.php @@ -0,0 +1,110 @@ +dynamic_tags_data_provider = new Dynamic_Tags_Data_Provider(); + $this->custom_fields_data_provider = new Custom_Fields_Data_Provider(); + } + + public function get_name() { + return 'dynamic_tags'; + } + + public function get_label() { + return esc_html__( 'Dynamic Tags', 'elementor-pro' ); + } + + public function get_group() { + return 'other'; + } + + public function check( $args ) : bool { + $value = $this->get_condition_value( $args ); + + if ( false === $value ) { + return false; + } + + return Comparators_Checker::check_string_contains_and_empty( $args['comparator'], $args['dynamic_tag_value'], $value ); + } + + public function get_options() { + $this->add_control( + 'dynamic_tag', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $this->dynamic_tags_data_provider->get_control_options() + $this->custom_fields_data_provider->get_control_options(), + 'default' => $this->dynamic_tags_data_provider->get_default_control_option(), + 'disabled_options' => ! current_user_can( 'manage_options' ) ? [ 'author_info_email' ] : [], + 'disabled_type' => 'hidden', + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + Comparator_Provider::COMPARATOR_CONTAINS, + Comparator_Provider::COMPARATOR_NOT_CONTAIN, + Comparator_Provider::COMPARATOR_IS_EMPTY, + Comparator_Provider::COMPARATOR_IS_NOT_EMPTY, + ] + ), + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'dynamic_tag_value', + [ + 'placeholder' => esc_html__( 'Type a value', 'elementor-pro' ), + 'required' => true, + ] + ); + } + + /** + * Conditionally retrieve the value of a dynamic tag or custom field. + * + * @return string | bool + */ + private function get_condition_value( array $args ) { + $dt_value = $this->dynamic_tags_data_provider->get_value( $args ); + + if ( $dt_value ) { + return $dt_value; + } + + return $this->custom_fields_data_provider->get_value( $args ); + } +} diff --git a/modules/display-conditions/conditions/featured-image-condition.php b/modules/display-conditions/conditions/featured-image-condition.php new file mode 100644 index 00000000..3ef28380 --- /dev/null +++ b/modules/display-conditions/conditions/featured-image-condition.php @@ -0,0 +1,63 @@ +wordpress_adapter->has_post_thumbnail() + ); + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'status', + [ + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'set' => esc_html__( 'Set', 'elementor-pro' ), + 'not_set' => esc_html__( 'Not Set', 'elementor-pro' ), + ], + 'default' => 'set', + ] + ); + } +} diff --git a/modules/display-conditions/conditions/from-url-condition.php b/modules/display-conditions/conditions/from-url-condition.php new file mode 100644 index 00000000..b08215ea --- /dev/null +++ b/modules/display-conditions/conditions/from-url-condition.php @@ -0,0 +1,62 @@ +add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'from_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'URL', 'elementor-pro' ), + 'required' => true, + ] + ); + } + + public function get_name() { + return 'from_url'; + } + + public function wp_get_referer() { + return wp_get_raw_referer(); + } + + public function check( $args ) : bool { + $referrer = $this->wp_get_referer(); + + return Comparators_Checker::check_string_contains( $args['comparator'], $args['from_url'], $referrer ); + } +} diff --git a/modules/display-conditions/conditions/in-categories-condition.php b/modules/display-conditions/conditions/in-categories-condition.php new file mode 100644 index 00000000..815fb618 --- /dev/null +++ b/modules/display-conditions/conditions/in-categories-condition.php @@ -0,0 +1,77 @@ + 'ids' ] ) ?? []; + + if ( empty( $post_categories ) ) { + return ! ( Comparator_Provider::COMPARATOR_IS === $args['comparator'] ); + } + + $category_ids = array_column( $args['categories'], 'id' ); + + return Comparators_Checker::check_array_contains( $args['comparator'], $category_ids, $post_categories ); + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'categories', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_TAX, + 'query' => [ + 'taxonomy' => 'category', + ], + ], + 'multiple' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + 'required' => true, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/in-tags-condition.php b/modules/display-conditions/conditions/in-tags-condition.php new file mode 100644 index 00000000..c898fae3 --- /dev/null +++ b/modules/display-conditions/conditions/in-tags-condition.php @@ -0,0 +1,73 @@ + 'ids' ] ) ?? []; + + $tag_ids = array_column( $args['tags'], 'id' ); + + return Comparators_Checker::check_array_contains( $args['comparator'], $tag_ids, $post_tags ); + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'tags', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_TAX, + 'query' => [ + 'taxonomy' => 'post_tag', + ], + ], + 'multiple' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + 'required' => true, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/login-status-condition.php b/modules/display-conditions/conditions/login-status-condition.php new file mode 100644 index 00000000..b76ff1e3 --- /dev/null +++ b/modules/display-conditions/conditions/login-status-condition.php @@ -0,0 +1,59 @@ +add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'status', + [ + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'logged_in' => esc_html__( 'Logged In', 'elementor-pro' ), + 'logged_out' => esc_html__( 'Logged Out', 'elementor-pro' ), + ], + 'default' => 'logged_in', + ] + ); + } +} diff --git a/modules/display-conditions/conditions/page-author-condition.php b/modules/display-conditions/conditions/page-author-condition.php new file mode 100644 index 00000000..724be886 --- /dev/null +++ b/modules/display-conditions/conditions/page-author-condition.php @@ -0,0 +1,76 @@ +post_author ], $author_ids ); + + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'authors', + [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_AUTHOR, + ], + 'multiple' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + 'required' => true, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/page-parent-condition.php b/modules/display-conditions/conditions/page-parent-condition.php new file mode 100644 index 00000000..f71da321 --- /dev/null +++ b/modules/display-conditions/conditions/page-parent-condition.php @@ -0,0 +1,74 @@ +post_parent ], $parent_page_ids ); + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS_ONE_OF, + Comparator_Provider::COMPARATOR_IS_NONE_OF, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS_ONE_OF, + ] + ); + + $this->add_control( + 'pages', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_status' => 'publish', + 'post_type' => 'page', + ], + ], + 'multiple' => true, + 'placeholder' => esc_html__( 'Type to search', 'elementor-pro' ), + 'required' => true, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/page-title-condition.php b/modules/display-conditions/conditions/page-title-condition.php new file mode 100644 index 00000000..ebc632ae --- /dev/null +++ b/modules/display-conditions/conditions/page-title-condition.php @@ -0,0 +1,27 @@ + 'publish', + 'post_type' => 'page', + ]; + } +} diff --git a/modules/display-conditions/conditions/post-author-condition.php b/modules/display-conditions/conditions/post-author-condition.php new file mode 100644 index 00000000..c9f04f63 --- /dev/null +++ b/modules/display-conditions/conditions/post-author-condition.php @@ -0,0 +1,13 @@ +wordpress_adapter->get_comments_number(); + + return Comparators_Checker::check_numeric_constraints( $args['comparator'], (int) $args['number_of_comments'], (int) $actual_number_of_comments ); + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS_GREATER_THAN_INCLUSIVE, + Comparator_Provider::COMPARATOR_IS_LESS_THAN_INCLUSIVE, + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'number_of_comments', + [ + 'type' => Controls_Manager::TEXT, + 'input_type' => 'number', + 'variant' => 'number', + 'placeholder' => 'Type a number...', + 'step' => 1, + 'min' => 0, + 'default' => 1, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/post-title-condition.php b/modules/display-conditions/conditions/post-title-condition.php new file mode 100644 index 00000000..9839cfba --- /dev/null +++ b/modules/display-conditions/conditions/post-title-condition.php @@ -0,0 +1,26 @@ + 'publish', + 'post_type' => 'post', + ]; + } +} diff --git a/modules/display-conditions/conditions/time-of-the-day-condition.php b/modules/display-conditions/conditions/time-of-the-day-condition.php new file mode 100644 index 00000000..557a0e2a --- /dev/null +++ b/modules/display-conditions/conditions/time-of-the-day-condition.php @@ -0,0 +1,111 @@ +get_gm_date(); + $expected_time = $this->convert_date_time_to_24_hour_format( $args['time'] ); + + return Comparators_Checker::check_date_time( $args['comparator'], $time_now, $expected_time ); + + } + + /** + * @param $date_time_string + * @return string + * @throws \Exception + */ + public function convert_date_time_to_24_hour_format( $date_time_string ): string { + + if ( ! $this->is_valid_date_time_string( $date_time_string ) ) { + return ''; + } + + $date_time = DateTime::createFromFormat( 'm-d-Y H:i', $date_time_string ); + + return $date_time->format( 'H:i' ); + } + + private function is_valid_date_time_string( $date_time_string ): bool { + $date_time = DateTime::createFromFormat( 'm-d-Y H:i', $date_time_string ); + + if ( ! $date_time || $date_time->format( 'm-d-Y H:i' ) !== $date_time_string ) { + return false; + } + + return true; + } + + public function get_options() { + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS, + Comparator_Provider::COMPARATOR_IS_NOT, + Comparator_Provider::COMPARATOR_IS_BEFORE, + Comparator_Provider::COMPARATOR_IS_AFTER, + Comparator_Provider::COMPARATOR_IS_BEFORE_INCLUSIVE, + Comparator_Provider::COMPARATOR_IS_AFTER_INCLUSIVE, + ] + ); + + $this->add_control( + 'comparator', + [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS, + ] + ); + + $this->add_control( + 'time', + [ + 'type' => Controls_Manager::DATE_TIME, + 'variant' => 'time', + 'required' => true, + ] + ); + + $this->add_control( + 'time_type', + [ + 'type' => Controls_Manager::SELECT, + 'options' => Date_Condition_Base::get_time_options(), + 'default' => Date_Condition_Base::OPTION_SERVER, + 'disabled_options' => Date_Condition_Base::OPTION_CLIENT, + ] + ); + } +} diff --git a/modules/display-conditions/conditions/user-registration-date-condition.php b/modules/display-conditions/conditions/user-registration-date-condition.php new file mode 100644 index 00000000..24d5870d --- /dev/null +++ b/modules/display-conditions/conditions/user-registration-date-condition.php @@ -0,0 +1,40 @@ +get_user_registration_date() ); + } + + private function get_user_registration_date() { + $registration_date = date_create( wp_get_current_user()->user_registered )->format( self::DATE_FORMAT ); + $registration_date = date_create_from_format( self::DATE_FORMAT, $registration_date ); + + return $registration_date; + } +} diff --git a/modules/display-conditions/conditions/user-role-condition.php b/modules/display-conditions/conditions/user-role-condition.php new file mode 100644 index 00000000..e76b07df --- /dev/null +++ b/modules/display-conditions/conditions/user-role-condition.php @@ -0,0 +1,70 @@ +roles : []; + + return Comparators_Checker::check_array_contains( $args['comparator'], $current_user_roles, $args['roles'] ); + } + + public function get_options() { + $user_roles = $this->get_available_roles(); + + $comparators = Comparator_Provider::get_comparators( + [ + Comparator_Provider::COMPARATOR_IS_ONE_OF, + Comparator_Provider::COMPARATOR_IS_NONE_OF, + ] + ); + + $this->add_control( 'comparator', [ + 'type' => Controls_Manager::SELECT, + 'options' => $comparators, + 'default' => Comparator_Provider::COMPARATOR_IS_ONE_OF, + ] ); + + $this->add_control( self::CONDITION_KEY, [ + 'type' => Controls_Manager::SELECT2, + 'options' => $user_roles, + 'multiple' => true, + 'required' => true, + 'default' => [], + ] ); + } + + private function get_available_roles(): array { + $user_roles = []; + + foreach ( get_editable_roles() as $role_slug => $role_data ) { + $role = $role_data['name']; + $user_roles[ $role_slug ] = esc_html( $role ); + } + + return $user_roles; + } +} diff --git a/modules/display-conditions/module.php b/modules/display-conditions/module.php new file mode 100644 index 00000000..57db7a24 --- /dev/null +++ b/modules/display-conditions/module.php @@ -0,0 +1,261 @@ +add_common_actions(); + return; + } + + $this->maybe_add_actions_and_components(); + } + + public static function should_show_promo(): bool { + return ! self::can_use_display_conditions(); + } + + private function add_actions() { + $this->add_render_actions(); + + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + add_filter( 'elementor/element/is_dynamic_content', [ $this, 'filter_element_caching_is_dynamic_content' ], 10, 3 ); + } + + private function add_components() { + $this->add_component( 'conditions', new Classes\Conditions_Manager( $this ) ); + $this->add_component( 'cache_notice', new Classes\Cache_Notice() ); + } + + private function add_common_actions() { + $this->add_advanced_tab_actions(); + + add_action( 'elementor/editor/before_enqueue_scripts', function() { + $this->enqueue_main_script(); + } ); + } + + private function enqueue_main_script() { + $min_suffix = Utils::is_script_debug() ? '' : '.min'; + + wp_enqueue_script( + 'e-display-conditions', + ELEMENTOR_PRO_ASSETS_URL . 'js/display-conditions' . $min_suffix . '.js', + [ + 'react', + 'react-dom', + 'backbone-marionette', + 'elementor-web-cli', + 'wp-date', + 'elementor-common', + 'elementor-editor-modules', + 'elementor-editor-document', + 'elementor-v2-ui', + 'elementor-v2-icons', + ], + ELEMENTOR_PRO_VERSION, + true + ); + + wp_set_script_translations( 'e-display-conditions', 'elementor-pro' ); + } + + private function add_advanced_tab_actions() { + $hooks = [ + 'elementor/element/section/section_advanced/after_section_end' => 'css_classes', // Sections + 'elementor/element/column/section_advanced/after_section_end' => 'css_classes', // Columns + 'elementor/element/common/_section_style/after_section_end' => '_css_classes', // Widgets + 'elementor/element/container/section_layout/after_section_end' => 'css_classes', // Containers + ]; + + foreach ( $hooks as $hook => $injection_position ) { + add_action( + $hook, + function( $element, $args ) use ( $injection_position ) { + $this->add_control_to_advanced_tab( $element, $args, $injection_position ); + }, + 10, + 2 + ); + } + } + + protected function add_render_actions() { + $element_types = [ + 'section', + 'column', + 'widget', + 'container', + ]; + + foreach ( $element_types as $el ) { + add_action( 'elementor/frontend/' . $el . '/before_render', [ $this, 'before_element_render' ] ); + add_action( 'elementor/frontend/' . $el . '/after_render', [ $this, 'after_element_render' ] ); + } + } + + private function add_control_to_advanced_tab( $element, $args, $injection_position ) { + $element->start_injection( + [ + 'of' => $injection_position, + ] + ); + + $element->add_control( + 'e_display_conditions_trigger', + [ + 'type' => Controls_Manager::RAW_HTML, + 'separator' => 'before', + 'raw' => $this->get_display_conditions_control_template(), + ] + ); + + $element->add_control( + 'e_display_conditions', + [ + 'type' => Controls_Manager::HIDDEN, + ] + ); + + $element->end_injection(); + } + + private function get_display_conditions_control_template() { + $icon_class = 'e-control-display-conditions'; + $show_promo = self::should_show_promo(); + + if ( $show_promo ) { + $icon_class .= '-promo'; + } + + ob_start(); + ?> +
      + + + + + + + +
      + get_settings_for_display(); + $is_visible = true; + $saved_conditions = $this->get_saved_conditions( $settings ); + + if ( empty( $settings['e_display_conditions'] ) || Plugin::elementor()->editor->is_edit_mode() || empty( $saved_conditions ) ) { + return $is_visible; + } + + $saved_conditions = $this->get_converted_conditions( $saved_conditions ); + $saved_conditions = new Or_Condition( $this->get_conditions_manager(), $saved_conditions ); + $is_visible = $saved_conditions->check(); + + if ( ! $is_visible ) { + add_filter( 'elementor/element/get_child_type', '__return_false' ); // Prevent getting content of inner elements. + add_filter( 'elementor/frontend/' . $element->get_type() . '/should_render', '__return_false' ); + + $this->hidden_elements_ids[] = $element->get_id(); + } + } + + public function after_element_render( $element ) { + if ( ! in_array( $element->get_id(), $this->hidden_elements_ids, true ) ) { + return; + } + + remove_filter( 'elementor/element/get_child_type', '__return_false' ); + remove_filter( 'elementor/frontend/' . $element->get_type() . '/should_render', '__return_false' ); + } + + /** + * @return string + */ + public function get_name() { + return static::LICENSE_FEATURE_NAME; + } + + /** + * @return Classes\Conditions_Manager + */ + public function get_conditions_manager() { + return $this->get_component( 'conditions' ); + } + + /** + * @param Ajax $ajax_manager + */ + public function register_ajax_actions( $ajax_manager ) { + $ajax_manager->register_ajax_action( 'display_conditions_set_cache_notice_status', [ $this->get_component( 'cache_notice' ), 'set_notice_status' ] ); + } + + public function filter_element_caching_is_dynamic_content( $is_dynamic_content, $element_rqw_data, $element_instance ) { + if ( ! empty( $element_rqw_data['settings']['e_display_conditions'] ) ) { + $is_dynamic_content = true; + } + + return $is_dynamic_content; + } + + /** + * @return bool + */ + public static function can_use_display_conditions(): bool { + if ( is_admin() ) { + return API::is_license_active() && API::is_licence_has_feature( self::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ); + } + + return API::is_licence_has_feature( self::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ); + } + + /** + * @return void + */ + private function maybe_add_actions_and_components(): void { + $this->add_common_actions(); + $this->add_actions(); + $this->add_components(); + } + + private function get_converted_conditions( $conditions ) { + foreach ( $conditions as $condition ) { + if ( ! isset( $condition['condition'] ) ) { + return $conditions; + } + } + return count( $conditions ) + ? [ $conditions ] + : []; + } +} diff --git a/modules/dynamic-tags/acf/dynamic-value-provider.php b/modules/dynamic-tags/acf/dynamic-value-provider.php new file mode 100644 index 00000000..456d6263 --- /dev/null +++ b/modules/dynamic-tags/acf/dynamic-value-provider.php @@ -0,0 +1,63 @@ +get_taxonomy_field_data( $field_key, $meta_key ); + } + + $document = Plugin::elementor()->documents->get_current(); + + if ( 'options' === $field_key ) { + $field = $this->get_field_object( $meta_key, $field_key ); + } elseif ( ! empty( $document ) && LoopBuilderModule::TEMPLATE_LIBRARY_TYPE_SLUG === $document::get_type() ) { + $field = $this->get_field_object( $field_key, get_the_ID() ); + } else { + $field = $this->get_field_object( $field_key, get_queried_object() ); + } + + return [ $field, $meta_key ]; + } + + /** + * Retrieve the custom field value from `ACF` plugin. + * Used for testing. + * + * @param $selector + * @param $post_id + * + * @return array|false + */ + protected function get_field_object( $selector, $post_id ) { + return get_field_object( $selector, $post_id ); + } + + /** + * Get the field data needed when rendering a dynamic tag for a taxonomy object. + * @param $field_key + * @param $meta_key + * + * @return array + */ + private function get_taxonomy_field_data( $field_key, $meta_key ) { + global $wp_query; + $field = $this->get_field_object( $field_key, $wp_query->loop_term ); + return [ $field, $meta_key ]; + } +} diff --git a/modules/dynamic-tags/acf/module.php b/modules/dynamic-tags/acf/module.php new file mode 100644 index 00000000..a2fdf4f4 --- /dev/null +++ b/modules/dynamic-tags/acf/module.php @@ -0,0 +1,240 @@ +ID; + } + + if ( $post_id instanceof \WP_Term ) { + return $post_id->term_id; + } + + return $post_id; + } + + /** + * Filter v4 Atomic editor select options for ACF URL tag to only include ACF 'url' type fields. + * Does not affect legacy editor or rendering. + * + * @param array $options key => label + * @param array $control Original control config + * @param array $tag Dynamic tag config + * @return array Filtered options + */ + public function filter_atomic_select_options_for_acf_url( $options, $control, $tag ) { + if ( empty( $tag['name'] ) || 'acf-url' !== $tag['name'] ) { + return $options; + } + + if ( empty( $control['name'] ) || 'key' !== $control['name'] ) { + return $options; + } + + if ( ! function_exists( 'acf_get_field' ) ) { + return $options; + } + + $filtered = []; + + foreach ( $options as $value => $label ) { + $field_selector = static::extract_field_selector_from_option( $value ); + + $field = acf_get_field( $field_selector ); + + if ( is_array( $field ) && isset( $field['type'] ) && 'url' === $field['type'] ) { + $filtered[ $value ] = $label; + } + } + + return empty( $filtered ) ? $options : $filtered; + } + + /** + * @param array $types + * + * @return array + */ + public static function get_control_options( $types ) { + // ACF >= 5.0.0 + if ( function_exists( 'acf_get_field_groups' ) ) { + $acf_groups = acf_get_field_groups(); + } else { + $acf_groups = apply_filters( 'acf/get_field_groups', [] ); + } + + $groups = []; + + $options_page_groups_ids = []; + + if ( function_exists( 'acf_options_page' ) ) { + $pages = acf_options_page()->get_pages(); + foreach ( $pages as $slug => $page ) { + $options_page_groups = acf_get_field_groups( [ + 'options_page' => $slug, + ] ); + + foreach ( $options_page_groups as $options_page_group ) { + $options_page_groups_ids[] = $options_page_group['ID']; + } + } + } + + foreach ( $acf_groups as $acf_group ) { + // ACF >= 5.0.0 + if ( function_exists( 'acf_get_fields' ) ) { + if ( isset( $acf_group['ID'] ) && ! empty( $acf_group['ID'] ) ) { + $fields = acf_get_fields( $acf_group['ID'] ); + } else { + $fields = acf_get_fields( $acf_group ); + } + } else { + $fields = apply_filters( 'acf/field_group/get_fields', [], $acf_group['id'] ); + } + + $options = []; + + if ( ! is_array( $fields ) ) { + continue; + } + + $has_option_page_location = in_array( $acf_group['ID'], $options_page_groups_ids, true ); + $is_only_options_page = $has_option_page_location && 1 === count( $acf_group['location'] ); + + foreach ( $fields as $field ) { + if ( ! in_array( $field['type'], $types, true ) ) { + continue; + } + + // Use group ID for unique keys + if ( $has_option_page_location ) { + $key = 'options:' . $field['name']; + $options[ $key ] = esc_html__( 'Options', 'elementor-pro' ) . ':' . $field['label']; + if ( $is_only_options_page ) { + continue; + } + } + + $key = $field['key'] . ':' . $field['name']; + $options[ $key ] = $field['label']; + } + + if ( empty( $options ) ) { + continue; + } + + if ( 1 === count( $options ) ) { + $options = [ -1 => ' -- ' ] + $options; + } + + $groups[] = [ + 'label' => $acf_group['title'], + 'options' => $options, + ]; + } // End foreach(). + + return $groups; + } + + public static function add_key_control( Base_Tag $tag ) { + $tag->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => self::get_control_options( $tag->get_supported_fields() ), + ] + ); + } + + public function get_tag_classes_names() { + return [ + 'ACF_Text', + 'ACF_Image', + 'ACF_URL', + 'ACF_Gallery', + 'ACF_File', + 'ACF_Number', + 'ACF_Color', + 'ACF_Date_Time', + ]; + } + + // For use by ACF tags + public static function get_tag_value_field( Base_Tag $tag ) { + $key = $tag->get_settings( 'key' ); + + // TODO: The tags should use the `Dynamic_Value_Provider::get_value()` method, but it involves + // heavily refactoring them, so currently this method is just a proxy and also kept for BC. + + if ( ! static::$dynamic_value_provider ) { + static::$dynamic_value_provider = new Dynamic_Value_Provider(); + } + + return static::$dynamic_value_provider->get_value( $key ); + } + + public function get_groups() { + return [ + self::ACF_GROUP => [ + 'title' => esc_html__( 'ACF', 'elementor-pro' ), + ], + ]; + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-color.php b/modules/dynamic-tags/acf/tags/acf-color.php new file mode 100644 index 00000000..b25fd667 --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-color.php @@ -0,0 +1,59 @@ +get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return $value; + } + + protected function register_controls() { + Module::add_key_control( $this ); + } + + public function get_supported_fields() { + return [ + 'color_picker', + ]; + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-date-time.php b/modules/dynamic-tags/acf/tags/acf-date-time.php new file mode 100644 index 00000000..8a138ebb --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-date-time.php @@ -0,0 +1,97 @@ +dynamic_value_provider->get_value( + $this->get_settings( 'key' ) + ); + + if ( empty( $field_settings ) ) { + return ''; + } + + $field = $field_settings[0]; + $value = ''; + + if ( $field ) { + $date_time = \DateTime::createFromFormat( $field['return_format'], $field['value'] ); + + $value = $date_time instanceof \DateTime + ? $date_time->format( 'Y-m-d H:i:s' ) + : ''; + } + + if ( empty( $value ) && $this->get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + Module::add_key_control( $this ); + + $this->add_control( + 'fallback', + [ + 'type' => Controls_Manager::DATE_TIME, + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + ] + ); + } + + public function get_supported_fields() { + return [ + 'date_time_picker', + ]; + } + + public function __construct( array $data = [], $dynamic_value_provider = null ) { + parent::__construct( $data ); + + $this->dynamic_value_provider = $dynamic_value_provider ?? new Dynamic_Value_Provider(); + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-file.php b/modules/dynamic-tags/acf/tags/acf-file.php new file mode 100644 index 00000000..fcba6ac8 --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-file.php @@ -0,0 +1,31 @@ + $image['ID'], + ]; + } + } + + return $images; + } + + protected function register_controls() { + Module::add_key_control( $this ); + } + + public function get_supported_fields() { + return [ + 'gallery', + ]; + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-image.php b/modules/dynamic-tags/acf/tags/acf-image.php new file mode 100644 index 00000000..1cba3ec8 --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-image.php @@ -0,0 +1,99 @@ + null, + 'url' => '', + ]; + + list( $field, $meta_key ) = Module::get_tag_value_field( $this ); + + if ( $field && is_array( $field ) ) { + $field['return_format'] = isset( $field['save_format'] ) ? $field['save_format'] : $field['return_format']; + switch ( $field['return_format'] ) { + case 'object': + case 'array': + $value = $field['value']; + break; + case 'url': + $value = [ + 'id' => 0, + 'url' => $field['value'], + ]; + break; + case 'id': + $src = wp_get_attachment_image_src( $field['value'], $field['preview_size'] ); + $value = [ + 'id' => $field['value'], + 'url' => $src[0], + ]; + break; + } + } + + if ( ! isset( $value ) ) { + // Field settings has been deleted or not available. + $value = get_field( $meta_key ); + } + + if ( empty( $value ) && $this->get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + if ( ! empty( $value ) && is_array( $value ) ) { + $image_data['id'] = $value['id']; + $image_data['url'] = $value['url']; + } + + return $image_data; + } + + protected function register_controls() { + Module::add_key_control( $this ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + ] + ); + } + + public function get_supported_fields() { + return [ + 'image', + ]; + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-number.php b/modules/dynamic-tags/acf/tags/acf-number.php new file mode 100644 index 00000000..e03bda24 --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-number.php @@ -0,0 +1,58 @@ + $item ) { + if ( isset( $field['choices'][ $item ] ) ) { + $values[ $key ] = $field['choices'][ $item ]; + } + } + + $value = implode( ', ', $values ); + + break; + case 'checkbox': + $value = (array) $value; + $values = []; + foreach ( $value as $item ) { + if ( isset( $field['choices'][ $item ] ) ) { + $values[] = $field['choices'][ $item ]; + } else { + $values[] = $item; + } + } + + $value = implode( ', ', $values ); + + break; + case 'oembed': + // Get from db without formatting. + $value = $this->get_queried_object_meta( $meta_key ); + break; + case 'google_map': + $meta = $this->get_queried_object_meta( $meta_key ); + $value = isset( $meta['address'] ) ? $meta['address'] : ''; + break; + case 'true_false': + $value = (string) $value; + break; + } // End switch(). + } else { + // Field settings has been deleted or not available. + $value = get_field( $meta_key ); + } // End if(). + + if ( ! is_string( $value ) ) { + $type = gettype( $value ); + wp_trigger_error( 'acf-text', "ACF Text Field value must be string, but is type of: $type", E_USER_WARNING ); + } else { + echo wp_kses_post( $value ); + } + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + Module::add_key_control( $this ); + } + + public function get_supported_fields() { + return [ + 'text', + 'textarea', + 'number', + 'email', + 'password', + 'wysiwyg', + 'select', + 'checkbox', + 'radio', + 'true_false', + + // Pro + 'oembed', + 'google_map', + 'date_picker', + 'time_picker', + 'date_time_picker', + 'color_picker', + ]; + } + + private function get_queried_object_meta( $meta_key ) { + $value = ''; + if ( is_singular() ) { + $value = get_post_meta( get_the_ID(), $meta_key, true ); + } elseif ( is_tax() || is_category() || is_tag() ) { + $value = get_term_meta( get_queried_object_id(), $meta_key, true ); + } + + return $value; + } +} diff --git a/modules/dynamic-tags/acf/tags/acf-url.php b/modules/dynamic-tags/acf/tags/acf-url.php new file mode 100644 index 00000000..f11aa7a7 --- /dev/null +++ b/modules/dynamic-tags/acf/tags/acf-url.php @@ -0,0 +1,116 @@ +get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return wp_kses_post( $value ); + } + + protected function register_controls() { + Module::add_key_control( $this ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + ] + ); + } + + public function get_supported_fields() { + return [ + 'text', + 'email', + 'image', + 'file', + 'page_link', + 'post_object', + 'relationship', + 'taxonomy', + 'url', + ]; + } +} diff --git a/modules/dynamic-tags/components/author-meta-filter.php b/modules/dynamic-tags/components/author-meta-filter.php new file mode 100644 index 00000000..1d13cd11 --- /dev/null +++ b/modules/dynamic-tags/components/author-meta-filter.php @@ -0,0 +1,73 @@ +get_dynamic_tag( $data['elements'] ); + + if ( ! $dynamic_tag ) { + return $data; + } + + if ( $this->is_dynamic_tag_authored_by_admin( $document, $dynamic_tag ) ) { + return $data; + } + + return Plugin::elementor()->db->iterate_data( $data, function ( $element ) { + if ( $this->is_dynamic_tag_to_escape( $element ) ) { + $element['settings']['__dynamic__'] = []; + } + + return $element; + }); + } + + private function is_dynamic_tag_authored_by_admin( $document, string $needle_tag ): bool { + global $post; + + $post_author_id = $post->post_author ?? 0; + $is_post_authored_by_admin = user_can( $post_author_id, 'manage_options' ); + + if ( ! $is_post_authored_by_admin ) { + return false; + } + + $json = wp_json_encode( $document->get_elements_data() ); + + return false !== strpos( $json, $needle_tag ); + } + + private function is_dynamic_tag_to_escape( array $element ): bool { + if ( 'widget' !== $element['elType'] ) { + return false; + } + + return ! empty( $element['settings']['__dynamic__'] ) && ! empty( preg_match( self::DYNAMIC_TAG_SHORTCODE_PATTERN, $element['settings']['__dynamic__']['title'] ) ); + } + + private function get_dynamic_tag( array $elements ): ?string { + $json = wp_json_encode( $elements ); + + preg_match( self::DYNAMIC_TAG_SHORTCODE_PATTERN, $json, $matches ); + + if ( empty( $matches ) ) { + return false; + } + + return $matches[0]; + } +} diff --git a/modules/dynamic-tags/module.php b/modules/dynamic-tags/module.php new file mode 100644 index 00000000..90deefc5 --- /dev/null +++ b/modules/dynamic-tags/module.php @@ -0,0 +1,162 @@ +add_component( 'author-meta-filter', new Components\Author_Meta_Filter() ); + + // ACF 5 and up + if ( class_exists( '\acf' ) && function_exists( 'acf_get_field_groups' ) && API::is_licence_has_feature( self::LICENSE_FEATURE_ACF_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'acf', new ACF\Module() ); + } + + if ( function_exists( 'wpcf_admin_fields_get_groups' ) && API::is_licence_has_feature( self::LICENSE_FEATURE_TOOLSET_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'toolset', new Toolset\Module() ); + } + + if ( function_exists( 'pods' ) && API::is_licence_has_feature( self::LICENSE_FEATURE_PODS_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'pods', new Pods\Module() ); + } + + /* + * WooCommerce Add To Cart Dynamic Tag. + * + * The WC ATC Dynamic Tag returns a URL that adds items to a users cart + * via the URL parameters `?add-to-cart=' . $product_id . '&quantity=' . $quantity`. + * Normally this URL method redirects to the website's Home page after adding the items to + * the cart. + * + * Since the behavior of the Tag should be identical to the "Add to Cart" widget, clicking an + * element that is using the tag needs to redirect to the Single Product page for the added + * product or the Cart page after this process if the user selected that setting in WooCommerce. + * + * To accomplish that, an extra parameter in the URL ('&e-redirect=') is used. When this + * paramater is found, the WooCommerce Add to Cart Dynamic Tag will redirect to the + * appropriate page. + */ + + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- The nonce is verified in the WC class. + $add_to_cart = Utils::_unstable_get_super_global_value( $_REQUEST, 'add-to-cart' ); + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- The nonce is verified in the WC class. + $redirect = Utils::_unstable_get_super_global_value( $_REQUEST, 'e-redirect' ); + + if ( $add_to_cart && $redirect ) { + add_filter( 'woocommerce_add_to_cart_redirect', [ $this, 'filter_woocommerce_add_to_cart_redirect' ], 10, 1 ); + } + + add_filter( 'elementor/document/save/data', [ $this->get_component( 'author-meta-filter' ), 'filter' ], 10, 2 ); + } + + public function filter_woocommerce_add_to_cart_redirect( $wc_get_cart_url ) { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here. + return esc_url( Utils::_unstable_get_super_global_value( $_REQUEST, 'e-redirect' ) ); + } + + public function get_name() { + return 'tags'; + } + + public function get_tag_classes_names() { + return [ + 'Archive_Description', + 'Archive_Meta', + 'Archive_Title', + 'Archive_URL', + 'Author_Info', + 'Author_Meta', + 'Author_Name', + 'Author_Profile_Picture', + 'Author_URL', + 'Comments_Number', + 'Comments_URL', + 'Page_Title', + 'Post_Custom_Field', + 'Post_Date', + 'Post_Excerpt', + 'Post_Featured_Image', + 'Post_Gallery', + 'Post_ID', + 'Post_Terms', + 'Post_Time', + 'Post_Title', + 'Post_URL', + 'Site_Logo', + 'Site_Tagline', + 'Site_Title', + 'Site_URL', + 'Internal_URL', + 'Current_Date_Time', + 'Reload_Page', + 'Request_Parameter', + 'Lightbox', + 'Featured_Image_Data', + 'Shortcode', + 'Contact_URL', + 'User_Info', + 'User_Profile_Picture', + ]; + } + + public function get_groups() { + return [ + self::POST_GROUP => [ + 'title' => esc_html__( 'Post', 'elementor-pro' ), + ], + self::ARCHIVE_GROUP => [ + 'title' => esc_html__( 'Archive', 'elementor-pro' ), + ], + self::SITE_GROUP => [ + 'title' => esc_html__( 'Site', 'elementor-pro' ), + ], + self::MEDIA_GROUP => [ + 'title' => esc_html__( 'Media', 'elementor-pro' ), + ], + self::ACTION_GROUP => [ + 'title' => esc_html__( 'Actions', 'elementor-pro' ), + ], + self::AUTHOR_GROUP => [ + 'title' => esc_html__( 'Author', 'elementor-pro' ), + ], + self::COMMENTS_GROUP => [ + 'title' => esc_html__( 'Comments', 'elementor-pro' ), + ], + self::WOOCOMMERCE_GROUP => [ + 'title' => esc_html__( 'WooCommerce', 'elementor-pro' ), + ], + ]; + } +} diff --git a/modules/dynamic-tags/pods/dynamic-value-provider.php b/modules/dynamic-tags/pods/dynamic-value-provider.php new file mode 100644 index 00000000..28de1e4d --- /dev/null +++ b/modules/dynamic-tags/pods/dynamic-value-provider.php @@ -0,0 +1,59 @@ +is_valid_field_key( $key ) ) { + return []; + } + + list( $pod_name, , $meta_key ) = explode( ':', $key ); + + $pod = $this->get_pods_value( $pod_name, get_the_ID() ); + + if ( false === $pod ) { + return []; + } + + return [ + 'field' => $pod->fields[ $meta_key ], + 'value' => $pod->field( $meta_key ), + 'display' => $pod->display( $meta_key ), + 'pod' => $pod, + 'key' => $meta_key, + ]; + } + + /** + * Retrieve the Pod value from `Pods` plugin. + * Used for testing. + * + * @param $type + * @param $id + * + * @return bool|\Pods + */ + protected function get_pods_value( $type, $id ) { + return pods( $type, $id ); + } + + private function is_valid_field_key( $key ) { + $key = trim( $key ); + + if ( empty( $key ) ) { + return false; + } + + $colon_count = substr_count( $key, ':' ); + + // Key structure looks like: `page:699:pods_date_time`. + return ( 2 === $colon_count ); + } +} diff --git a/modules/dynamic-tags/pods/module.php b/modules/dynamic-tags/pods/module.php new file mode 100644 index 00000000..f36d9edb --- /dev/null +++ b/modules/dynamic-tags/pods/module.php @@ -0,0 +1,132 @@ +load_pods( [ + 'table_info' => true, + 'fields' => true, + ] ); + + $groups = []; + + foreach ( $all_pods as $group ) { + $options = []; + + foreach ( $group['fields'] as $field ) { + if ( ! self::valid_field_type( $types, $field ) ) { + continue; + } + + // Use pods ID for unique keys + $key = $group['name'] . ':' . $field['pod_id'] . ':' . $field['name']; + $options[ $key ] = $field['label']; + } + + if ( empty( $options ) ) { + continue; + } + + if ( 1 === count( $options ) ) { + $options = [ -1 => ' -- ' ] + $options; + } + + $groups[] = [ + 'label' => $group['name'], + 'options' => $options, + ]; + } + + return $groups; + } + + public static function valid_field_type( $types, $field ) { + // Only file field with single image value + if ( in_array( 'pods_image', $types, true ) && self::pods_image_mapping( $field ) ) { + return true; + } + if ( in_array( 'pods_url', $types, true ) && in_array( $field['type'], [ 'email', 'file', 'website', 'phone' ] ) ) { + // Only file with single value allowed + if ( 'file' === $field['type'] && ! self::pods_file_mapping( $field ) ) { + return false; + } + + return true; + } + // Only file with multiple images allowed + if ( in_array( 'pods_gallery', $types, true ) && self::pods_image_mapping( $field, false ) ) { + return true; + } + // Any other type + if ( in_array( $field['type'], $types, true ) ) { + return true; + } + + return false; + } + + public static function pods_file_mapping( $field, $single = true ) { + if ( 'file' !== $field['type'] ) { + return false; + } + + $limit = $single ? 'single' : 'multi'; + if ( $limit !== $field['options']['file_format_type'] ) { + return false; + } + + return true; + } + + public static function pods_image_mapping( $field, $single = true ) { + if ( ! isset( $field['options'] ) || ! isset( $field['options']['file_type'] ) ) { + return false; + } + if ( 'images' !== $field['options']['file_type'] ) { + return false; + } + if ( ! self::pods_file_mapping( $field, $single ) ) { + return false; + } + + return true; + } + + public function get_tag_classes_names() { + return [ + 'Pods_Text', + 'Pods_Date', + 'Pods_Date_Time', + 'Pods_Image', + 'Pods_Gallery', + 'Pods_URL', + 'Pods_Numeric', + ]; + } + + public function get_groups() { + return [ + self::PODS_GROUP => [ + 'title' => esc_html__( 'Pods', 'elementor-pro' ), + ], + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-base.php b/modules/dynamic-tags/pods/tags/pods-base.php new file mode 100644 index 00000000..3f9865a0 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-base.php @@ -0,0 +1,64 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return false; + } + + list( $pod_name, $pod_id, $meta_key ) = explode( ':', $key ); + /** + * @var \Pods + */ + $pod = pods( $pod_name, get_the_ID() ); + + if ( false === $pod ) { + return []; + } + + return [ + 'field' => $pod->fields[ $meta_key ], + 'value' => $pod->field( $meta_key ), + 'display' => $pod->display( $meta_key ), + 'pod' => $pod, + 'key' => $meta_key, + ]; + } + + public function get_categories() { + return [ + Module::TEXT_CATEGORY, + Module::POST_META_CATEGORY, + ]; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + } + + protected function get_supported_fields() { + return []; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-date-time.php b/modules/dynamic-tags/pods/tags/pods-date-time.php new file mode 100644 index 00000000..d70efdc8 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-date-time.php @@ -0,0 +1,95 @@ +dynamic_value_provider->get_value( + $this->get_settings( 'key' ) + ); + + $value = $field['value'] ?? ''; + + if ( ! empty( $value ) ) { + $value = gmdate( 'Y-m-d H:i:s', strtotime( $value ) ); + } + + if ( empty( $value ) && $this->get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + + $this->add_control( + 'fallback', + [ + 'type' => Controls_Manager::DATE_TIME, + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + ] + ); + } + + protected function get_supported_fields() { + return [ + 'datetime', + ]; + } + + public function __construct( array $data = [], $dynamic_value_provider = null ) { + parent::__construct( $data ); + + $this->dynamic_value_provider = $dynamic_value_provider ?? new Dynamic_Value_Provider(); + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-date.php b/modules/dynamic-tags/pods/tags/pods-date.php new file mode 100644 index 00000000..6b1e42aa --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-date.php @@ -0,0 +1,96 @@ +get_field(); + $field = $field_data['field']; + $value = empty( $field_data['value'] ) ? '' : $field_data['value']; + + if ( $field && ! empty( $field['type'] ) && in_array( $field['type'], [ 'date', 'datetime' ] ) ) { + + $format = $this->get_settings( 'format' ); + + $timestamp = strtotime( $value ); + + if ( 'human' === $format ) { + $value = human_time_diff( $timestamp ); + } else { + switch ( $format ) { + case 'default': + $date_format = get_option( 'date_format' ); + break; + case 'custom': + $date_format = $this->get_settings( 'custom_format' ); + break; + default: + $date_format = $format; + break; + } + + $value = gmdate( $date_format, $timestamp ); + } + } + echo wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + parent::register_controls(); + + $this->add_control( + 'format', + [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'F j, Y' => gmdate( 'F j, Y' ), + 'Y-m-d' => gmdate( 'Y-m-d' ), + 'm/d/Y' => gmdate( 'm/d/Y' ), + 'd/m/Y' => gmdate( 'd/m/Y' ), + 'human' => esc_html__( 'Human Readable', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $this->add_control( + 'custom_format', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'default' => '', + 'description' => sprintf( '%s', esc_html__( 'Documentation on date and time formatting', 'elementor-pro' ) ), + 'condition' => [ + 'format' => 'custom', + ], + ] + ); + } + + protected function get_supported_fields() { + return [ + 'datetime', + 'date', + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-gallery.php b/modules/dynamic-tags/pods/tags/pods-gallery.php new file mode 100644 index 00000000..a05ee5ee --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-gallery.php @@ -0,0 +1,83 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return false; + } + + $images = []; + + list( $pod_name, $pod_id, $meta_key ) = explode( ':', $key ); + /** + * @var \Pods + */ + $pod = pods( $pod_name, get_the_ID() ); + + if ( false === $pod ) { + return []; + } + + $galley_images = $pod->field( $meta_key ); + + if ( empty( $galley_images ) || ! is_array( $galley_images ) ) { + return $images; + } + + foreach ( $galley_images as $image ) { + $images[] = [ + 'id' => $image['ID'], + ]; + } + + return $images; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + } + + protected function get_supported_fields() { + return [ + 'pods_gallery', + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-image.php b/modules/dynamic-tags/pods/tags/pods-image.php new file mode 100644 index 00000000..0c5444c3 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-image.php @@ -0,0 +1,87 @@ +get_settings( 'key' ); + + $image_data = $this->get_settings( 'fallback' ); + + if ( empty( $key ) ) { + return $image_data; + } + + list( $pod_name, $pod_id, $meta_key ) = explode( ':', $key ); + /** + * @var \Pods + */ + $pod = pods( $pod_name, get_the_ID() ); + + if ( false === $pod ) { + return []; + } + + $image = $pod->field( $meta_key ); + + $image_data = [ + 'id' => empty( $image['ID'] ) ? $image_data['id'] : $image['ID'], + 'url' => empty( $image['guid'] ) ? $image_data['url'] : $image['guid'], + ]; + + return $image_data; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + ] + ); + } + + protected function get_supported_fields() { + return [ + 'pods_image', + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-numeric.php b/modules/dynamic-tags/pods/tags/pods-numeric.php new file mode 100644 index 00000000..78a596d7 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-numeric.php @@ -0,0 +1,39 @@ +get_field(); + $value = ! empty( $field_data['value'] ) && is_numeric( $field_data['value'] ) ? $field_data['value'] : ''; + + echo wp_kses_post( $value ); + } + + protected function get_supported_fields() { + return [ + 'numeric', + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-text.php b/modules/dynamic-tags/pods/tags/pods-text.php new file mode 100644 index 00000000..13733262 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-text.php @@ -0,0 +1,55 @@ +get_field(); + $field = $field_data['field']; + $value = empty( $field_data['value'] ) ? '' : $field_data['value']; + + if ( ! empty( $field['type'] ) ) { + switch ( $field['type'] ) { + case 'paragraph': + $value = $field_data['display']; + break; + case 'pick': + $value = $field_data['display']; + if ( is_array( $value ) ) { + $value = implode( ', ', $value ); + } + break; + } + } + + echo wp_kses_post( $value ); + } + + protected function get_supported_fields() { + return [ + 'text', + 'phone', + 'paragraph', + 'relationship', + 'pick', + 'numeric', + 'email', + 'oembed', + 'google_address', + 'wysiwyg', + 'time', + ]; + } +} diff --git a/modules/dynamic-tags/pods/tags/pods-url.php b/modules/dynamic-tags/pods/tags/pods-url.php new file mode 100644 index 00000000..fbe8ef51 --- /dev/null +++ b/modules/dynamic-tags/pods/tags/pods-url.php @@ -0,0 +1,95 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return false; + } + + list( $pod_name, $pod_id, $meta_key ) = explode( ':', $key ); + /** + * @var \Pods + */ + $pod = pods( $pod_name, get_the_ID() ); + + if ( false === $pod ) { + return []; + } + + $field = $pod->fields[ $meta_key ]; + $value = $pod->field( $meta_key ); + if ( $field && ! empty( $field['type'] ) ) { + + switch ( $field['type'] ) { + case 'phone': + $value = 'tel:' . $value; + break; + case 'file': + $value = empty( $value['guid'] ) ? '' : $value['guid']; + break; + case 'email': + $value = 'mailto:' . $value; + break; + } // End switch(). + } + + if ( empty( $value ) && $this->get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return wp_kses_post( $value ); + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + ] + ); + } + + protected function get_supported_fields() { + return [ 'pods_url' ]; + } +} diff --git a/modules/dynamic-tags/tags/archive-description.php b/modules/dynamic-tags/tags/archive-description.php new file mode 100644 index 00000000..b60cb168 --- /dev/null +++ b/modules/dynamic-tags/tags/archive-description.php @@ -0,0 +1,46 @@ +render_loop_taxonomy(); + return; + } + + $this->render_post(); + } + + private function render_post() { + echo wp_kses_post( get_the_archive_description() ); + } + + private function render_loop_taxonomy() { + $this->render_taxonomy_content_by_key( 'description' ); + } +} diff --git a/modules/dynamic-tags/tags/archive-meta.php b/modules/dynamic-tags/tags/archive-meta.php new file mode 100644 index 00000000..88490e09 --- /dev/null +++ b/modules/dynamic-tags/tags/archive-meta.php @@ -0,0 +1,66 @@ +get_settings( 'key' ); + + if ( empty( $key ) ) { + return; + } + + $value = ''; + + if ( is_category() || is_tax() ) { + $value = get_term_meta( get_queried_object_id(), $key, true ); + } elseif ( is_author() ) { + $value = get_user_meta( get_queried_object_id(), $key, true ); + } + + echo wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Meta Key', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/archive-title.php b/modules/dynamic-tags/tags/archive-title.php new file mode 100644 index 00000000..0f3e3454 --- /dev/null +++ b/modules/dynamic-tags/tags/archive-title.php @@ -0,0 +1,77 @@ + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'settings' => [ 'include_context' => 'no' ], + 'group' => 'archive', + ], + ]; + + return $config; + } + + public function render() { + if ( Taxonomy_Loop_Provider::is_loop_taxonomy() ) { + $this->render_loop_taxonomy(); + return; + } + + $this->render_post(); + } + + private function render_post() { + $include_context = $this->get_settings( 'include_context' ); + $is_included = 'yes' === $include_context || true === $include_context; + + $title = Utils::get_page_title( $is_included ); + + echo wp_kses_post( $title ); + } + + private function render_loop_taxonomy() { + $this->render_taxonomy_content_by_key( 'name' ); + } + + protected function register_controls() { + $this->add_control( + 'include_context', + [ + 'label' => esc_html__( 'Include Context', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/archive-url.php b/modules/dynamic-tags/tags/archive-url.php new file mode 100644 index 00000000..bb78df8c --- /dev/null +++ b/modules/dynamic-tags/tags/archive-url.php @@ -0,0 +1,38 @@ + [ + 'label' => esc_html__( 'Author Bio', 'elementor-pro' ), + 'settings' => [ 'key' => 'description' ], + 'group' => 'author', + ], + 'author_info_email' => [ + 'label' => esc_html__( 'Author Email', 'elementor-pro' ), + 'settings' => [ 'key' => 'email' ], + 'group' => 'author', + ], + 'author_info_website' => [ + 'label' => esc_html__( 'Author Website', 'elementor-pro' ), + 'settings' => [ 'key' => 'url' ], + 'group' => 'author', + ], + ]; + + return $config; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Field', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'description', + 'options' => $this->get_key_options(), + ] + ); + } + + private function get_key_options() { + $options = []; + $options['description'] = esc_html__( 'Bio', 'elementor-pro' ); + + if ( current_user_can( 'manage_options' ) ) { + $options['email'] = esc_html__( 'Email', 'elementor-pro' ); + } + + $options['url'] = esc_html__( 'Website', 'elementor-pro' ); + + return $options; + } +} diff --git a/modules/dynamic-tags/tags/author-meta.php b/modules/dynamic-tags/tags/author-meta.php new file mode 100644 index 00000000..bc1c3267 --- /dev/null +++ b/modules/dynamic-tags/tags/author-meta.php @@ -0,0 +1,31 @@ +add_control( + 'key', + [ + 'label' => esc_html__( 'Meta Key', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/author-name.php b/modules/dynamic-tags/tags/author-name.php new file mode 100644 index 00000000..d7413dce --- /dev/null +++ b/modules/dynamic-tags/tags/author-name.php @@ -0,0 +1,32 @@ + '', + 'url' => get_avatar_url( (int) get_the_author_meta( 'ID' ) ), + ]; + } +} diff --git a/modules/dynamic-tags/tags/author-url.php b/modules/dynamic-tags/tags/author-url.php new file mode 100644 index 00000000..7f86c892 --- /dev/null +++ b/modules/dynamic-tags/tags/author-url.php @@ -0,0 +1,64 @@ +get_settings( 'url' ) ) { + global $authordata; + + if ( $authordata ) { + $value = get_author_posts_url( $authordata->ID, $authordata->user_nicename ); + } + } else { + $value = get_the_author_meta( 'url' ); + } + + return $value; + } + + protected function register_controls() { + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'archive', + 'options' => [ + 'archive' => esc_html__( 'Author Archive', 'elementor-pro' ), + 'website' => esc_html__( 'Author Website', 'elementor-pro' ), + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/base/author-tag.php b/modules/dynamic-tags/tags/base/author-tag.php new file mode 100644 index 00000000..d000c2e1 --- /dev/null +++ b/modules/dynamic-tags/tags/base/author-tag.php @@ -0,0 +1,77 @@ +get_not_allowed_fields(), true ); + } + + private function get_not_allowed_fields() { + $not_allowed_fields = [ + 'user_login', + 'user_pass', + 'user_registered', + 'user_activation_key', + 'user_status', + 'user_email', + // WordPress allows these aliases. + 'login', + 'pass', + 'registered', + 'activation_key', + 'status', + 'email', + ]; + + if ( $this->allow_email_key_for_admins_only() ) { + unset( $not_allowed_fields[ array_search( 'user_email', $not_allowed_fields ) ] ); + unset( $not_allowed_fields[ array_search( 'email', $not_allowed_fields ) ] ); + } + + return $not_allowed_fields; + } + + private function allow_email_key_for_admins_only() { + return current_user_can( 'manage_options' ) || $this->is_post_authored_by_admin(); + } + + private function is_post_authored_by_admin() { + global $post; + + $post_author_id = $post->post_author ?? 0; + + return user_can( $post_author_id, 'manage_options' ); + } + + public function render() { + $key = $this->get_settings( 'key' ); + + if ( empty( $key ) || ! $this->is_field_allowed( $key ) ) { + return; + } + + $value = get_the_author_meta( $key ); + + echo wp_kses_post( $value ); + } +} diff --git a/modules/dynamic-tags/tags/base/data-tag.php b/modules/dynamic-tags/tags/base/data-tag.php new file mode 100644 index 00000000..90afcac0 --- /dev/null +++ b/modules/dynamic-tags/tags/base/data-tag.php @@ -0,0 +1,14 @@ +loop_term ) || ! is_object( $wp_query->loop_term ) ) { + return; + } + + $content = ''; + + if ( isset( $wp_query->loop_term->$key ) ) { + $content = $wp_query->loop_term->$key; + } + + echo wp_kses_post( $content ); + } + + protected function get_data_id_from_taxonomy_loop_query() { + global $wp_query; + + if ( isset( $wp_query->loop_term ) && isset( $wp_query->loop_term->term_id ) ) { + return $wp_query->loop_term->term_id; + } + + return 0; + } +} diff --git a/modules/dynamic-tags/tags/base/tag.php b/modules/dynamic-tags/tags/base/tag.php new file mode 100644 index 00000000..4a67fd23 --- /dev/null +++ b/modules/dynamic-tags/tags/base/tag.php @@ -0,0 +1,16 @@ +add_control( + 'format_no_comments', + [ + 'label' => esc_html__( 'No Comments Format', 'elementor-pro' ), + 'default' => esc_html__( 'No Responses', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'format_one_comments', + [ + 'label' => esc_html__( 'One Comment Format', 'elementor-pro' ), + 'default' => esc_html__( 'One Response', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'format_many_comments', + [ + 'label' => esc_html__( 'Many Comment Format', 'elementor-pro' ), + 'default' => esc_html__( '{number} Responses', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'link_to', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'comments_link' => esc_html__( 'Comments Link', 'elementor-pro' ), + ], + ] + ); + } + + public function render() { + $settings = $this->get_settings(); + + $comments_number = get_comments_number(); + + if ( ! $comments_number ) { + $count = $settings['format_no_comments']; + } elseif ( 1 === $comments_number ) { + $count = $settings['format_one_comments']; + } else { + $count = strtr( $settings['format_many_comments'], [ + '{number}' => number_format_i18n( $comments_number ), + ] ); + } + + if ( 'comments_link' === $this->get_settings( 'link_to' ) ) { + $count = sprintf( '%s', get_comments_link(), $count ); + } + + echo wp_kses_post( $count ); + } +} diff --git a/modules/dynamic-tags/tags/comments-url.php b/modules/dynamic-tags/tags/comments-url.php new file mode 100644 index 00000000..2fd1c466 --- /dev/null +++ b/modules/dynamic-tags/tags/comments-url.php @@ -0,0 +1,32 @@ +add_control( + 'link_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => '— ' . esc_html__( 'Select', 'elementor-pro' ) . ' —', + 'email' => esc_html__( 'Email', 'elementor-pro' ), + 'tel' => esc_html__( 'Tel', 'elementor-pro' ), + 'sms' => esc_html__( 'SMS', 'elementor-pro' ), + 'whatsapp' => esc_html__( 'WhatsApp', 'elementor-pro' ), + 'skype' => esc_html__( 'Skype', 'elementor-pro' ), + 'messenger' => esc_html__( 'Messenger', 'elementor-pro' ), + 'viber' => esc_html__( 'Viber', 'elementor-pro' ), + 'waze' => esc_html__( 'Waze', 'elementor-pro' ), + 'google_calendar' => esc_html__( 'Google Calendar', 'elementor-pro' ), + 'outlook_calendar' => esc_html__( 'Outlook Calendar', 'elementor-pro' ), + 'yahoo_calendar' => esc_html__( 'Yahoo Calendar', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'mail_to', + [ + 'label' => esc_html__( 'Email', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'link_type' => 'email', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'mail_subject', + [ + 'label' => esc_html__( 'Subject', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => 'true', + 'condition' => [ + 'link_type' => 'email', + ], + ] + ); + + $this->add_control( + 'mail_body', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'condition' => [ + 'link_type' => 'email', + ], + ] + ); + + $this->add_control( + 'tel_number', + [ + 'label' => esc_html__( 'Number', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'link_type' => [ + 'tel', + 'sms', + 'whatsapp', + 'viber', + ], + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'username', + [ + 'label' => esc_html__( 'Username', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'link_type' => [ 'skype', 'messenger' ], + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'viber_action', + [ + 'label' => esc_html__( 'Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'contact' => esc_html__( 'Contact', 'elementor-pro' ), + 'add' => esc_html__( 'Add', 'elementor-pro' ), + ], + 'default' => 'contact', + 'condition' => [ + 'link_type' => 'viber', + ], + ] + ); + + $this->add_control( + 'skype_action', + [ + 'label' => esc_html__( 'Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'call' => esc_html__( 'Call', 'elementor-pro' ), + 'chat' => esc_html__( 'Chat', 'elementor-pro' ), + 'userinfo' => esc_html__( 'Show Profile', 'elementor-pro' ), + 'add' => esc_html__( 'Add to Contacts', 'elementor-pro' ), + 'voicemail' => esc_html__( 'Send Voice Mail', 'elementor-pro' ), + ], + 'default' => 'call', + 'condition' => [ + 'link_type' => 'skype', + ], + ] + ); + + $this->add_control( + 'waze_address', + [ + 'label' => esc_html__( 'Location', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => 'true', + 'condition' => [ + 'link_type' => 'waze', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'event_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => 'true', + 'condition' => [ + 'link_type' => [ + 'google_calendar', + 'outlook_calendar', + 'yahoo_calendar', + ], + ], + ] + ); + + $this->add_control( + 'event_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'condition' => [ + 'link_type' => [ + 'google_calendar', + 'outlook_calendar', + 'yahoo_calendar', + ], + ], + ] + ); + + $this->add_control( + 'event_location', + [ + 'label' => esc_html__( 'Location', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => 'true', + 'condition' => [ + 'link_type' => [ + 'google_calendar', + 'outlook_calendar', + 'yahoo_calendar', + ], + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'event_start_date', + [ + 'label' => esc_html__( 'Start', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'condition' => [ + 'link_type' => [ + 'google_calendar', + 'outlook_calendar', + 'yahoo_calendar', + ], + ], + ] + ); + + $this->add_control( + 'event_end_date', + [ + 'label' => esc_html__( 'End', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'condition' => [ + 'link_type' => [ + 'google_calendar', + 'outlook_calendar', + 'yahoo_calendar', + ], + ], + ] + ); + } + + protected function register_advanced_section() {} + + private function build_mail_to_link( $settings ) { + if ( empty( $settings['mail_to'] ) ) { + return ''; + } + + $link = 'mailto:' . $settings['mail_to'] . '?'; + + $build_parts = []; + + if ( ! empty( $settings['mail_subject'] ) ) { + $build_parts['subject'] = $this->escape_space_in_url( $settings['mail_subject'] ); + } + + if ( ! empty( $settings['mail_body'] ) ) { + $build_parts['body'] = $this->escape_space_in_url( $settings['mail_body'] ); + } + + return add_query_arg( $build_parts, $link ); + } + + private function build_sms_link( $settings ) { + if ( empty( $settings['tel_number'] ) ) { + return ''; + } + + $value = 'sms:' . $settings['tel_number']; + return $value; + } + + private function build_whatsapp_link( $settings ) { + if ( empty( $settings['tel_number'] ) ) { + return ''; + } + + return 'https://api.whatsapp.com/send?phone=' . $settings['tel_number']; + } + + private function build_skype_link( $settings ) { + if ( empty( $settings['username'] ) ) { + return ''; + } + + $action = 'call'; + if ( ! empty( $settings['skype_action'] ) ) { + $action = $settings['skype_action']; + } + $link = 'skype:' . $settings['username'] . '?' . $action; + return $link; + } + + private function build_waze_link( $settings ) { + $link = 'https://waze.com/ul?'; + + $build_parts = [ + 'q' => $settings['waze_address'], + 'z' => 10, + 'navigate' => 'yes', + ]; + + return add_query_arg( $build_parts, $link ); + } + + private function date_to_iso( $date, $all_day = false ) { + $time = strtotime( $date ); + + if ( $all_day ) { + return gmdate( 'Ymd\/Ymd', $time ); + } + + return gmdate( 'Ymd\THis', $time ); + } + + private function date_to_ics( $date ) { + $time = strtotime( $date ); + return gmdate( 'Y-m-d\Th:i:s', $time ); + } + + private function escape_space_in_url( $url ) { + return str_replace( ' ', '%20', $url ); + } + + private function build_google_calendar_link( $settings ) { + $dates = ''; + if ( ! empty( $settings['event_start_date'] ) ) { + if ( empty( $settings['event_end_date'] ) ) { + $dates = $this->date_to_iso( $settings['event_start_date'], true ); + } else { + $dates = $this->date_to_iso( $settings['event_start_date'] ) . '/' . $this->date_to_iso( $settings['event_end_date'] ); + } + } + $link = 'https://www.google.com/calendar/render?action=TEMPLATE&'; + $build_parts = [ + 'text' => empty( $settings['event_title'] ) ? '' : $this->escape_space_in_url( $settings['event_title'] ), + 'details' => empty( $settings['event_description'] ) ? '' : $this->escape_space_in_url( $settings['event_description'] ), + 'dates' => $dates, + 'location' => empty( $settings['event_location'] ) ? '' : $this->escape_space_in_url( $settings['event_location'] ), + ]; + + return add_query_arg( $build_parts, $link ); + } + + private function build_outlook_calendar_link( $settings ) { + $link = 'https://outlook.office.com/owa/?path=/calendar/action/compose&'; + $build_parts = [ + 'subject' => empty( $settings['event_title'] ) ? '' : urlencode( $settings['event_title'] ), + 'body' => empty( $settings['event_description'] ) ? '' : urlencode( $settings['event_description'] ), + 'location' => empty( $settings['event_location'] ) ? '' : urlencode( $settings['event_location'] ), + ]; + + if ( ! empty( $settings['event_start_date'] ) ) { + $build_parts['startdt'] = urlencode( $this->date_to_ics( $settings['event_start_date'] ) ); + } + + if ( ! empty( $settings['event_end_date'] ) ) { + $build_parts['enddt'] = urlencode( $this->date_to_ics( $settings['event_end_date'] ) ); + } + + return add_query_arg( $build_parts, $link ); + } + + private function build_messenger_link( $settings ) { + if ( empty( $settings['username'] ) ) { + return ''; + } + return 'https://m.me/' . $settings['username']; + } + + private function build_yahoo_calendar_link( $settings ) { + $link = 'https://calendar.yahoo.com/?v=60&view=d&type=20'; + $build_parts = [ + 'title' => empty( $settings['event_title'] ) ? '' : urlencode( $settings['event_title'] ), + 'desc' => empty( $settings['event_description'] ) ? '' : urlencode( $settings['event_description'] ), + 'in_loc' => empty( $settings['event_location'] ) ? '' : urlencode( $settings['event_location'] ), + ]; + + if ( ! empty( $settings['event_start_date'] ) ) { + $build_parts['st'] = urlencode( gmdate( 'Ymd\This', strtotime( $settings['event_start_date'] ) ) ); + } + + if ( ! empty( $settings['event_end_date'] ) ) { + $build_parts['et'] = urlencode( gmdate( 'Ymd\This', strtotime( $settings['event_end_date'] ) ) ); + } + + return add_query_arg( $build_parts, $link ); + } + + public function build_viber_link( $settings ) { + if ( empty( $settings['tel_number'] ) ) { + return ''; + } + $action = 'contact'; + if ( ! empty( $settings['viber_action'] ) ) { + $action = $settings['viber_action']; + } + return add_query_arg( [ + 'number' => urlencode( $settings['tel_number'] ), + ], 'viber://' . $action ); + } + + public function render() { + $settings = $this->get_settings(); + + if ( empty( $settings['link_type'] ) ) { + return ''; + } + + $value = ''; + switch ( $settings['link_type'] ) { + case 'email': + $value = $this->build_mail_to_link( $settings ); + break; + case 'tel': + $value = ( empty( $settings['tel_number'] ) ? '' : 'tel:' . $settings['tel_number'] ); + break; + case 'sms': + $value = $this->build_sms_link( $settings ); + break; + case 'messenger': + $value = $this->build_messenger_link( $settings ); + break; + case 'whatsapp': + $value = $this->build_whatsapp_link( $settings ); + break; + case 'skype': + $value = $this->build_skype_link( $settings ); + break; + case 'waze': + $value = $this->build_waze_link( $settings ); + break; + case 'google_calendar': + $value = $this->build_google_calendar_link( $settings ); + break; + case 'outlook_calendar': + $value = $this->build_outlook_calendar_link( $settings ); + break; + case 'yahoo_calendar': + $value = $this->build_yahoo_calendar_link( $settings ); + break; + case 'viber': + $value = $this->build_viber_link( $settings ); + break; + } + echo esc_html( $value ); + } +} + diff --git a/modules/dynamic-tags/tags/current-date-time.php b/modules/dynamic-tags/tags/current-date-time.php new file mode 100644 index 00000000..73b6cce5 --- /dev/null +++ b/modules/dynamic-tags/tags/current-date-time.php @@ -0,0 +1,120 @@ +add_control( + 'date_format', + [ + 'label' => esc_html__( 'Date Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + '' => esc_html__( 'None', 'elementor-pro' ), + 'F j, Y' => gmdate( 'F j, Y' ), + 'Y-m-d' => gmdate( 'Y-m-d' ), + 'm/d/Y' => gmdate( 'm/d/Y' ), + 'd/m/Y' => gmdate( 'd/m/Y' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $this->add_control( + 'time_format', + [ + 'label' => esc_html__( 'Time Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + '' => esc_html__( 'None', 'elementor-pro' ), + 'g:i a' => gmdate( 'g:i a' ), + 'g:i A' => gmdate( 'g:i A' ), + 'H:i' => gmdate( 'H:i' ), + ], + 'default' => 'default', + 'condition' => [ + 'date_format!' => 'custom', + ], + ] + ); + + $this->add_control( + 'custom_format', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'default' => get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), + 'description' => sprintf( '%s', esc_html__( 'Documentation on date and time formatting', 'elementor-pro' ) ), + 'condition' => [ + 'date_format' => 'custom', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + } + + public function render() { + $settings = $this->get_settings(); + + if ( 'custom' === $settings['date_format'] ) { + $format = $settings['custom_format']; + } else { + $date_format = $settings['date_format']; + $time_format = $settings['time_format']; + $format = ''; + + if ( 'default' === $date_format ) { + $date_format = get_option( 'date_format' ); + } + + if ( 'default' === $time_format ) { + $time_format = get_option( 'time_format' ); + } + + if ( $date_format ) { + $format = $date_format; + $has_date = true; + } else { + $has_date = false; + } + + if ( $time_format ) { + if ( $has_date ) { + $format .= ' '; + } + $format .= $time_format; + } + } + + $value = date_i18n( $format ); + + echo wp_kses_post( $value ); + } +} diff --git a/modules/dynamic-tags/tags/featured-image-data.php b/modules/dynamic-tags/tags/featured-image-data.php new file mode 100644 index 00000000..f2af14a9 --- /dev/null +++ b/modules/dynamic-tags/tags/featured-image-data.php @@ -0,0 +1,121 @@ + [ + 'label' => esc_html__( 'Image Title', 'elementor-pro' ), + 'settings' => [ 'attachment_data' => 'title' ], + 'group' => 'featured_image', + ], + 'featured_image_data_alt' => [ + 'label' => esc_html__( 'Image Alt', 'elementor-pro' ), + 'settings' => [ 'attachment_data' => 'alt' ], + 'group' => 'featured_image', + ], + 'featured_image_data_caption' => [ + 'label' => esc_html__( 'Image Caption', 'elementor-pro' ), + 'settings' => [ 'attachment_data' => 'caption' ], + 'group' => 'featured_image', + ], + ]; + + return $config; + } + + private function get_attacment() { + $id = get_post_thumbnail_id(); + + if ( ! $id ) { + return false; + } + + return get_post( $id ); + } + + public function render() { + $settings = $this->get_settings(); + $attachment = $this->get_attacment(); + + if ( ! $attachment ) { + return; + } + + $value = ''; + + switch ( $settings['attachment_data'] ) { + case 'alt': + $value = get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ); + break; + case 'caption': + $value = $attachment->post_excerpt; + break; + case 'description': + $value = $attachment->post_content; + break; + case 'href': + $value = get_permalink( $attachment->ID ); + break; + case 'src': + $value = $attachment->guid; + break; + case 'title': + $value = $attachment->post_title; + break; + } + + echo wp_kses_post( $value ); + } + + protected function register_controls() { + + $this->add_control( + 'attachment_data', + [ + 'label' => esc_html__( 'Data', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'title', + 'options' => [ + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'alt' => esc_html__( 'Alt', 'elementor-pro' ), + 'caption' => esc_html__( 'Caption', 'elementor-pro' ), + 'description' => esc_html__( 'Description', 'elementor-pro' ), + 'src' => esc_html__( 'File URL', 'elementor-pro' ), + 'href' => esc_html__( 'Attachment URL', 'elementor-pro' ), + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/internal-url.php b/modules/dynamic-tags/tags/internal-url.php new file mode 100644 index 00000000..c801f5e2 --- /dev/null +++ b/modules/dynamic-tags/tags/internal-url.php @@ -0,0 +1,143 @@ +get_settings(); + + $type = $settings['type']; + $url = ''; + + if ( 'post' === $type && ! empty( $settings['post_id'] ) ) { + $url = get_permalink( (int) $settings['post_id'] ); + } elseif ( 'taxonomy' === $type && ! empty( $settings['taxonomy_id'] ) ) { + $url = get_term_link( (int) $settings['taxonomy_id'] ); + } elseif ( 'attachment' === $type && ! empty( $settings['attachment_id'] ) ) { + $url = get_attachment_link( (int) $settings['attachment_id'] ); + } elseif ( 'author' === $type && ! empty( $settings['author_id'] ) ) { + $url = get_author_posts_url( (int) $settings['author_id'] ); + } + + if ( ! is_wp_error( $url ) ) { + return $url; + } + + return ''; + } + + protected function register_controls() { + $this->add_control( 'type', [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'post' => esc_html__( 'Content', 'elementor-pro' ), + 'taxonomy' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'attachment' => esc_html__( 'Media', 'elementor-pro' ), + 'author' => esc_html__( 'Author', 'elementor-pro' ), + ], + ] ); + + $this->add_control( 'post_id', [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'display' => 'detailed', + 'query' => [ + 'post_type' => 'any', + ], + ], + 'condition' => [ + 'type' => 'post', + ], + ] ); + + $this->add_control( 'taxonomy_id', [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_TAX, + 'display' => 'detailed', + ], + 'condition' => [ + 'type' => 'taxonomy', + ], + ] ); + + $this->add_control( 'attachment_id', [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_ATTACHMENT, + 'display' => 'detailed', + ], + 'condition' => [ + 'type' => 'attachment', + ], + ] ); + + $this->add_control( 'author_id', [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_AUTHOR, + 'display' => 'detailed', + ], + 'condition' => [ + 'type' => 'author', + ], + ] ); + } +} diff --git a/modules/dynamic-tags/tags/lightbox.php b/modules/dynamic-tags/tags/lightbox.php new file mode 100644 index 00000000..53153623 --- /dev/null +++ b/modules/dynamic-tags/tags/lightbox.php @@ -0,0 +1,174 @@ +add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'video' => [ + 'title' => esc_html__( 'Video', 'elementor-pro' ), + 'icon' => 'eicon-video-camera', + 'atomic-icon' => 'BrandYoutubeIcon', + ], + 'image' => [ + 'title' => esc_html__( 'Image', 'elementor-pro' ), + 'icon' => 'eicon-image-bold', + 'atomic-icon' => 'PhotoIcon', + ], + ], + 'default' => 'video', + ] + ); + + $this->add_control( + 'image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'condition' => [ + 'type' => 'image', + ], + ] + ); + + $this->add_control( + 'video_url', + [ + 'label' => esc_html__( 'Video URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'condition' => [ + 'type' => 'video', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + } + + private function get_image_settings( $settings ) { + $image_settings = [ + 'url' => $this->get_image_url( $settings['image'] ), + 'type' => 'image', + ]; + + return array_merge( $image_settings, $this->get_image_attributes( $settings['image'] ) ); + } + + private function get_image_url( array $image_settings ): string { + if ( ! empty( $image_settings['url'] ) ) { + return $image_settings['url']; + } + + if ( ! empty( $image_settings['src'] ) ) { + return $this->get_atomic_image_url( $image_settings ); + } + + return ''; + } + + private function get_atomic_image_url( array $image_settings ): string { + $default = $image_settings['src']['url'] ?? ''; + + if ( ! empty( $image_settings['src']['id'] ) ) { + $image_src = wp_get_attachment_image_src( $image_settings['src']['id'], 'full' ); + + return ! empty( $image_src[0] ) ? $image_src[0] : $default; + } + + return $image_settings['src']; + } + + private function get_image_attributes( array $image_settings ): array { + if ( ! empty( $image_settings['id'] ) ) { + return Plugin::elementor()->images_manager->get_lightbox_image_attributes( $image_settings['id'] ); + } + + if ( ! empty( $image_settings['src']['id'] ) ) { + return Plugin::elementor()->images_manager->get_lightbox_image_attributes( $image_settings['src']['id'] ); + } + + return []; + } + + private function get_video_settings( $settings ) { + $video_properties = Embed::get_video_properties( $settings['video_url'] ); + $video_url = null; + if ( ! $video_properties ) { + $video_type = 'hosted'; + $video_url = $settings['video_url']; + } else { + $video_type = $video_properties['provider']; + $video_url = Embed::get_embed_url( $settings['video_url'] ); + } + + if ( null === $video_url ) { + return ''; + } + + return [ + 'type' => 'video', + 'videoType' => $video_type, + 'url' => $video_url, + ]; + } + + public function render() { + $settings = $this->get_settings(); + + $value = []; + + if ( ! $settings['type'] ) { + return; + } + + if ( 'image' === $settings['type'] && $settings['image'] ) { + $value = $this->get_image_settings( $settings ); + } elseif ( 'video' === $settings['type'] && $settings['video_url'] ) { + $value = $this->get_video_settings( $settings ); + } + + if ( ! $value ) { + return; + } + + // PHPCS - the method Plugin::elementor()->frontend->create_action_hash is safe. + echo Plugin::elementor()->frontend->create_action_hash( 'lightbox', $value ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/dynamic-tags/tags/page-title.php b/modules/dynamic-tags/tags/page-title.php new file mode 100644 index 00000000..1438d82c --- /dev/null +++ b/modules/dynamic-tags/tags/page-title.php @@ -0,0 +1,75 @@ +get_settings( 'show_home_title' ) ) { + return; + } + + if ( Plugin::elementor()->common ) { + $current_action_data = Plugin::elementor()->common->get_component( 'ajax' )->get_current_action_data(); + + if ( $current_action_data && 'render_tags' === $current_action_data['action'] ) { + // Override the global $post for the render. + query_posts( + [ + 'p' => get_the_ID(), + 'post_type' => 'any', + ] + ); + } + } + + $include_context = $this->get_settings( 'include_context' ); + $is_included = 'yes' === $include_context || true === $include_context; + + $title = Utils::get_page_title( $is_included ); + + echo wp_kses_post( $title ); + } + + protected function register_controls() { + $this->add_control( + 'include_context', + [ + 'label' => esc_html__( 'Include Context', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'show_home_title', + [ + 'label' => esc_html__( 'Show Home Title', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/post-custom-field.php b/modules/dynamic-tags/tags/post-custom-field.php new file mode 100644 index 00000000..24e56af1 --- /dev/null +++ b/modules/dynamic-tags/tags/post-custom-field.php @@ -0,0 +1,118 @@ +add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_keys_array(), + ] + ); + + $this->add_control( + 'custom_key', + [ + 'label' => esc_html__( 'Custom Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'key', + 'condition' => [ + 'key' => '', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + } + + public function get_custom_field_value( string $key ) : string { + $value = get_post_meta( get_the_ID(), $key, true ); + + if ( ! is_string( $value ) ) { + return ''; + } + + return $value; + } + + public function render() { + $key = $this->get_settings( 'key' ); + + if ( empty( $key ) ) { + $key = $this->get_settings( 'custom_key' ); + } + + if ( empty( $key ) ) { + return; + } + + $value = $this->get_custom_field_value( $key ); + + if ( empty( $value ) ) { + return; + } + + echo wp_kses_post( $value ); + } + + private function get_custom_keys_array() { + $custom_keys = get_post_custom_keys(); + $options = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $custom_keys ) ) { + foreach ( $custom_keys as $custom_key ) { + if ( '_' !== substr( $custom_key, 0, 1 ) ) { + $options[ $custom_key ] = $custom_key; + } + } + } + + return $options; + } +} diff --git a/modules/dynamic-tags/tags/post-date.php b/modules/dynamic-tags/tags/post-date.php new file mode 100644 index 00000000..e44efbaf --- /dev/null +++ b/modules/dynamic-tags/tags/post-date.php @@ -0,0 +1,102 @@ +add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'post_date_gmt' => esc_html__( 'Post Published', 'elementor-pro' ), + 'post_modified_gmt' => esc_html__( 'Post Modified', 'elementor-pro' ), + ], + 'default' => 'post_date_gmt', + ] + ); + + $this->add_control( + 'format', + [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'F j, Y' => gmdate( 'F j, Y' ), + 'Y-m-d' => gmdate( 'Y-m-d' ), + 'm/d/Y' => gmdate( 'm/d/Y' ), + 'd/m/Y' => gmdate( 'd/m/Y' ), + 'human' => esc_html__( 'Human Readable', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $this->add_control( + 'custom_format', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'default' => '', + 'description' => sprintf( '%s', esc_html__( 'Documentation on date and time formatting', 'elementor-pro' ) ), + 'condition' => [ + 'format' => 'custom', + ], + ] + ); + } + + public function render() { + $date_type = $this->get_settings( 'type' ); + $format = $this->get_settings( 'format' ); + + if ( 'human' === $format ) { + /* translators: %s: Human readable date/time. */ + $value = sprintf( esc_html__( '%s ago', 'elementor-pro' ), human_time_diff( strtotime( get_post()->{$date_type} ) ) ); + } else { + switch ( $format ) { + case 'default': + $date_format = ''; + break; + case 'custom': + $date_format = $this->get_settings( 'custom_format' ); + break; + default: + $date_format = $format; + break; + } + + if ( 'post_date_gmt' === $date_type ) { + $value = get_the_date( $date_format ); + } else { + $value = get_the_modified_date( $date_format ); + } + } + echo wp_kses_post( $value ); + } +} diff --git a/modules/dynamic-tags/tags/post-excerpt.php b/modules/dynamic-tags/tags/post-excerpt.php new file mode 100644 index 00000000..3b35a897 --- /dev/null +++ b/modules/dynamic-tags/tags/post-excerpt.php @@ -0,0 +1,107 @@ +add_control( + 'max_length', + [ + 'label' => esc_html__( 'Excerpt Length', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => null, + 'min' => 0, + 'step' => 1, + 'should_force_int' => true, + ] + ); + + $this->add_control( + 'apply_to_post_content', + [ + 'label' => esc_html__( 'Apply to post content', 'elementor-pro' ), + 'atomic_label' => esc_html__( 'Apply post content', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'default' => 'no', + ] + ); + } + + public function get_categories() { + return [ Module::TEXT_CATEGORY ]; + } + + public function should_get_excerpt_from_post_content( $settings ) { + return 'yes' === $settings['apply_to_post_content'] || true === $settings['apply_to_post_content']; + } + + public function is_post_excerpt_valid( $settings, $post ) { + if ( ! $post ) { + return false; + } + + if ( empty( $post->post_excerpt ) && ! $this->should_get_excerpt_from_post_content( $settings ) ) { + return false; + } + + if ( empty( $post->post_excerpt ) && empty( $post->post_content ) && $this->should_get_excerpt_from_post_content( $settings ) ) { + return false; + } + + if ( empty( $post->post_excerpt ) && empty( $post->post_content ) ) { + return false; + } + + return true; + } + + public function get_post_excerpt( $settings, $post ) { + $post_excerpt = $post->post_excerpt ?? ''; + + if ( empty( $post_excerpt ) && ! empty( $post->post_content ) && $this->should_get_excerpt_from_post_content( $settings ) ) { + $post_excerpt = apply_filters( 'the_excerpt', get_the_excerpt( $post ) ); + } + + return $post_excerpt; + } + + public function render() { + // Allow only a real `post_excerpt` and not the trimmed `post_content` from the `get_the_excerpt` filter + $post = get_post(); + $settings = $this->get_settings_for_display(); + + if ( ! $this->is_post_excerpt_valid( $settings, $post ) ) { + return; + } + + $max_length = (int) $settings['max_length']; + $excerpt = $this->get_post_excerpt( $settings, $post ); + + $excerpt = Utils::trim_words( $excerpt, $max_length ); + + echo wp_kses_post( $excerpt ); + } +} diff --git a/modules/dynamic-tags/tags/post-featured-image.php b/modules/dynamic-tags/tags/post-featured-image.php new file mode 100644 index 00000000..32863d57 --- /dev/null +++ b/modules/dynamic-tags/tags/post-featured-image.php @@ -0,0 +1,57 @@ + $thumbnail_id, + 'url' => wp_get_attachment_image_src( $thumbnail_id, 'full' )[0], + ]; + } else { + $image_data = $this->get_settings( 'fallback' ); + } + + return $image_data; + } + + protected function register_controls() { + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/post-gallery.php b/modules/dynamic-tags/tags/post-gallery.php new file mode 100644 index 00000000..b7ecdb57 --- /dev/null +++ b/modules/dynamic-tags/tags/post-gallery.php @@ -0,0 +1,59 @@ +ID, array_column( $value, 'id' ), true ) ) { + $value[] = [ + 'id' => $image->ID, + ]; + } + } + + return $value; + } +} diff --git a/modules/dynamic-tags/tags/post-id.php b/modules/dynamic-tags/tags/post-id.php new file mode 100644 index 00000000..ef61714a --- /dev/null +++ b/modules/dynamic-tags/tags/post-id.php @@ -0,0 +1,34 @@ + true, + 'object_type' => [ get_post_type() ], + ]; + + /** + * Dynamic tags taxonomy args. + * + * Filters the taxonomy arguments used to retrieve the registered taxonomies + * displayed in the taxonomy dynamic tag. + * + * @since 2.0.0 + * + * @param array $taxonomy_filter_args An array of `key => value` arguments to + * match against the taxonomy objects inside + * the `get_taxonomies()` function. + */ + $taxonomy_filter_args = apply_filters( 'elementor_pro/dynamic_tags/post_terms/taxonomy_args', $taxonomy_filter_args ); + + $taxonomies = Utils::get_taxonomies( $taxonomy_filter_args, 'objects' ); + + $options = []; + + foreach ( $taxonomies as $taxonomy => $object ) { + $options[ $taxonomy ] = $object->label; + } + + $this->add_control( + 'taxonomy', + [ + 'label' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $options, + 'default' => 'post_tag', + ] + ); + + $this->add_control( + 'separator', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => ', ', + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + } + + public function render() { + $settings = $this->get_settings(); + + if ( 'yes' === $settings['link'] || true === $settings['link'] ) { + $value = get_the_term_list( get_the_ID(), $settings['taxonomy'], '', $settings['separator'] ); + } else { + $terms = get_the_terms( get_the_ID(), $settings['taxonomy'] ); + + if ( is_wp_error( $terms ) || empty( $terms ) ) { + return ''; + } + + $term_names = []; + + foreach ( $terms as $term ) { + $term_names[] = '' . $term->name . ''; + } + + $value = implode( $settings['separator'], $term_names ); + } + + echo wp_kses_post( $value ); + } +} diff --git a/modules/dynamic-tags/tags/post-time.php b/modules/dynamic-tags/tags/post-time.php new file mode 100644 index 00000000..bc4f6e3f --- /dev/null +++ b/modules/dynamic-tags/tags/post-time.php @@ -0,0 +1,96 @@ +add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'post_date_gmt' => esc_html__( 'Post Published', 'elementor-pro' ), + 'post_modified_gmt' => esc_html__( 'Post Modified', 'elementor-pro' ), + ], + 'default' => 'post_date_gmt', + ] + ); + + $this->add_control( + 'format', + [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'g:i a' => gmdate( 'g:i a' ), + 'g:i A' => gmdate( 'g:i A' ), + 'H:i' => gmdate( 'H:i' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $this->add_control( + 'custom_format', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'default' => '', + 'description' => sprintf( '%s', esc_html__( 'Documentation on date and time formatting', 'elementor-pro' ) ), + 'condition' => [ + 'format' => 'custom', + ], + ] + ); + } + + public function render() { + $time_type = $this->get_settings( 'type' ); + $format = $this->get_settings( 'format' ); + + switch ( $format ) { + case 'default': + $date_format = ''; + break; + case 'custom': + $date_format = $this->get_settings( 'custom_format' ); + break; + default: + $date_format = $format; + break; + } + + if ( 'post_date_gmt' === $time_type ) { + $value = get_the_time( $date_format ); + } else { + $value = get_the_modified_time( $date_format ); + } + + echo wp_kses_post( $value ); + } +} diff --git a/modules/dynamic-tags/tags/post-title.php b/modules/dynamic-tags/tags/post-title.php new file mode 100644 index 00000000..5cd67bb8 --- /dev/null +++ b/modules/dynamic-tags/tags/post-title.php @@ -0,0 +1,31 @@ +frontend->create_action_hash is safe. + echo Plugin::elementor()->frontend->create_action_hash( 'reload-page' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/dynamic-tags/tags/request-parameter.php b/modules/dynamic-tags/tags/request-parameter.php new file mode 100644 index 00000000..56149000 --- /dev/null +++ b/modules/dynamic-tags/tags/request-parameter.php @@ -0,0 +1,82 @@ +get_settings(); + $request_type = isset( $settings['request_type'] ) ? strtoupper( $settings['request_type'] ) : false; + $param_name = isset( $settings['param_name'] ) ? $settings['param_name'] : false; + $value = ''; + + if ( ! $param_name || ! $request_type ) { + return ''; + } + + switch ( $request_type ) { + case 'POST': + $value = Utils::_unstable_get_super_global_value( $_POST, $param_name ) ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing + break; + case 'GET': + $value = Utils::_unstable_get_super_global_value( $_GET, $param_name ) ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended + break; + case 'QUERY_VAR': + $value = get_query_var( $param_name ); + break; + } + echo htmlentities( wp_kses_post( $value ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + protected function register_controls() { + $this->add_control( + 'request_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'get', + 'options' => [ + 'get' => 'Get', + 'post' => 'Post', + 'query_var' => 'Query Var', + ], + ] + ); + $this->add_control( + 'param_name', + [ + 'label' => esc_html__( 'Parameter Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/shortcode.php b/modules/dynamic-tags/tags/shortcode.php new file mode 100644 index 00000000..6d918f28 --- /dev/null +++ b/modules/dynamic-tags/tags/shortcode.php @@ -0,0 +1,79 @@ +add_control( + 'shortcode', + [ + 'label' => esc_html__( 'Shortcode', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'ai' => [ + 'active' => false, + ], + ], + ); + } + + public function render() { + $settings = $this->get_settings(); + + if ( empty( $settings['shortcode'] ) ) { + return; + } + + $shortcode_string = $settings['shortcode']; + + $value = do_shortcode( $shortcode_string ); + + $should_escape = true; + + /** + * Should escape shortcodes. + * + * By default shortcodes in dynamic tags are escaped. This hook allows developers + * to avoid shortcodes from beeing escaped. Defaults to true. + * + * @since 2.2.1 + * + * @param bool $should_escape Whether to escape shortcodes in dynamic tags. + */ + $should_escape = apply_filters( 'elementor_pro/dynamic_tags/shortcode/should_escape', $should_escape ); + + if ( $should_escape ) { + $value = wp_kses_post( $value ); + } + // PHPCS - the variable $value is safe. + echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/dynamic-tags/tags/site-logo.php b/modules/dynamic-tags/tags/site-logo.php new file mode 100644 index 00000000..487e28aa --- /dev/null +++ b/modules/dynamic-tags/tags/site-logo.php @@ -0,0 +1,42 @@ + $custom_logo_id, + 'url' => $url, + ]; + } +} diff --git a/modules/dynamic-tags/tags/site-tagline.php b/modules/dynamic-tags/tags/site-tagline.php new file mode 100644 index 00000000..ec236050 --- /dev/null +++ b/modules/dynamic-tags/tags/site-tagline.php @@ -0,0 +1,31 @@ +get_settings( 'type' ); + $user = wp_get_current_user(); + if ( empty( $type ) || 0 === $user->ID ) { + return; + } + + $value = ''; + switch ( $type ) { + case 'login': + case 'email': + case 'url': + case 'nicename': + $field = 'user_' . $type; + $value = isset( $user->$field ) ? $user->$field : ''; + break; + case 'id': + $value = $user->ID; + break; + case 'description': + case 'first_name': + case 'last_name': + case 'display_name': + $value = isset( $user->$type ) ? $user->$type : ''; + break; + case 'meta': + $key = $this->get_settings( 'meta_key' ); + if ( ! empty( $key ) ) { + $value = get_user_meta( $user->ID, $key, true ); + } + break; + } + + echo wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'type'; + } + + protected function register_controls() { + $this->add_control( + 'type', + [ + 'label' => esc_html__( 'Field', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Choose', 'elementor-pro' ), + 'id' => esc_html__( 'ID', 'elementor-pro' ), + 'display_name' => esc_html__( 'Display Name', 'elementor-pro' ), + 'login' => esc_html__( 'Username', 'elementor-pro' ), + 'first_name' => esc_html__( 'First Name', 'elementor-pro' ), + 'last_name' => esc_html__( 'Last Name', 'elementor-pro' ), + 'description' => esc_html__( 'Bio', 'elementor-pro' ), + 'email' => esc_html__( 'Email', 'elementor-pro' ), + 'url' => esc_html__( 'Website', 'elementor-pro' ), + 'meta' => esc_html__( 'User Meta', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'meta_key', + [ + 'label' => esc_html__( 'Meta Key', 'elementor-pro' ), + 'condition' => [ + 'type' => 'meta', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + } +} diff --git a/modules/dynamic-tags/tags/user-profile-picture.php b/modules/dynamic-tags/tags/user-profile-picture.php new file mode 100644 index 00000000..0bb7d5de --- /dev/null +++ b/modules/dynamic-tags/tags/user-profile-picture.php @@ -0,0 +1,21 @@ + '', + 'url' => get_avatar_url( get_current_user_id() ), + ]; + } +} diff --git a/modules/dynamic-tags/toolset/module.php b/modules/dynamic-tags/toolset/module.php new file mode 100644 index 00000000..55a3a164 --- /dev/null +++ b/modules/dynamic-tags/toolset/module.php @@ -0,0 +1,114 @@ + $field ) { + if ( ! is_array( $field ) || empty( $field['type'] ) ) { + continue; + } + + if ( ! self::valid_field_type( $types, $field ) ) { + continue; + } + + // Use group ID for unique keys + $key = $group['slug'] . ':' . $field_key; + $options[ $key ] = $field['name']; + } + + if ( empty( $options ) ) { + continue; + } + + if ( 1 === count( $options ) ) { + $options = [ -1 => ' -- ' ] + $options; + } + + $groups[] = [ + 'label' => $group['name'], + 'options' => $options, + ]; + } + + return $groups; + } + + public static function toolset_image_mapping( $field, $single = true ) { + if ( 'image' !== $field['type'] ) { + return false; + } + + $limit = $single ? '0' : '1'; + if ( empty( $field['data'] ) || $limit !== $field['data']['repetitive'] ) { + return false; + } + + return true; + } + + public static function valid_field_type( $types, $field ) { + // Only file field with single image value + if ( in_array( 'toolset_image', $types, true ) && self::toolset_image_mapping( $field ) ) { + return true; + } + + // Only file with multiple images allowed + if ( in_array( 'toolset_gallery', $types, true ) && self::toolset_image_mapping( $field, false ) ) { + return true; + } + + // Any other type + if ( in_array( $field['type'], $types, true ) ) { + return true; + } + + return false; + } + + public function get_tag_classes_names() { + return [ + 'Toolset_Text', + 'Toolset_Date', + 'Toolset_Image', + 'Toolset_URL', + 'Toolset_Gallery', + ]; + } + + public function get_groups() { + return [ + self::TOOLSET_GROUP => [ + 'title' => esc_html__( 'Toolset', 'elementor-pro' ), + ], + ]; + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-base.php b/modules/dynamic-tags/toolset/tags/toolset-base.php new file mode 100644 index 00000000..1c99e75d --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-base.php @@ -0,0 +1,39 @@ +add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + } + + protected function get_supported_fields() { + return []; + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-date.php b/modules/dynamic-tags/toolset/tags/toolset-date.php new file mode 100644 index 00000000..866d1f76 --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-date.php @@ -0,0 +1,112 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return; + } + + list( $field_group, $field_key ) = explode( ':', $key ); + + $field = wpcf_admin_fields_get_field( $field_key ); + $value = ''; + + if ( $field && ! empty( $field['type'] ) && 'date' === $field['type'] ) { + + $format = $this->get_settings( 'format' ); + + $timestamp = types_render_field( $field_key, [ + 'output' => 'raw', + 'style' => 'text', + ] ); + + if ( empty( $timestamp ) ) { + return $value; + } + + if ( 'human' === $format ) { + /* translators: %s: Human readable date/time. */ + $value = human_time_diff( $timestamp ); + } else { + switch ( $format ) { + case 'default': + $date_format = get_option( 'date_format' ); + break; + case 'custom': + $date_format = $this->get_settings( 'custom_format' ); + break; + default: + $date_format = $format; + break; + } + + $value = date_i18n( $date_format, $timestamp ); + } + } + echo wp_kses_post( $value ); + } + + public function get_panel_template_setting_key() { + return 'key'; + } + + protected function register_controls() { + parent::register_controls(); + + $this->add_control( + 'format', + [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'F j, Y' => gmdate( 'F j, Y' ), + 'Y-m-d' => gmdate( 'Y-m-d' ), + 'm/d/Y' => gmdate( 'm/d/Y' ), + 'd/m/Y' => gmdate( 'd/m/Y' ), + 'human' => esc_html__( 'Human Readable', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $this->add_control( + 'custom_format', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'default' => '', + 'description' => sprintf( '%s', esc_html__( 'Documentation on date and time formatting', 'elementor-pro' ) ), + 'condition' => [ + 'format' => 'custom', + ], + ] + ); + } + + protected function get_supported_fields() { + return [ 'date' ]; + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-gallery.php b/modules/dynamic-tags/toolset/tags/toolset-gallery.php new file mode 100644 index 00000000..93c2ae34 --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-gallery.php @@ -0,0 +1,113 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return []; + } + + $images = []; + + list( $field_group, $field_key ) = explode( ':', $key ); + + $field = wpcf_admin_fields_get_field( $field_key ); + + if ( $field && ! empty( $field['type'] ) ) { + + $galley_images = types_render_field( $field_key, [ + 'separator' => '|', + 'url' => true, + ] ); + $galley_images = explode( '|', $galley_images ); + foreach ( $galley_images as $image_url ) { + $images[] = [ + 'id' => $this->get_cached_attachment_url_to_post_id( $image_url ), + 'url' => $image_url, + ]; + } + } + + return $images; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + } + + protected function get_supported_fields() { + return [ + 'toolset_gallery', + ]; + } + + /** + * @param $attachment_url + * + * @return false|int|mixed + */ + private function get_cached_attachment_url_to_post_id( $attachment_url ) { + $id = wp_cache_get( $attachment_url, __CLASS__ ); + + if ( false === $id ) { + $id = attachment_url_to_postid( $attachment_url ); + + wp_cache_set( $attachment_url, $id, __CLASS__ ); + } + + return $id; + } + + /** + * Toolset_Gallery constructor. + * + * @param array $data + */ + public function __construct( array $data = [] ) { + parent::__construct( $data ); + + wp_cache_add_non_persistent_groups( __CLASS__ ); + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-image.php b/modules/dynamic-tags/toolset/tags/toolset-image.php new file mode 100644 index 00000000..0e70e72b --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-image.php @@ -0,0 +1,91 @@ +get_settings( 'key' ); + $image_data = $this->get_settings( 'fallback' ); + if ( empty( $key ) ) { + return $image_data; + } + + list( $field_group, $field_key ) = explode( ':', $key ); + + $field = wpcf_admin_fields_get_field( $field_key ); + + if ( $field && ! empty( $field['type'] ) ) { + + $url = types_render_field( $field_key, [ 'url' => true ] ); + + if ( empty( $url ) ) { + return $image_data; + } + + $image_data = [ + 'id' => attachment_url_to_postid( $url ), + 'url' => $url, + ]; + } + + return $image_data; + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + ] + ); + } + + protected function get_supported_fields() { + return [ + 'toolset_image', + ]; + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-text.php b/modules/dynamic-tags/toolset/tags/toolset-text.php new file mode 100644 index 00000000..6773f0f9 --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-text.php @@ -0,0 +1,70 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return; + } + + list( $field_group, $field_key ) = explode( ':', $key ); + + $field = wpcf_admin_fields_get_field( $field_key ); + + if ( $field && ! empty( $field['type'] ) ) { + $value = ''; + switch ( $field['type'] ) { + case 'google_address': + $value = types_render_field( $field_key, [ 'format' => 'FIELD_ADDRESS' ] ); + break; + case 'email': + case 'embed': + $value = types_render_field( $field_key, [ 'output' => 'raw' ] ); + break; + default: + $value = types_render_field( $field_key ); + break; + } // End switch(). + } else { + // Field settings has been deleted or not available. + $value = types_render_field( $field_key ); + } // End if(). + + echo wp_kses_post( $value ); + } + + protected function get_supported_fields() { + return [ + 'textfield', + 'phone', + 'textarea', + 'checkbox', + 'select', + 'numeric', + 'email', + 'embed', + 'google_address', + 'wysiwyg', + 'radio', + ]; + } +} diff --git a/modules/dynamic-tags/toolset/tags/toolset-url.php b/modules/dynamic-tags/toolset/tags/toolset-url.php new file mode 100644 index 00000000..ffb4efe8 --- /dev/null +++ b/modules/dynamic-tags/toolset/tags/toolset-url.php @@ -0,0 +1,97 @@ +get_settings( 'key' ); + if ( empty( $key ) ) { + return; + } + + list( $field_group, $field_key ) = explode( ':', $key ); + + $field = wpcf_admin_fields_get_field( $field_key ); + + if ( $field && ! empty( $field['type'] ) ) { + $value = ''; + switch ( $field['type'] ) { + case 'email': + $value = 'mailto:' . types_render_field( $field_key, [ 'output' => 'raw' ] ); + break; + case 'image': + $value = types_render_field( $field_key, [ 'url' => true ] ); + break; + default: + $value = types_render_field( $field_key, [ 'output' => 'raw' ] ); + } // End switch(). + } + + if ( empty( $value ) && $this->get_settings( 'fallback' ) ) { + $value = $this->get_settings( 'fallback' ); + } + + return wp_kses_post( $value ); + } + + protected function register_controls() { + $this->add_control( + 'key', + [ + 'label' => esc_html__( 'Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => Module::get_control_options( $this->get_supported_fields() ), + ] + ); + + $this->add_control( + 'fallback', + [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + ] + ); + } + + protected function get_supported_fields() { + return [ + 'email', + 'image', + 'file', + 'audio', + 'url', + ]; + } +} diff --git a/modules/element-manager/module.php b/modules/element-manager/module.php new file mode 100644 index 00000000..e62db883 --- /dev/null +++ b/modules/element-manager/module.php @@ -0,0 +1,83 @@ + $restricted_roles ) { + $compare_roles = array_intersect( $user->roles, $restricted_roles ); + + if ( ! empty( $compare_roles ) ) { + $additional_config['widgets'][ $element_name ]['show_in_panel'] = false; + } + } + + return $additional_config; + }, 100, 2 ); + + add_action( 'elementor/element_manager/save_disabled_elements', function() { + $role_restrictions = Utils::get_super_global_value( $_POST, 'elements_restriction' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + + if ( empty( $role_restrictions ) ) { + return; + } + + $role_restrictions = json_decode( $role_restrictions, true ); + + if ( is_array( $role_restrictions ) ) { + Options::update_role_restrictions( $role_restrictions ); + } + } ); + + add_filter( 'elementor/element_manager/admin_app_data/additional_data', function( $additional_data ) { + $additional_data['roles'] = $this->get_roles(); + $additional_data['role_restrictions'] = Options::get_role_restrictions(); + + return $additional_data; + } ); + } + + private function get_roles() : array { + $roles = []; + + foreach ( get_editable_roles() as $role => $details ) { + if ( 'administrator' === $role ) { + continue; + } + + $name = translate_user_role( $details['name'] ); + + $roles[] = [ + 'id' => $role, + 'name' => $name, + ]; + } + + return $roles; + } +} diff --git a/modules/element-manager/options.php b/modules/element-manager/options.php new file mode 100644 index 00000000..ed7ea630 --- /dev/null +++ b/modules/element-manager/options.php @@ -0,0 +1,17 @@ +breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-flip-box', + Plugin::get_frontend_file_url( "widget-flip-box{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/flip-box/widgets/flip-box.php b/modules/flip-box/widgets/flip-box.php new file mode 100644 index 00000000..4aec6fa7 --- /dev/null +++ b/modules/flip-box/widgets/flip-box.php @@ -0,0 +1,1790 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-flip-box' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_side_a_content', + [ + 'label' => esc_html__( 'Front', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'graphic_element', + [ + 'label' => esc_html__( 'Graphic Element', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'none' => [ + 'title' => esc_html__( 'None', 'elementor-pro' ), + 'icon' => 'eicon-ban', + ], + 'image' => [ + 'title' => esc_html__( 'Image', 'elementor-pro' ), + 'icon' => 'eicon-image-bold', + ], + 'icon' => [ + 'title' => esc_html__( 'Icon', 'elementor-pro' ), + 'icon' => 'eicon-star', + ], + ], + 'default' => 'icon', + ] + ); + + $this->add_control( + 'image', + [ + 'label' => esc_html__( 'Choose Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'image', // Actually its `image_size` + 'default' => 'thumbnail', + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'selected_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-star', + 'library' => 'fa-solid', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'title_text_a', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'This is the heading', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your title', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'description_text_a', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your description', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'rows' => 10, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_side_b_content', + [ + 'label' => esc_html__( 'Back', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title_text_b', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'This is the heading', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your title', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + ] + ); + + $this->add_control( + 'description_text_b', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Enter your description', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'rows' => 10, + ] + ); + + $this->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Button Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Click Here', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'link_click', + [ + 'label' => esc_html__( 'Apply Link On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'box' => esc_html__( 'Whole Box', 'elementor-pro' ), + 'button' => esc_html__( 'Button Only', 'elementor-pro' ), + ], + 'default' => 'button', + 'condition' => [ + 'link[url]!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_box_settings', + [ + 'label' => esc_html__( 'Settings', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'h3', + ] + ); + + $this->add_control( + 'description_tag', + [ + 'label' => esc_html__( 'Description HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'div', + ] + ); + + $this->add_responsive_control( + 'height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'em' => [ + 'min' => 10, + 'max' => 100, + ], + 'rem' => [ + 'min' => 10, + 'max' => 100, + ], + 'vh' => [ + 'min' => 10, + 'max' => 100, + ], + ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'separator' => 'after', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__layer, {{WRAPPER}} .elementor-flip-box__layer__overlay' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'flip_effect', + [ + 'label' => esc_html__( 'Flip Effect', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'flip', + 'options' => [ + 'flip' => 'Flip', + 'slide' => 'Slide', + 'push' => 'Push', + 'zoom-in' => 'Zoom In', + 'zoom-out' => 'Zoom Out', + 'fade' => 'Fade', + ], + 'prefix_class' => 'elementor-flip-box--effect-', + ] + ); + + $this->add_control( + 'flip_direction', + [ + 'label' => esc_html__( 'Flip Direction', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'up', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'up' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'down' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'toggle' => false, + 'condition' => [ + 'flip_effect!' => [ + 'fade', + 'zoom-in', + 'zoom-out', + ], + ], + 'prefix_class' => 'elementor-flip-box--direction-', + ] + ); + + $this->add_control( + 'flip_3d', + [ + 'label' => esc_html__( '3D Depth', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'return_value' => 'elementor-flip-box--3d', + 'default' => '', + 'prefix_class' => '', + 'condition' => [ + 'flip_effect' => 'flip', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_a', + [ + 'label' => esc_html__( 'Front', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'background_a', + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__front', + ] + ); + + $this->add_control( + 'background_overlay_a', + [ + 'label' => esc_html__( 'Background Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay' => 'background-color: {{VALUE}};', + ], + 'separator' => 'before', + 'condition' => [ + 'background_a_image[id]!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'background_overlay_a_filters', + 'selector' => '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay', + 'condition' => [ + 'background_overlay_a!' => '', + ], + ] + ); + + $this->add_control( + 'background_overlay_a_blend_mode', + [ + 'label' => esc_html__( 'Blend Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'multiply' => 'Multiply', + 'screen' => 'Screen', + 'overlay' => 'Overlay', + 'darken' => 'Darken', + 'lighten' => 'Lighten', + 'color-dodge' => 'Color Dodge', + 'color-burn' => 'Color Burn', + 'hue' => 'Hue', + 'saturation' => 'Saturation', + 'color' => 'Color', + 'exclusion' => 'Exclusion', + 'luminosity' => 'Luminosity', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay' => 'mix-blend-mode: {{VALUE}}', + ], + 'condition' => [ + 'background_overlay_a!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'padding_a', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'alignment_a', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'vertical_position_a', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__overlay' => 'justify-content: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'border_a', + 'selector' => '{{WRAPPER}} .elementor-flip-box__front', + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'shadow_a', + 'selector' => '{{WRAPPER}} .elementor-flip-box__front', + ] + ); + + $this->add_control( + 'heading_image_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'condition' => [ + 'graphic_element' => 'image', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'image_spacing', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__image' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'image_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 5, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__image img' => 'width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'image_opacity', + [ + 'label' => esc_html__( 'Opacity', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'max' => 1, + 'min' => 0.10, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__image' => 'opacity: {{SIZE}};', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'image_border', + 'selector' => '{{WRAPPER}} .elementor-flip-box__image img', + 'condition' => [ + 'graphic_element' => 'image', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__image img' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'image', + ], + ] + ); + + $this->add_control( + 'heading_icon_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'condition' => [ + 'graphic_element' => 'icon', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'icon_view', + [ + 'label' => esc_html__( 'View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + 'framed' => esc_html__( 'Framed', 'elementor-pro' ), + ], + 'default' => 'default', + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_shape', + [ + 'label' => esc_html__( 'Shape', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'circle' => esc_html__( 'Circle', 'elementor-pro' ), + 'square' => esc_html__( 'Square', 'elementor-pro' ), + ], + 'default' => 'circle', + 'condition' => [ + 'icon_view!' => 'default', + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_spacing', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-wrapper' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-view-stacked .elementor-icon' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon svg' => 'stroke: {{VALUE}}', + '{{WRAPPER}} .elementor-view-framed .elementor-icon, {{WRAPPER}} .elementor-view-default .elementor-icon' => 'color: {{VALUE}}; border-color: {{VALUE}}', + '{{WRAPPER}} .elementor-view-framed .elementor-icon svg, {{WRAPPER}} .elementor-view-default .elementor-icon svg' => 'fill: {{VALUE}}; border-color: {{VALUE}}', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-view-framed .elementor-icon' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-view-framed .elementor-icon svg' => 'stroke: {{VALUE}};', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-view-stacked .elementor-icon svg' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 6, + 'max' => 300, + ], + 'em' => [ + 'min' => 0.6, + 'max' => 30, + ], + 'rem' => [ + 'min' => 0.6, + 'max' => 30, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'font-size: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-icon svg' => 'width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_padding', + [ + 'label' => esc_html__( 'Icon Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'padding: {{SIZE}}{{UNIT}};', + ], + 'range' => [ + 'em' => [ + 'min' => 0, + 'max' => 5, + ], + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + ] + ); + + $this->add_control( + 'icon_rotate', + [ + 'label' => esc_html__( 'Icon Rotate', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'deg', 'grad', 'rad', 'turn' ], + 'default' => [ + 'size' => 0, + 'unit' => 'deg', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon i' => 'transform: rotate({{SIZE}}{{UNIT}});', + '{{WRAPPER}} .elementor-icon svg' => 'transform: rotate({{SIZE}}{{UNIT}});', + ], + 'condition' => [ + 'graphic_element' => 'icon', + ], + ] + ); + + $this->add_control( + 'icon_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'border-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view' => 'framed', + ], + ] + ); + + $this->add_control( + 'icon_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'graphic_element' => 'icon', + 'icon_view!' => 'default', + ], + ] + ); + + $this->add_control( + 'heading_title_style_a', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'title_text_a!' => '', + ], + ] + ); + + $this->add_control( + 'title_spacing_a', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__title' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'description_text_a!' => '', + 'title_text_a!' => '', + ], + ] + ); + + $this->add_control( + 'title_color_a', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__title' => 'color: {{VALUE}}', + + ], + 'condition' => [ + 'title_text_a!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography_a', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__title', + 'condition' => [ + 'title_text_a!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__title', + ] + ); + + $this->add_control( + 'heading_description_style_a', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'description_text_a!' => '', + ], + ] + ); + + $this->add_control( + 'description_color_a', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__description' => 'color: {{VALUE}}', + + ], + 'condition' => [ + 'description_text_a!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography_a', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__front .elementor-flip-box__layer__description', + 'condition' => [ + 'description_text_a!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_b', + [ + 'label' => esc_html__( 'Back', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'background_b', + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__back', + ] + ); + + $this->add_control( + 'background_overlay_b', + [ + 'label' => esc_html__( 'Background Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay' => 'background-color: {{VALUE}};', + ], + 'separator' => 'before', + 'condition' => [ + 'background_b_image[id]!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'background_overlay_b_filters', + 'selector' => '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay', + 'condition' => [ + 'background_overlay_b!' => '', + ], + ] + ); + + $this->add_control( + 'background_overlay_b_blend_mode', + [ + 'label' => esc_html__( 'Blend Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'multiply' => 'Multiply', + 'screen' => 'Screen', + 'overlay' => 'Overlay', + 'darken' => 'Darken', + 'lighten' => 'Lighten', + 'color-dodge' => 'Color Dodge', + 'color-burn' => 'Color Burn', + 'hue' => 'Hue', + 'saturation' => 'Saturation', + 'color' => 'Color', + 'exclusion' => 'Exclusion', + 'luminosity' => 'Luminosity', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay' => 'mix-blend-mode: {{VALUE}}', + ], + 'condition' => [ + 'background_overlay_b!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'padding_b', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'alignment_b', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay' => 'text-align: {{VALUE}}', + '{{WRAPPER}} .elementor-flip-box__button' => 'margin-{{VALUE}}: 0', + ], + ] + ); + + $this->add_control( + 'vertical_position_b', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__overlay' => 'justify-content: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'border_b', + 'selector' => '{{WRAPPER}} .elementor-flip-box__back', + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'shadow_b', + 'selector' => '{{WRAPPER}} .elementor-flip-box__back', + ] + ); + + $this->add_control( + 'heading_title_style_b', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'title_text_b!' => '', + ], + ] + ); + + $this->add_control( + 'title_spacing_b', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__title' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'title_text_b!' => '', + ], + ] + ); + + $this->add_control( + 'title_color_b', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__title' => 'color: {{VALUE}}', + + ], + 'condition' => [ + 'title_text_b!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography_b', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__title', + 'condition' => [ + 'title_text_b!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke_b', + 'selector' => '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__title', + ] + ); + + $this->add_control( + 'heading_description_style_b', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'description_text_b!' => '', + ], + ] + ); + + $this->add_control( + 'description_spacing_b', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__description' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'description_text_b!' => '', + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'description_color_b', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__description' => 'color: {{VALUE}}', + + ], + 'condition' => [ + 'description_text_b!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography_b', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__back .elementor-flip-box__layer__description', + 'condition' => [ + 'description_text_b!' => '', + ], + ] + ); + + $this->add_control( + 'heading_button', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'sm', + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .elementor-flip-box__button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->start_controls_tabs( 'button_tabs' ); + + $this->start_controls_tab( 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__button', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'button_text!' => '', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button:hover' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_hover_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-flip-box__button:hover', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button' => 'border-width: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-flip-box__button' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->end_controls_section(); + + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $wrapper_tag = 'div'; + $button_tag = 'a'; + $title_tag = Utils::validate_html_tag( $settings['title_tag'] ); + $description_tag = Utils::validate_html_tag( $settings['description_tag'] ); + $migration_allowed = Icons_Manager::is_migration_allowed(); + $this->add_render_attribute( 'button', 'class', [ + 'elementor-flip-box__button', + 'elementor-button', + 'elementor-size-' . $settings['button_size'], + ] ); + + $this->add_render_attribute( 'wrapper', 'class', 'elementor-flip-box__layer elementor-flip-box__back' ); + + if ( ! empty( $settings['link']['url'] ) ) { + $link_element = 'button'; + + if ( 'box' === $settings['link_click'] ) { + $wrapper_tag = 'a'; + $button_tag = 'span'; + $link_element = 'wrapper'; + } + + $this->add_link_attributes( $link_element, $settings['link'] ); + } + + if ( 'icon' === $settings['graphic_element'] ) { + $this->add_render_attribute( 'icon-wrapper', 'class', 'elementor-icon-wrapper' ); + $this->add_render_attribute( 'icon-wrapper', 'class', 'elementor-view-' . $settings['icon_view'] ); + if ( 'default' != $settings['icon_view'] ) { + $this->add_render_attribute( 'icon-wrapper', 'class', 'elementor-shape-' . $settings['icon_shape'] ); + } + + if ( ! isset( $settings['icon'] ) && ! $migration_allowed ) { + // add old default + $settings['icon'] = 'fa fa-star'; + } + + if ( ! empty( $settings['icon'] ) ) { + $this->add_render_attribute( 'icon', 'class', $settings['icon'] ); + } + } + + $has_icon = ! empty( $settings['icon'] ) || ! empty( $settings['selected_icon'] ); + $migrated = isset( $settings['__fa4_migrated']['selected_icon'] ); + $is_new = empty( $settings['icon'] ) && $migration_allowed; + + ?> +
      +
      +
      +
      + +
      + +
      + +
      print_render_attribute_string( 'icon-wrapper' ); ?>> +
      + + print_render_attribute_string( 'icon' ); ?>> + +
      +
      + + + + < class="elementor-flip-box__layer__title"> + + > + + + + < class="elementor-flip-box__layer__description"> + + > + +
      +
      +
      + < print_render_attribute_string( 'wrapper' ); ?>> +
      +
      + + < class="elementor-flip-box__layer__title"> + + > + + + + < class="elementor-flip-box__layer__description"> + + > + + + + < print_render_attribute_string( 'button' ); ?>> + + > + +
      +
      + > +
      + + <# + var btnClasses = 'elementor-flip-box__button elementor-button elementor-size-' + settings.button_size; + + if ( 'image' === settings.graphic_element && '' !== settings.image.url ) { + var image = { + id: settings.image.id, + url: settings.image.url, + size: settings.image_size, + dimension: settings.image_custom_dimension, + model: view.getEditModel() + }; + + var imageUrl = elementor.imagesManager.getImageUrl( image ); + } + + var wrapperTag = 'div', + buttonTag = 'a', + titleTag = elementor.helpers.validateHTMLTag( settings.title_tag ), + descriptionTag = elementor.helpers.validateHTMLTag( settings.description_tag ); + + if ( 'box' === settings.link_click ) { + wrapperTag = 'a'; + buttonTag = 'span'; + } + + if ( 'icon' === settings.graphic_element ) { + var iconWrapperClasses = 'elementor-icon-wrapper'; + iconWrapperClasses += ' elementor-view-' + settings.icon_view; + if ( 'default' !== settings.icon_view ) { + iconWrapperClasses += ' elementor-shape-' + settings.icon_shape; + } + } + var hasIcon = settings.icon || settings.selected_icon, + iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ), + migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ); + #> + +
      +
      +
      +
      + <# if ( 'image' === settings.graphic_element && '' !== settings.image.url ) { #> +
      + +
      + <# } else if ( 'icon' === settings.graphic_element && hasIcon ) { #> +
      +
      + <# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #> + {{{ iconHTML.value }}} + <# } else { #> + + <# } #> +
      +
      + <# } #> + + <# if ( settings.title_text_a ) { #> + <{{ titleTag }} class="elementor-flip-box__layer__title">{{ settings.title_text_a }} + <# } #> + + <# if ( settings.description_text_a ) { #> + <{{ descriptionTag }} class="elementor-flip-box__layer__description">{{ settings.description_text_a }} + <# } #> +
      +
      +
      + <{{ wrapperTag }} class="elementor-flip-box__layer elementor-flip-box__back"> +
      +
      + <# if ( settings.title_text_b ) { #> + <{{ titleTag }} class="elementor-flip-box__layer__title">{{ settings.title_text_b }} + <# } #> + + <# if ( settings.description_text_b ) { #> + <{{ descriptionTag }} class="elementor-flip-box__layer__description">{{ settings.description_text_b }} + <# } #> + + <# if ( settings.button_text ) { #> + <{{ buttonTag }} href="#" class="{{ btnClasses }}">{{ settings.button_text }} + <# } #> +
      +
      + +
      + experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/floating-buttons/base/widget-floating-bars-base-pro.php b/modules/floating-buttons/base/widget-floating-bars-base-pro.php new file mode 100644 index 00000000..9a2edc83 --- /dev/null +++ b/modules/floating-buttons/base/widget-floating-bars-base-pro.php @@ -0,0 +1,13 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/floating-buttons/classes/render/contact-buttons-var-1-render.php b/modules/floating-buttons/classes/render/contact-buttons-var-1-render.php new file mode 100644 index 00000000..15c5fc9b --- /dev/null +++ b/modules/floating-buttons/classes/render/contact-buttons-var-1-render.php @@ -0,0 +1,62 @@ +widget->add_render_attribute( 'message-bubble', [ + 'class' => $message_bubble_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'message-bubble' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_message_bubble_container(); + ?> +
      + settings['chat_button_icon'] ?? ''; + + Icons_Manager::render_icon( $custom_icon ); + } + + public function render(): void { + $this->build_layout_render_attribute(); + $this->add_content_wrapper_render_attribute(); + + $content_classnames = 'e-contact-buttons__content'; + $animation_duration = $this->settings['style_chat_box_animation_duration']; + + if ( ! empty( $animation_duration ) ) { + $content_classnames .= ' has-animation-duration-' . $animation_duration; + } + + $this->widget->add_render_attribute( 'content', [ + 'class' => $content_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content-wrapper' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_top_bar(); + $this->render_message_bubble(); + $this->render_contact_section(); + ?> +
      +
      + render_chat_button(); + ?> +
      + widget->get_name(); + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function render_contact_section(): void { + $contact_icons = $this->settings['contact_repeater'] ?? []; + $button_size = $this->settings['style_contact_button_size']; + $button_corners = $this->settings['style_contact_corners']; + + ?> + + build_layout_render_attribute(); + + $this->widget->add_render_attribute( 'content', [ + 'class' => 'e-contact-buttons__content', + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_contact_section(); ?> +
      + settings['chat_button_icon'] ?? ''; + + Icons_Manager::render_icon( $custom_icon ); + } + + protected function render_chat_button(): void { + $button_size = $this->settings['style_chat_button_size']; + $hover_animation = $this->settings['style_button_color_hover_animation']; + $entrance_animation = $this->settings['style_chat_button_animation']; + $entrance_animation_duration = $this->settings['style_chat_button_animation_duration']; + $entrance_animation_delay = $this->settings['style_chat_button_animation_delay']; + $accessible_name = $this->settings['chat_aria_label']; + + $button_classnames = 'e-contact-buttons__chat-button e-contact-buttons__chat-button-shadow'; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + if ( ! empty( $entrance_animation ) && 'none' != $entrance_animation ) { + $button_classnames .= ' has-entrance-animation'; + } + + if ( ! empty( $entrance_animation_delay ) ) { + $button_classnames .= ' has-entrance-animation-delay'; + } + + if ( ! empty( $entrance_animation_duration ) ) { + $button_classnames .= ' has-entrance-animation-duration-' . $entrance_animation_duration; + } + + $this->widget->add_render_attribute( 'button-', [ + 'class' => $button_classnames, + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'type' => 'button', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Toggle %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'aria-expanded' => 'true', + ] ); + + ?> +
      + +
      + settings['top_bar_title'] ?? ''; + $has_top_bar_title = ! empty( $top_bar_title ); + $accessible_name = $this->settings['chat_aria_label']; + + $this->widget->add_render_attribute( 'close-button', [ + 'class' => 'e-contact-buttons__close-button', + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Close %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'type' => 'button', + ] ); + + ?> +
      + +
      + +

      + +
      +
      + settings['contact_repeater'] ?? []; + $icon_position = $this->settings['style_info_links_icon_position']; + $has_dividers = $this->settings['style_info_links_dividers']; + $hover_animation = $this->settings['style_info_links_hover_animation']; + + ?> + + settings['send_button_text']; + $hover_animation = $this->settings['style_send_hover_animation']; + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + $formatted_link = $this->settings['send_button_url']['url']; + + $this->widget->add_render_attribute( 'send-button', [ + 'aria-label' => esc_attr( $button_text ), + 'class' => $button_classnames, + 'href' => esc_url( $formatted_link ), + 'rel' => 'noopener noreferrer', + 'target' => '_blank', + ] ); + ?> + widget->get_render_attribute_string( 'send-button' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + + + widget->get_name(); + $has_animations = ! empty( $this->settings['style_chat_box_exit_animation'] ) || ! empty( $this->settings['style_chat_box_entrance_animation'] ); + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + $border_radius = $this->settings['style_chat_box_corners']; + + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( ! empty( $border_radius ) ) { + $layout_classnames .= ' has-corners-' . $border_radius; + } + + if ( $has_animations ) { + $layout_classnames .= ' has-animations'; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + $this->widget->add_render_attribute( 'layout', [ + 'class' => $layout_classnames, + 'id' => $this->settings['advanced_custom_css_id'], + ] ); + } + + public function render(): void { + $this->build_layout_render_attribute(); + $this->add_content_wrapper_render_attribute(); + + $content_classnames = 'e-contact-buttons__content'; + + $this->widget->add_render_attribute( 'content', [ + 'class' => $content_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content-wrapper' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_top_bar(); + ?> + +
      +
      + render_chat_button(); + ?> +
      + settings['chat_button_icon'] ?? ''; + + Icons_Manager::render_icon( $custom_icon ); + } + + protected function build_layout_render_attribute(): void { + $layout_classnames = 'e-contact-buttons e-' . $this->widget->get_name(); + $has_animations = ! empty( $this->settings['style_chat_box_exit_animation'] ) || ! empty( $this->settings['style_chat_box_entrance_animation'] ); + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + + if ( $has_animations ) { + $layout_classnames .= ' has-animations'; + } + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function render_close_button(): void { + $button_size = $this->settings['style_chat_button_size']; + $button_classnames = 'e-contact-buttons__close-button e-contact-buttons__chat-button-shadow'; + $accessible_name = $this->settings['chat_aria_label']; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + $this->widget->add_render_attribute( 'close-button', [ + 'class' => $button_classnames, + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Close %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'type' => 'button', + 'aria-expanded' => 'false', + ] ); + + ?> + + settings['chat_button_platform'] ?? ''; + $button_size = $this->settings['style_chat_button_size']; + $hover_animation = $this->settings['style_button_color_hover_animation']; + $entrance_animation = $this->settings['style_chat_button_animation']; + $entrance_animation_duration = $this->settings['style_chat_button_animation_duration']; + $entrance_animation_delay = $this->settings['style_chat_button_animation_delay']; + $accessible_name = $this->settings['chat_aria_label']; + + $button_classnames = 'e-contact-buttons__chat-button e-contact-buttons__chat-button-shadow'; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + if ( ! empty( $entrance_animation ) && 'none' != $entrance_animation ) { + $button_classnames .= ' has-entrance-animation'; + } + + if ( ! empty( $entrance_animation_delay ) ) { + $button_classnames .= ' has-entrance-animation-delay'; + } + + if ( ! empty( $entrance_animation_duration ) ) { + $button_classnames .= ' has-entrance-animation-duration-' . $entrance_animation_duration; + } + + $this->widget->add_render_attribute( 'button-', [ + 'class' => $button_classnames, + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Expand %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'type' => 'button', + 'aria-expanded' => 'true', + ] ); + + ?> +
      + + render_close_button(); + ?> +
      + settings['contact_repeater'] ?? []; + $button_size = $this->settings['style_chat_button_size']; + + ?> +
      + +
      + build_layout_render_attribute(); + $this->add_content_wrapper_render_attribute(); + + $content_classnames = 'e-contact-buttons__content'; + $animation_duration = $this->settings['style_chat_box_animation_duration']; + + if ( ! empty( $animation_duration ) ) { + $content_classnames .= ' has-animation-duration-' . $animation_duration; + } + + $this->widget->add_render_attribute( 'content', [ + 'class' => $content_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content-wrapper' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_contact_section(); + ?> +
      +
      + render_chat_button(); + ?> +
      + widget->get_name(); + $platform = $this->settings['chat_button_platform'] ?? ''; + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + $has_animations = ! empty( $this->settings['style_chat_box_exit_animation'] ) || ! empty( $this->settings['style_chat_box_entrance_animation'] ); + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + $icon_name_mapping = Social_Network_Provider::get_name_mapping( $platform ); + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $has_animations ) { + $layout_classnames .= ' has-animations'; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + if ( ! empty( $platform ) ) { + $layout_classnames .= ' has-platform-' . $icon_name_mapping; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function render_chat_button(): void { + $platform = $this->settings['chat_button_platform'] ?? ''; + $display_dot = $this->settings['chat_button_show_dot'] ?? ''; + $button_size = $this->settings['style_chat_button_size']; + $hover_animation = $this->settings['style_button_color_hover_animation']; + $accessible_name = $this->settings['chat_aria_label']; + $icon_text_mapping = Social_Network_Provider::get_text_mapping( $platform ); + $aria_label = sprintf( + /* translators: 1: Accessible name, 2: Platform name */ + esc_attr__( 'Open %1$s %2$s', 'elementor-pro' ), + $accessible_name, + $icon_text_mapping + ); + + $button_classnames = 'e-contact-buttons__chat-button e-contact-buttons__chat-button-shadow'; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + if ( 'yes' === $display_dot ) { + $button_classnames .= ' has-dot'; + } + + $link = [ + 'platform' => $platform, + 'number' => $this->settings['chat_button_number'] ?? '', + 'username' => $this->settings['chat_button_username'] ?? '', + 'email_data' => [ + 'chat_button_mail' => $this->settings['chat_button_mail'] ?? '', + 'chat_button_mail_subject' => $this->settings['chat_button_mail_subject'] ?? '', + 'chat_button_mail_body' => $this->settings['chat_button_mail_body'] ?? '', + ], + 'viber_action' => $this->settings['chat_button_viber_action'] ?? '', + 'location' => $this->settings['chat_button_waze'] ?? '', + ]; + + if ( $this->is_url_link( $platform ) ) { + $this->render_link_attributes( $link, 'formatted-cta' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + 'aria-label' => $aria_label, + ] ); + } else { + $formatted_link = $this->get_formatted_link( $link, 'chat_button' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + 'href' => $formatted_link, + 'rel' => 'noopener noreferrer', + 'target' => '_blank', + 'aria-label' => $aria_label, + ] ); + } + + ?> + + build_layout_render_attribute(); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_chat_button(); + ?> +
      + widget->get_name(); + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function render_contact_links(): void { + $contact_icons = $this->settings['contact_repeater'] ?? []; + $icons_size = $this->settings['style_contact_button_size'] ?? 'small'; + $hover_animation = $this->settings['style_contact_button_hover_animation']; + $border_radius = $this->settings['style_contact_button_bar_corners']; + $accessible_name = $this->settings['contact_aria_label']; + + $links_classnames = 'e-contact-buttons__contact-links'; + + if ( ! empty( $border_radius ) ) { + $links_classnames .= ' has-corners-' . $border_radius; + } + + $this->widget->add_render_attribute( 'contact-links', [ + 'class' => $links_classnames, + ] ); + + ?> +
      widget->get_render_attribute_string( 'contact-links' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + $icon ) { + $icon_text_mapping = Social_Network_Provider::get_text_mapping( $icon['contact_icon_platform'] ); + $aria_label = sprintf( + /* translators: 1: Accessible name, 2: Platform name */ + esc_attr__( 'Access %1$s %2$s', 'elementor-pro' ), + $accessible_name, + $icon_text_mapping + ); + + $link = [ + 'platform' => $icon['contact_icon_platform'], + 'number' => $icon['contact_icon_number'] ?? '', + 'username' => $icon['contact_icon_username'] ?? '', + 'email_data' => [ + 'contact_icon_mail' => $icon['contact_icon_mail'] ?? '', + 'contact_icon_mail_subject' => $icon['contact_icon_mail_subject'] ?? '', + 'contact_icon_mail_body' => $icon['contact_icon_mail_body'] ?? '', + ], + 'viber_action' => $icon['contact_icon_viber_action'] ?? '', + 'location' => $icon['contact_icon_waze'] ?? '', + ]; + + $icon_classnames = 'e-contact-buttons__contact-icon-link has-size-' . $icons_size; + + if ( ! empty( $hover_animation ) ) { + $icon_classnames .= ' elementor-animation-' . $hover_animation; + } + + if ( $this->is_url_link( $icon['contact_icon_platform'] ) ) { + $this->render_link_attributes( $link, 'icon-link-' . $key ); + + $this->widget->add_render_attribute( 'icon-link-' . $key, [ + 'class' => $icon_classnames, + 'aria-label' => $aria_label, + ] ); + } else { + $formatted_link = $this->get_formatted_link( $link, 'contact_icon' ); + + $this->widget->add_render_attribute( 'icon-link-' . $key, [ + 'class' => $icon_classnames, + 'href' => $formatted_link, + 'rel' => 'noopener noreferrer', + 'target' => '_blank', + 'aria-label' => $aria_label, + ] ); + } + + ?> + + widget->get_render_attribute_string( 'icon-link-' . $key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + $library, + 'value' => $mapping, + ], + [ 'aria-hidden' => 'true' ] + ); + ?> + + +
      + build_layout_render_attribute(); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_contact_links(); + ?> +
      + widget->get_name(); + $platform = $this->settings['chat_button_platform'] ?? ''; + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + $icon_name_mapping = Social_Network_Provider::get_name_mapping( $platform ); + $mobile_full_width = $this->settings['advanced_mobile_full_width']; + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( ! empty( $mobile_full_width ) ) { + $layout_classnames .= ' has-mobile-full-width'; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + if ( ! empty( $platform ) ) { + $layout_classnames .= ' has-platform-' . $icon_name_mapping; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function get_platform_text(): string { + $platform = $this->settings['chat_button_platform']; + + switch ( $platform ) { + case Social_Network_Provider::EMAIL: + $platform_text = $this->settings['chat_button_mail']; + break; + case Social_Network_Provider::SMS: + $platform_text = $this->settings['chat_button_number']; + break; + case Social_Network_Provider::MESSENGER: + $platform_text = $this->settings['chat_button_username']; + break; + case Social_Network_Provider::WHATSAPP: + $platform_text = $this->settings['chat_button_number']; + break; + case Social_Network_Provider::VIBER: + $platform_text = $this->settings['chat_button_number']; + break; + case Social_Network_Provider::SKYPE: + $platform_text = $this->settings['chat_button_username']; + break; + case Social_Network_Provider::WAZE: + $platform_text = $this->settings['chat_button_waze']['url']; + break; + case Social_Network_Provider::URL: + $platform_text = $this->settings['chat_button_url']['url']; + break; + case Social_Network_Provider::TELEPHONE: + $platform_text = $this->settings['chat_button_number']; + break; + default: + break; + } + + return $platform_text; + } + + protected function get_chat_button_text(): string { + if ( 'cta' == $this->settings['chat_button_display_text_select'] ) { + $button_text = $this->settings['chat_button_display_text']; + } else { + $button_text = $this->get_platform_text(); + } + + return $button_text; + } + + protected function get_aria_label(): string { + $platform = $this->settings['chat_button_platform'] ?? ''; + $icon_text_mapping = Social_Network_Provider::get_text_mapping( $platform ); + $accessible_name = $this->settings['chat_aria_label']; + + if ( 'cta' == $this->settings['chat_button_display_text_select'] ) { + return $this->settings['chat_button_display_text']; + } else { + return sprintf( + /* translators: 1: Accessible name, 2: Platform name */ + esc_attr__( 'Open %1$s %2$s', 'elementor-pro' ), + $accessible_name, + $icon_text_mapping + ); + } + } + + protected function render_chat_button(): void { + $platform = $this->settings['chat_button_platform'] ?? ''; + $hover_animation = $this->settings['style_button_color_hover_animation']; + $chat_button_text = $this->get_chat_button_text(); + $aria_label = $this->get_aria_label(); + + $button_classnames = 'e-contact-buttons__chat-button'; + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + $link = [ + 'platform' => $platform, + 'number' => $this->settings['chat_button_number'] ?? '', + 'username' => $this->settings['chat_button_username'] ?? '', + 'email_data' => [ + 'chat_button_mail' => $this->settings['chat_button_mail'] ?? '', + 'chat_button_mail_subject' => $this->settings['chat_button_mail_subject'] ?? '', + 'chat_button_mail_body' => $this->settings['chat_button_mail_body'] ?? '', + ], + 'viber_action' => $this->settings['chat_button_viber_action'] ?? '', + 'location' => $this->settings['chat_button_waze'] ?? '', + 'url' => $this->settings['chat_button_url'] ?? '', + ]; + + if ( $this->is_url_link( $platform ) ) { + $this->render_link_attributes( $link, 'formatted-cta' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + 'aria-label' => $aria_label, + ] ); + } else { + $formatted_link = $this->get_formatted_link( $link, 'chat_button' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + 'href' => $formatted_link, + 'rel' => 'noopener noreferrer', + 'target' => '_blank', + 'aria-label' => $aria_label, + ] ); + } + + ?> + + build_layout_render_attribute(); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_chat_button(); + ?> +
      + settings['chat_button_icon'] ?? ''; + + Icons_Manager::render_icon( $custom_icon ); + } + + protected function render_close_button(): void { + $button_size = $this->settings['style_chat_button_size']; + $button_classnames = 'e-contact-buttons__close-button e-contact-buttons__chat-button-shadow'; + $accessible_name = $this->settings['chat_aria_label']; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + $this->widget->add_render_attribute( 'close-button', [ + 'class' => $button_classnames, + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Close %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'type' => 'button', + 'aria-expanded' => 'false', + ] ); + + ?> + + settings['chat_button_platform'] ?? ''; + $button_size = $this->settings['style_chat_button_size']; + $hover_animation = $this->settings['style_button_color_hover_animation']; + $entrance_animation = $this->settings['style_chat_button_animation']; + $entrance_animation_duration = $this->settings['style_chat_button_animation_duration']; + $entrance_animation_delay = $this->settings['style_chat_button_animation_delay']; + $accessible_name = $this->settings['chat_aria_label']; + + $button_classnames = 'e-contact-buttons__chat-button e-contact-buttons__chat-button-shadow'; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + if ( ! empty( $hover_animation ) ) { + $button_classnames .= ' elementor-animation-' . $hover_animation; + } + + if ( ! empty( $entrance_animation ) && 'none' != $entrance_animation ) { + $button_classnames .= ' has-entrance-animation'; + } + + if ( ! empty( $entrance_animation_delay ) ) { + $button_classnames .= ' has-entrance-animation-delay'; + } + + if ( ! empty( $entrance_animation_duration ) ) { + $button_classnames .= ' has-entrance-animation-duration-' . $entrance_animation_duration; + } + + $this->widget->add_render_attribute( 'button-', [ + 'class' => $button_classnames, + 'aria-controls' => 'e-contact-buttons__content-wrapper', + 'aria-label' => sprintf( + /* translators: 1: Accessible name */ + esc_attr__( 'Open %1$s', 'elementor-pro' ), + $accessible_name, + ), + 'type' => 'button', + 'aria-expanded' => 'true', + ] ); + + ?> +
      + + render_close_button(); + ?> +
      + widget->get_name(); + $has_animations = ! empty( $this->settings['style_chat_box_exit_animation'] ) || ! empty( $this->settings['style_chat_box_entrance_animation'] ); + $border_radius = $this->settings['style_chat_box_corners']; + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + + if ( ! empty( $border_radius ) ) { + $layout_classnames .= ' has-corners-' . $border_radius; + } + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $has_animations ) { + $layout_classnames .= ' has-animations'; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + protected function render_top_bar(): void { + $top_bar_title = $this->settings['top_bar_title'] ?? ''; + $top_bar_subtitle = $this->settings['top_bar_subtitle'] ?? ''; + + $has_top_bar_title = ! empty( $top_bar_title ); + $has_top_bar_subtitle = ! empty( $top_bar_subtitle ); + ?> +
      +
      + +

      + + +

      + +
      +
      + settings['contact_repeater'] ?? []; + $button_size = $this->settings['style_resource_links_button_size']; + $hover_animation = $this->settings['style_resource_links_hover_animation']; + + ?> + + build_layout_render_attribute(); + $this->add_content_wrapper_render_attribute(); + + $content_classnames = 'e-contact-buttons__content'; + + $this->widget->add_render_attribute( 'content', [ + 'class' => $content_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content-wrapper' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      widget->get_render_attribute_string( 'content' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_top_bar(); + $this->render_contact_section(); + ?> +
      +
      + render_chat_button(); + ?> +
      + settings['chat_button_platform'] ?? ''; + $button_size = $this->settings['style_chat_button_size']; + $chat_button_text = $this->settings['chat_button_display_text']; + + $button_classnames = 'e-contact-buttons__chat-button e-contact-buttons__chat-button-drop-shadow'; + + if ( ! empty( $button_size ) ) { + $button_classnames .= ' has-size-' . $button_size; + } + + $link = [ + 'platform' => $platform, + 'number' => $this->settings['chat_button_number'] ?? '', + 'username' => $this->settings['chat_button_username'] ?? '', + 'email_data' => [ + 'chat_button_mail' => $this->settings['chat_button_mail'] ?? '', + 'chat_button_mail_subject' => $this->settings['chat_button_mail_subject'] ?? '', + 'chat_button_mail_body' => $this->settings['chat_button_mail_body'] ?? '', + ], + 'viber_action' => $this->settings['chat_button_viber_action'] ?? '', + 'location' => $this->settings['chat_button_waze'] ?? '', + 'url' => $this->settings['chat_button_url'] ?? '', + ]; + + if ( $this->is_url_link( $platform ) ) { + $this->render_link_attributes( $link, 'formatted-cta' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + ] ); + } else { + $formatted_link = $this->get_formatted_link( $link, 'chat_button' ); + + $this->widget->add_render_attribute( 'formatted-cta', [ + 'class' => $button_classnames, + 'href' => $formatted_link, + 'rel' => 'noopener noreferrer', + 'target' => '_blank', + ] ); + } + + ?> + + widget->get_name(); + $platform = $this->settings['chat_button_platform'] ?? ''; + $alignment_position_horizontal = $this->settings['advanced_horizontal_position']; + $alignment_position_vertical = $this->settings['advanced_vertical_position']; + $has_animations = ! empty( $this->settings['style_chat_box_exit_animation'] ) || ! empty( $this->settings['style_chat_box_entrance_animation'] ); + $custom_classes = $this->settings['advanced_custom_css_classes'] ?? ''; + $icon_name_mapping = Social_Network_Provider::get_name_mapping( $platform ); + + if ( ! empty( $alignment_position_horizontal ) ) { + $layout_classnames .= ' has-h-alignment-' . $alignment_position_horizontal; + } + + if ( ! empty( $alignment_position_vertical ) ) { + $layout_classnames .= ' has-v-alignment-' . $alignment_position_vertical; + } + + if ( $has_animations ) { + $layout_classnames .= ' has-animations'; + } + + if ( $custom_classes ) { + $layout_classnames .= ' ' . $custom_classes; + } + + if ( ! empty( $platform ) ) { + $layout_classnames .= ' has-platform-' . $icon_name_mapping; + } + + $this->add_layout_render_attribute( $layout_classnames ); + } + + public function render(): void { + $this->build_layout_render_attribute(); + + $content_classnames = 'e-contact-buttons__content'; + + $this->widget->add_render_attribute( 'content', [ + 'class' => $content_classnames, + ] ); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_chat_button(); + ?> +
      + settings['headlines_repeater'] ?? []; + $has_pause_hover = $this->settings['style_ticker_pause_hover']; + + $headlines_classnames = 'e-floating-bars__headlines'; + + if ( 'yes' == $has_pause_hover ) { + $headlines_classnames .= ' has-pause-hover'; + } + + $this->widget->add_render_attribute( 'headlines', [ + 'class' => $headlines_classnames, + ] ); + + ?> +
      widget->get_render_attribute_string( 'headlines' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> +
      + $headline ) { + $link = $headline['headlines_url']; + $text = $headline['headlines_text']; + $icon = $headline['headlines_icon']; + + $headline_classnames = 'e-floating-bars__headline'; + + $this->widget->add_render_attribute( 'headline-' . $key, [ + 'class' => $headline_classnames, + ] ); + + $this->widget->add_link_attributes( 'headline-' . $key, $link ); + ?> + + + widget->get_render_attribute_string( 'headline-' . $key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + + 'true' ] ); ?> + + + + + +
      +
      +
      + settings['floating_bar_pause_icon']; + $play_icon = $this->settings['floating_bar_play_icon']; + $accessible_name = $this->settings['accessible_name']; + + $this->widget->add_render_attribute( 'pause-button', [ + 'class' => 'e-floating-bars__pause-button', + 'aria-label' => sprintf( + /* translators: 1: Accessible name. */ + esc_attr__( 'Pause %1$s', 'elementor-pro' ), + $accessible_name, + ), + ] ); + + $this->widget->add_render_attribute( 'play-button', [ + 'class' => 'e-floating-bars__play-button', + 'aria-label' => sprintf( + /* translators: 1: Accessible name. */ + esc_attr__( 'Play %1$s', 'elementor-pro' ), + $accessible_name, + ), + ] ); + ?> +
      + + +
      + build_layout_render_attribute(); + $has_close_button = $this->settings['floating_bar_close_switch']; + $has_pause_play_buttons = $this->settings['floating_bar_pause_switch']; + + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_headlines(); + + if ( 'yes' == $has_pause_play_buttons || 'yes' == $has_close_button ) { + ?> +
      + render_pause_play_buttons(); + } + if ( 'yes' == $has_close_button ) { + $this->render_close_button(); + } + ?> + +
      + +
      + settings['style_coupon_type']; + + if ( 'price-tag' === $style_type ) { + ?> + + + + + + + + + + settings['coupon_code'] ?? ''; + $success_message = $this->settings['coupon_success_message'] ?? ''; + $accessible_name = $this->settings['accessible_name']; + $copy_icon = $this->settings['coupon_copy_icon'] ?? ''; + $success_icon = $this->settings['coupon_success_icon'] ?? ''; + $entrance_animation = $this->settings['style_coupon_animation']; + $style_type = $this->settings['style_coupon_type']; + $has_border = $this->settings['style_coupon_show_border']; + + $coupon_classnames = 'e-floating-bars__coupon-button'; + + if ( ! empty( $entrance_animation ) && 'none' !== $entrance_animation ) { + $coupon_classnames .= ' has-entrance-animation'; + } + + if ( ! empty( $style_type ) ) { + $coupon_classnames .= ' is-type-' . $style_type; + } + + if ( 'yes' == $has_border ) { + $coupon_classnames .= ' has-border'; + } + + $this->widget->add_render_attribute( 'coupon-button', [ + 'class' => $coupon_classnames, + 'type' => 'button', + 'aria-label' => sprintf( + /* translators: 1: Accessible name. */ + esc_attr__( 'Copy %1$s coupon code', 'elementor-pro' ), + $accessible_name, + ), + ] ); + + if ( '' !== $text ) { + ?> + + build_layout_render_attribute(); + $has_close_button = $this->settings['floating_bar_close_switch']; + + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + render_announcement_text(); + + $this->render_announcement_icon(); + + $this->render_coupon_button(); + + if ( 'yes' == $has_close_button ) { + $this->render_close_button(); + } + ?> +
      +
      + $this->get_main_id(), + 'action' => 'elementor', + 'floating_element' => get_post_meta( + $this->get_main_id(), + static::FLOATING_ELEMENTS_TYPE_META_KEY, + true + ), + ], + admin_url( 'post.php' ) + ); + } + + public function print_content() { + $plugin = \Elementor\Plugin::$instance; + + if ( $plugin->preview->is_preview_mode( $this->get_main_id() ) ) { + // PHPCS - the method builder_wrapper is safe. + echo $plugin->preview->builder_wrapper( '' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + // PHPCS - the method get_content is safe. + echo $this->get_content(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + public function get_location() { + return self::get_property( 'location' ); + } + + public static function get_type() { + return Floating_Buttons_Module::FLOATING_BUTTONS_DOCUMENT_TYPE; + } + + public static function register_post_fields_control( $document ) {} + + public static function register_hide_title_control( $document ) {} + + public static function get_preview_as_default() { + return ''; + } + + public static function get_preview_as_options() { + return array_merge( + [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ], + Archive::get_preview_as_options(), + Single::get_preview_as_options() + ); + } + + public function get_name() { + return Floating_Buttons_Module::FLOATING_BUTTONS_DOCUMENT_TYPE; + } + + public function filter_admin_row_actions( $actions ) { + unset( $actions['edit'] ); + unset( $actions['inline hide-if-no-js'] ); + $built_with_elementor = $this->add_built_with_elementor( [] ); + + if ( isset( $actions['trash'] ) ) { + $delete = $actions['trash']; + unset( $actions['trash'] ); + $actions['trash'] = $delete; + } + + return $built_with_elementor + $actions; + } + + public function add_built_with_elementor( $actions ) { + if ( $this->is_built_with_elementor() && $this->is_editable_by_current_user() ) { + $edit_url = $this->get_edit_url(); + + if ( ! $this->get_post()->post_content ) { + $edit_url .= '#library'; + } + + $actions['edit_with_elementor'] = sprintf( + '%2$s', + $edit_url, + esc_html__( 'Edit with Elementor', 'elementor-pro' ) + ); + } + + return $actions; + } + + public static function get_title() { + return esc_html__( 'Floating Element', 'elementor-pro' ); + } + + public static function get_plural_title() { + return esc_html__( 'Floating Elements', 'elementor-pro' ); + } + + public static function get_create_url() { + return parent::get_create_url(); + } + + public function save( $data ) { + if ( empty( $data['settings']['template'] ) ) { + $data['settings']['template'] = Page_Templates_Module::TEMPLATE_CANVAS; + } + + return parent::save( $data ); + } + + protected function register_controls() { + parent::register_controls(); + + $latest_posts = get_posts( [ + 'posts_per_page' => 1, + 'post_type' => 'page', + ] ); + + if ( ! empty( $latest_posts ) ) { + $this->update_control( + 'preview_type', + [ + 'default' => 'single/page', + ] + ); + + $this->update_control( + 'preview_id', + [ + 'default' => $latest_posts[0]->ID, + ] + ); + } + } + + public function admin_columns_content( $column_name ) { + if ( 'elementor_library_type' === $column_name ) { + $admin_filter_url = admin_url( Source_Local::ADMIN_MENU_SLUG . '&elementor_library_type=' . $this->get_name() ); + $meta = static::get_floating_element_type( $this->get_main_id() ); + printf( '%s', $admin_filter_url, Floating_Buttons_Module::get_floating_elements_types()[ $meta ] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + protected function get_remote_library_config() { + $config = [ + 'type' => 'floating_button', + 'default_route' => 'templates/floating-buttons', + 'autoImportSettings' => true, + ]; + + return array_replace_recursive( parent::get_remote_library_config(), $config ); + } +} diff --git a/modules/floating-buttons/module.php b/modules/floating-buttons/module.php new file mode 100644 index 00000000..7bc473d8 --- /dev/null +++ b/modules/floating-buttons/module.php @@ -0,0 +1,109 @@ +experiments->is_feature_active( 'container' ); + } + + public function get_name(): string { + return static::EXPERIMENT_NAME; + } + + public function get_widgets(): array { + $floating_buttons = [ + 'Contact_Buttons_Var_1', + 'Contact_Buttons_Var_3', + 'Contact_Buttons_Var_4', + 'Contact_Buttons_Var_5', + 'Contact_Buttons_Var_6', + 'Contact_Buttons_Var_7', + 'Contact_Buttons_Var_8', + 'Contact_Buttons_Var_9', + 'Contact_Buttons_Var_10', + ]; + + $floating_bars = [ + 'Floating_Bars_Var_2', + 'Floating_Bars_Var_3', + ]; + + return class_exists( 'Elementor\Modules\FloatingButtons\Base\Widget_Floating_Bars_Base' ) ? array_merge( $floating_buttons, $floating_bars ) : $floating_buttons; + } + + public static function get_floating_elements_types() { + return [ + 'floating-buttons' => esc_html__( 'Floating Buttons', 'elementor-pro' ), + 'floating-bars' => esc_html__( 'Floating Bars', 'elementor-pro' ), + ]; + } + + public function is_preview_for_document( $post_id ) { + $preview_id = ElementorUtils::get_super_global_value( $_GET, 'preview_id' ); + $preview = ElementorUtils::get_super_global_value( $_GET, 'preview' ); + + return 'true' === $preview && (int) $post_id === (int) $preview_id; + } + + public function __construct() { + parent::__construct(); + + add_action( 'elementor/theme/register_locations', [ $this, 'register_location' ] ); + add_action( 'wp_footer', [ $this, 'print_floating_buttons' ] ); + + if ( API::is_license_active() ) { + add_action( 'elementor/documents/register', function ( Documents_Manager $documents_manager ) { + $documents_manager->register_document_type( + self::FLOATING_BUTTONS_DOCUMENT_TYPE, + Floating_Buttons::class + ); + }, 11 ); + } + + add_action( 'elementor/theme/before_do_floating_buttons', function ( Locations_Manager $locations_manager ) { + $documents = $locations_manager->get_documents_for_location( 'floating_buttons' ); + foreach ( $documents as $post_id ) { + if ( $this->is_preview_for_document( $post_id ) || get_the_ID() === $post_id ) { + $locations_manager->skip_doc_in_location( 'floating_buttons', $post_id ); + } + } + } ); + } + + public function print_floating_buttons() { + elementor_theme_do_location( 'floating_buttons' ); + } + + public function register_location( Locations_Manager $location_manager ) { + $location_manager->register_location( + 'floating_buttons', + [ + 'label' => esc_html__( 'Floating Buttons', 'elementor-pro' ), + 'multiple' => true, + 'public' => false, + 'edit_in_content' => true, + ] + ); + } +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-1.php b/modules/floating-buttons/widgets/contact-buttons-var-1.php new file mode 100644 index 00000000..7d837a64 --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-1.php @@ -0,0 +1,64 @@ +add_chat_button_section(); + + $this->add_top_bar_section(); + + $this->add_message_bubble_section(); + + $this->add_contact_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + + $this->add_style_top_bar_section(); + + $this->add_style_message_bubble_section(); + + $this->add_style_contact_section(); + + $this->add_style_chat_box_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_1_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-10.php b/modules/floating-buttons/widgets/contact-buttons-var-10.php new file mode 100644 index 00000000..ca394802 --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-10.php @@ -0,0 +1,72 @@ +add_contact_section(); + } + + protected function add_style_tab(): void { + $this->add_style_contact_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_10_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-3.php b/modules/floating-buttons/widgets/contact-buttons-var-3.php new file mode 100644 index 00000000..98d61297 --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-3.php @@ -0,0 +1,133 @@ + 'fas fa-info', + 'library' => 'fa-solid', + ]; + $config['content']['chat_button_section']['icons_recommended'] = [ + 'fa-solid' => [ + 'info', + 'info-circle', + 'question', + 'question-circle', + ], + ]; + $config['content']['top_bar_section']['section_name'] = esc_html__( 'Heading', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['label'] = esc_html__( 'Greeting', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['placeholder'] = esc_html__( 'Enter your text here', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['dynamic'] = true; + $config['content']['top_bar_section']['title']['ai'] = true; + $config['content']['top_bar_section']['title']['label_block'] = true; + $config['content']['top_bar_section']['title']['default'] = esc_html__( 'Need help?', 'elementor-pro' ); + $config['content']['top_bar_section']['has_image'] = false; + $config['content']['top_bar_section']['has_active_dot'] = false; + $config['content']['top_bar_section']['has_subtitle'] = false; + $config['style']['top_bar_section']['has_title_heading'] = false; + $config['style']['top_bar_section']['has_close_button_heading'] = false; + $config['style']['top_bar_section']['has_background'] = false; + + $config['content']['contact_section']['section_name'] = esc_html__( 'Info Links', 'elementor-pro' ); + $config['content']['contact_section']['has_cta_text'] = false; + $config['content']['contact_section']['platform']['limit'] = null; + $config['content']['contact_section']['repeater']['has_tooltip'] = true; + $config['content']['contact_section']['repeater']['tooltip_default'] = esc_html__( 'Sample Link Text', 'elementor-pro' ); + $config['content']['contact_section']['repeater']['tooltip_placeholder'] = esc_html__( 'Enter your text here', 'elementor-pro' ); + $config['content']['contact_section']['platform']['group-1'] = [ + Social_Network_Provider::EMAIL, + Social_Network_Provider::TELEPHONE, + Social_Network_Provider::SMS, + Social_Network_Provider::WHATSAPP, + Social_Network_Provider::SKYPE, + Social_Network_Provider::MESSENGER, + Social_Network_Provider::VIBER, + Social_Network_Provider::WAZE, + Social_Network_Provider::URL, + ]; + $config['content']['contact_section']['default'] = [ + [ + 'contact_icon_platform' => Social_Network_Provider::TELEPHONE, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::MESSENGER, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::URL, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::WAZE, + ], + ]; + $config['content']['contact_section']['has_accessible_name'] = false; + + $config['style']['chat_box_section']['section_name'] = esc_html__( 'Box', 'elementor-pro' ); + $config['style']['chat_box_section']['has_width'] = false; + $config['style']['chat_box_section']['has_padding'] = true; + + $config['content']['send_button_section']['section_name'] = esc_html__( 'CTA Button', 'elementor-pro' ); + $config['content']['send_button_section']['text']['default'] = esc_html__( 'Shop Now', 'elementor-pro' ); + $config['content']['send_button_section']['has_link'] = true; + $config['style']['send_button_section']['has_platform_colors'] = false; + $config['style']['send_button_section']['has_icon_color'] = false; + $config['style']['send_button_section']['has_background_color'] = true; + $config['style']['send_button_section']['has_text_color'] = true; + $config['style']['send_button_section']['typography_selector'] = '{{WRAPPER}} .e-contact-buttons__cta-button'; + + return $config; + } + + public function get_name(): string { + return 'contact-buttons-var-3'; + } + + public function get_title(): string { + return esc_html__( 'Info Button Box', 'elementor-pro' ); + } + + protected function add_content_tab(): void { + $this->add_chat_button_section(); + + $this->add_top_bar_section(); + + $this->add_contact_section(); + + $this->add_send_button_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + + $this->add_style_top_bar_section(); + + $this->add_style_info_links_section(); + + $this->add_style_send_button_section(); + + $this->add_style_chat_box_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_3_Render( $this ); + + $render_strategy->render(); + } +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-4.php b/modules/floating-buttons/widgets/contact-buttons-var-4.php new file mode 100644 index 00000000..0adb5ccf --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-4.php @@ -0,0 +1,96 @@ + 'fas fa-ellipsis-v', + 'library' => 'fa-solid', + ]; + $config['content']['chat_button_section']['has_notification_dot'] = false; + $config['content']['chat_button_section']['has_active_tab'] = true; + $config['content']['chat_button_section']['chat_aria_label'] = esc_html__( 'Links', 'elementor-pro' ); + $config['content']['contact_section']['platform']['group-1'] = [ + Social_Network_Provider::EMAIL, + Social_Network_Provider::TELEPHONE, + Social_Network_Provider::SMS, + Social_Network_Provider::WHATSAPP, + Social_Network_Provider::SKYPE, + Social_Network_Provider::MESSENGER, + Social_Network_Provider::VIBER, + Social_Network_Provider::WAZE, + Social_Network_Provider::URL, + ]; + $config['content']['contact_section']['default'] = [ + [ + 'contact_icon_platform' => Social_Network_Provider::WHATSAPP, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::MESSENGER, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::EMAIL, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::TELEPHONE, + ], + ]; + $config['content']['contact_section']['has_cta_text'] = false; + $config['content']['contact_section']['repeater']['has_tooltip'] = true; + $config['content']['contact_section']['repeater']['tooltip_label'] = esc_html__( 'Tooltip', 'elementor-pro' ); + $config['content']['contact_section']['platform']['limit'] = null; + $config['content']['contact_section']['has_accessible_name'] = false; + $config['style']['contact_section']['has_buttons_heading'] = false; + $config['style']['contact_section']['has_buttons_size'] = false; + $config['style']['contact_section']['has_box_shadow'] = true; + $config['style']['contact_section']['has_buttons_spacing'] = true; + $config['style']['contact_section']['has_hover_animation'] = false; + $config['style']['contact_section']['has_chat_box_animation'] = true; + $config['style']['send_button_section']['has_typography'] = false; + + return $config; + } + + public function get_name(): string { + return 'contact-buttons-var-4'; + } + + public function get_title(): string { + return esc_html__( 'Vertical Links', 'elementor-pro' ); + } + + protected function add_content_tab(): void { + $this->add_chat_button_section(); + + $this->add_contact_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + + $this->add_style_contact_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_4_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-5.php b/modules/floating-buttons/widgets/contact-buttons-var-5.php new file mode 100644 index 00000000..43d5d8cb --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-5.php @@ -0,0 +1,57 @@ +add_chat_button_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_5_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-6.php b/modules/floating-buttons/widgets/contact-buttons-var-6.php new file mode 100644 index 00000000..659adc50 --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-6.php @@ -0,0 +1,78 @@ + Social_Network_Provider::TELEPHONE, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::EMAIL, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::WHATSAPP, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::WAZE, + ], + ]; + $config['style']['contact_section']['has_buttons_heading'] = true; + $config['style']['contact_section']['buttons_heading_label'] = esc_html__( 'Icons', 'elementor-pro' ); + $config['style']['contact_section']['has_icon_bg_color'] = false; + $config['style']['contact_section']['has_button_bar'] = true; + $config['advanced']['horizontal_position_default'] = 'center'; + $config['style']['send_button_section']['has_typography'] = false; + + return $config; + } + + public function get_name(): string { + return 'contact-buttons-var-6'; + } + + public function get_title(): string { + return esc_html__( 'Quick Access Bar', 'elementor-pro' ); + } + + protected function add_content_tab(): void { + $this->add_contact_section(); + } + + protected function add_style_tab(): void { + $this->add_style_contact_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_6_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-7.php b/modules/floating-buttons/widgets/contact-buttons-var-7.php new file mode 100644 index 00000000..fdf93d6c --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-7.php @@ -0,0 +1,67 @@ +add_chat_button_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_7_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-8.php b/modules/floating-buttons/widgets/contact-buttons-var-8.php new file mode 100644 index 00000000..dbe1480a --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-8.php @@ -0,0 +1,128 @@ + 'fas fa-life-ring', + 'library' => 'fa-solid', + ]; + $config['content']['chat_button_section']['icons_recommended'] = [ + 'fa-solid' => [ + 'life-ring', + 'info', + 'question', + ], + 'fa-regular' => [ + 'info', + 'question', + 'comment-alt', + ], + ]; + $config['content']['chat_button_section']['has_notification_dot'] = false; + $config['content']['chat_button_section']['has_active_tab'] = true; + + $config['content']['top_bar_section']['title']['label'] = esc_html__( 'Greeting', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['default'] = __( 'We\'re here for you', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['placeholder'] = esc_html__( 'Enter your text here', 'elementor-pro' ); + $config['content']['top_bar_section']['title']['dynamic'] = true; + $config['content']['top_bar_section']['title']['ai'] = true; + $config['content']['top_bar_section']['title']['label_block'] = true; + $config['content']['top_bar_section']['subtitle']['label'] = esc_html__( 'Call to Action', 'elementor-pro' ); + $config['content']['top_bar_section']['subtitle']['default'] = esc_html__( 'Explore our resources', 'elementor-pro' ); + $config['content']['top_bar_section']['subtitle']['placeholder'] = esc_html__( 'Enter your text here', 'elementor-pro' ); + $config['content']['top_bar_section']['subtitle']['dynamic'] = true; + $config['content']['top_bar_section']['subtitle']['ai'] = true; + $config['content']['top_bar_section']['subtitle']['label_block'] = true; + $config['content']['top_bar_section']['has_image'] = false; + $config['content']['top_bar_section']['has_active_dot'] = false; + $config['style']['top_bar_section']['title_heading_label'] = esc_html__( 'Greeting', 'elementor-pro' ); + $config['style']['top_bar_section']['subtitle_heading_label'] = esc_html__( 'Call to Action', 'elementor-pro' ); + $config['style']['top_bar_section']['has_style_close_button'] = false; + + $config['content']['contact_section']['platform']['limit'] = null; + $config['content']['contact_section']['section_name'] = esc_html__( 'Resource Links', 'elementor-pro' ); + $config['content']['contact_section']['platform']['group-1'] = [ + Social_Network_Provider::EMAIL, + Social_Network_Provider::TELEPHONE, + Social_Network_Provider::SMS, + Social_Network_Provider::WHATSAPP, + Social_Network_Provider::SKYPE, + Social_Network_Provider::MESSENGER, + Social_Network_Provider::VIBER, + Social_Network_Provider::WAZE, + Social_Network_Provider::URL, + ]; + $config['content']['contact_section']['default'] = [ + [ + 'contact_icon_platform' => Social_Network_Provider::WHATSAPP, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::MESSENGER, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::EMAIL, + ], + [ + 'contact_icon_platform' => Social_Network_Provider::TELEPHONE, + ], + ]; + $config['content']['contact_section']['has_cta_text'] = false; + $config['content']['contact_section']['repeater']['has_title'] = true; + $config['content']['contact_section']['repeater']['has_description'] = true; + + $config['style']['chat_box_section']['section_name'] = esc_html__( 'Box', 'elementor-pro' ); + $config['style']['send_button_section']['has_typography'] = false; + + return $config; + } + + public function get_name(): string { + return 'contact-buttons-var-8'; + } + + public function get_title(): string { + return esc_html__( 'Resource Box', 'elementor-pro' ); + } + + protected function add_content_tab(): void { + $this->add_chat_button_section(); + + $this->add_top_bar_section(); + + $this->add_contact_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + + $this->add_style_top_bar_section(); + + $this->add_style_resource_links_section(); + + $this->add_style_chat_box_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_8_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/contact-buttons-var-9.php b/modules/floating-buttons/widgets/contact-buttons-var-9.php new file mode 100644 index 00000000..d7a8365e --- /dev/null +++ b/modules/floating-buttons/widgets/contact-buttons-var-9.php @@ -0,0 +1,70 @@ +add_chat_button_section(); + } + + protected function add_style_tab(): void { + $this->add_style_chat_button_section(); + } + + public function render(): void { + $render_strategy = new Contact_Buttons_Var_9_Render( $this ); + + $render_strategy->render(); + } + +} diff --git a/modules/floating-buttons/widgets/floating-bars-var-2.php b/modules/floating-buttons/widgets/floating-bars-var-2.php new file mode 100644 index 00000000..ffa80316 --- /dev/null +++ b/modules/floating-buttons/widgets/floating-bars-var-2.php @@ -0,0 +1,308 @@ +start_controls_section( + 'style_floating_bar', + [ + 'label' => esc_html__( 'Floating Bar', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'style_floating_bar_horizontal_position', + [ + 'label' => esc_html__( 'Controls Horizontal position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'default' => 'end', + 'toggle' => true, + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-ticker-controls-order: {{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '-1', + 'end' => '2', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'floating_bar_close_switch', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'floating_bar_pause_switch', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'style_floating_bar_controls_size', + [ + 'label' => esc_html__( 'Controls Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 150, + ], + ], + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-controls-icon-size: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'after', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'floating_bar_close_switch', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'floating_bar_pause_switch', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $this->add_floating_bar_pause_style_controls(); + + $this->add_floating_bar_close_button_style_controls(); + + $this->add_responsive_control( + 'style_floating_bar_element_spacing', + [ + 'label' => esc_html__( 'Headline Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 50, + ], + ], + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-headlines-gap: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'style_floating_bar_padding', + [ + 'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 50, + ], + ], + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-vertical-padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_floating_bar_background_style_controls(); + + $this->end_controls_section(); + } + + protected function add_accessible_name_control(): void { + $this->add_control( + 'accessible_name', + [ + 'label' => esc_html__( 'Accessible Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Enter text', 'elementor-pro' ), + 'default' => esc_html__( 'Banner', 'elementor-pro' ), + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'floating_bar_close_switch', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'floating_bar_pause_switch', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ], + ); + } + + protected function add_ticker_content_section(): void { + $this->start_controls_section( + 'style_ticker', + [ + 'label' => esc_html__( 'Ticker', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_responsive_control( + 'style_ticker_animation_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'autoplay', + 'mobile_default' => 'autoplay', + 'options' => [ + 'autoplay' => esc_html__( 'Autoplay', 'elementor-pro' ), + 'scroll' => esc_html__( 'On page scroll', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'style_ticker_scroll_direction', + [ + 'label' => esc_html__( 'Scroll Direction', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'forwards', + 'mobile_default' => 'forwards', + 'toggle' => false, + 'options' => [ + 'forwards' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-arrow-left', + ], + 'reverse' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-arrow-right', + ], + ], + 'selectors_dictionary' => [ + 'forwards' => is_rtl() ? 'reverse' : 'forwards', + 'reverse' => is_rtl() ? 'forwards' : 'reverse', + ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-scroll-direction: {{VALUE}};', + ], + 'frontend_available' => true, + 'condition' => [ + 'style_ticker_animation_type' => 'autoplay', + ], + ] + ); + + $this->add_control( + 'style_ticker_scroll_speed', + [ + 'label' => esc_html__( 'Scroll speed', 'elementor-pro' ) . ' (s)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0.5, + 'max' => 100, + 'step' => 0.5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-scroll-duration: {{SIZE}}s;', + ], + 'condition' => [ + 'style_ticker_animation_type' => 'autoplay', + ], + ] + ); + + $this->add_control( + 'style_ticker_pause_hover', + [ + 'label' => esc_html__( 'Pause on Hover', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'condition' => [ + 'style_ticker_animation_type' => 'autoplay', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function add_content_tab(): void { + $this->add_headlines_content_section(); + $this->add_ticker_content_section(); + $this->add_floating_bar_content_section(); + } + + protected function add_style_tab(): void { + $this->add_headlines_style_section(); + $this->add_floating_bar_style_section(); + } + + public function render(): void { + $render_strategy = new Floating_Bars_Var_2_Render( $this ); + + $render_strategy->render(); + } +} diff --git a/modules/floating-buttons/widgets/floating-bars-var-3.php b/modules/floating-buttons/widgets/floating-bars-var-3.php new file mode 100644 index 00000000..73a3712a --- /dev/null +++ b/modules/floating-buttons/widgets/floating-bars-var-3.php @@ -0,0 +1,470 @@ + 'fas fa-star', + 'library' => 'fa-solid', + ]; + $config['content']['announcement_section']['text_label'] = esc_html__( 'Offer Text', 'elementor-pro' ); + $config['content']['announcement_section']['text_default'] = esc_html__( '10% off on your first order!', 'elementor-pro' ); + $config['content']['floating_bar_section']['accessible_name_default'] = esc_html__( 'Coupon Banner', 'elementor-pro' ); + $config['style']['floating_bar_section']['align_elements_selector'] = [ + '{{WRAPPER}} .e-floating-bars' => 'justify-content: {{VALUE}};', + '{{WRAPPER}} .e-floating-bars__coupon-button' => 'justify-self: {{VALUE}};', + '{{WRAPPER}} .e-floating-bars__announcement-text' => 'text-align: {{VALUE}};', + ]; + + return $config; + } + + public function get_name(): string { + return 'floating-bars-var-3'; + } + + public function get_title(): string { + return esc_html__( 'Coupon', 'elementor-pro' ); + } + + public function add_coupon_content_section(): void { + $this->start_controls_section( + 'coupon_content_section', + [ + 'label' => __( 'Coupon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'coupon_code', + [ + 'label' => esc_html__( 'Code', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'label_block' => false, + 'placeholder' => esc_html__( 'Enter coupon code', 'elementor-pro' ), + 'default' => esc_html__( 'NEW10', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'coupon_copy_icon', + [ + 'label' => esc_html__( 'Copy Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'default' => [ + 'value' => 'fas fa-copy', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-regular' => [ + 'clipboard', + 'copy', + ], + 'fa-solid' => [ + 'clipboard', + 'copy', + ], + ], + 'label_block' => false, + 'icon_exclude_inline_options' => [], + ] + ); + + $this->add_control( + 'coupon_success_message', + [ + 'label' => esc_html__( 'Success Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'label_block' => false, + 'placeholder' => esc_html__( 'Enter text', 'elementor-pro' ), + 'default' => esc_html__( 'Copied', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'coupon_success_icon', + [ + 'label' => esc_html__( 'Success Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'default' => [ + 'value' => 'fas fa-check', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-regular' => [ + 'check-circle', + 'check-square', + ], + 'fa-solid' => [ + 'check', + 'check-circle', + 'check-square', + ], + ], + 'label_block' => false, + 'icon_exclude_inline_options' => [], + ] + ); + + $this->end_controls_section(); + } + + public function add_coupon_style_section(): void { + $this->start_controls_section( + 'style_coupon', + [ + 'label' => esc_html__( 'Coupon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'style_coupon_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'cutout', + 'options' => [ + 'text' => esc_html__( 'Text', 'elementor-pro' ), + 'cutout' => esc_html__( 'Cutout', 'elementor-pro' ), + 'price-tag' => esc_html__( 'Price Tag', 'elementor-pro' ), + 'gift-tag' => esc_html__( 'Gift Tag', 'elementor-pro' ), + 'round-ticket' => esc_html__( 'Round Ticket', 'elementor-pro' ), + 'square-ticket' => esc_html__( 'Square Ticket', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'style_coupon_icon_position', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => is_rtl() ? 'row-reverse' : 'row', + 'toggle' => false, + 'options' => [ + 'row' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'row-reverse' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors_dictionary' => [ + 'row' => is_rtl() ? 'row-reverse' : 'row', + 'row-reverse' => is_rtl() ? 'row' : 'row-reverse', + ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars__coupon-text-group' => 'flex-direction: {{VALUE}};', + ], + 'condition' => [ + 'coupon_copy_icon[value]!' => '', + ], + ] + ); + + $this->add_control( + 'style_coupon_icon_spacing', + [ + 'label' => esc_html__( 'Icon Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-icon-gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'coupon_copy_icon[value]!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'style_coupon_typography', + 'selector' => '{{WRAPPER}} .e-floating-bars__coupon-button', + ] + ); + + $this->add_control( + 'style_coupon_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-button-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'style_coupon_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-bg-color: {{VALUE}}', + ], + 'condition' => [ + 'style_coupon_type!' => 'text', + ], + ] + ); + + $this->add_control( + 'style_coupon_show_border', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'condition' => [ + 'style_coupon_type!' => 'text', + ], + ] + ); + + $this->add_responsive_control( + 'style_coupon_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + '%' => [ + 'min' => 10, + 'max' => 100, + ], + 'px' => [ + 'min' => 0, + 'max' => 10, + ], + ], + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-border-width: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'style_coupon_show_border', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'style_coupon_type', + 'operator' => '!==', + 'value' => 'text', + ], + ], + ], + ] + ); + + $this->add_control( + 'style_coupon_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-border-color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'style_coupon_show_border', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'style_coupon_type', + 'operator' => '!==', + 'value' => 'text', + ], + ], + ], + ] + ); + + $this->add_control( + 'style_coupon_success_message_duration', + [ + 'label' => esc_html__( 'Success Message Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms' ], + 'default' => [ + 'unit' => 's', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'style_coupon_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem' ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-padding-block-end: {{BOTTOM}}{{UNIT}} !important; --e-floating-bars-coupon-padding-block-start: {{TOP}}{{UNIT}} !important; --e-floating-bars-coupon-padding-inline-end: {{RIGHT}}{{UNIT}} !important; --e-floating-bars-coupon-padding-inline-start: {{LEFT}}{{UNIT}} !important;', + ], + 'condition' => [ + 'style_coupon_type!' => [ + 'text', + 'price-tag', + 'gift-tag', + 'round-ticket', + 'square-ticket', + ], + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'style_coupon_animation', + [ + 'label' => esc_html__( 'Entrance Animation', 'elementor-pro' ), + 'type' => Controls_Manager::ANIMATION, + 'frontend_available' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'style_coupon_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '1000', + 'options' => [ + '2000' => esc_html__( 'Slow', 'elementor-pro' ), + '1000' => esc_html__( 'Normal', 'elementor-pro' ), + '800' => esc_html__( 'Fast', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-animation-duration: {{VALUE}}ms', + ], + 'prefix_class' => 'animated-', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'style_coupon_animation', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'style_coupon_animation', + 'operator' => '!==', + 'value' => 'none', + ], + ], + ], + ] + ); + + $this->add_control( + 'style_coupon_animation_delay', + [ + 'label' => esc_html__( 'Animation Delay', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'min' => 0, + 'step' => 100, + 'selectors' => [ + '{{WRAPPER}} .e-floating-bars' => '--e-floating-bars-coupon-animation-delay: {{SIZE}}ms;', + ], + 'render_type' => 'none', + 'frontend_available' => true, + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'style_coupon_animation', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'style_coupon_animation', + 'operator' => '!==', + 'value' => 'none', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + } + + protected function add_content_tab(): void { + $this->add_announcement_content_section(); + + $this->add_coupon_content_section(); + + $this->add_floating_bar_content_section(); + } + + protected function add_style_tab(): void { + $this->add_announcement_style_section(); + + $this->add_coupon_style_section(); + + $this->add_floating_bar_style_section(); + } + + public function render(): void { + $this->add_inline_editing_attributes( 'announcement_text', 'none' ); + + $render_strategy = new Floating_Bars_Var_3_Render( $this ); + + $render_strategy->render(); + } +} diff --git a/modules/forms/actions/activecampaign.php b/modules/forms/actions/activecampaign.php new file mode 100644 index 00000000..de5b2f14 --- /dev/null +++ b/modules/forms/actions/activecampaign.php @@ -0,0 +1,343 @@ +start_controls_section( + 'section_activecampaign', + [ + 'label' => esc_html__( 'ActiveCampaign', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'ActiveCampaign API credentials', + [ + 'activecampaign_api_credentials_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'activecampaign_api_credentials_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'activecampaign_api_key', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'condition' => [ + 'activecampaign_api_credentials_source' => 'custom', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'activecampaign_api_url', + [ + 'label' => esc_html__( 'API URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Use this field to set a custom API URL for the current form', 'elementor-pro' ), + 'condition' => [ + 'activecampaign_api_credentials_source' => 'custom', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'activecampaign_list', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'activecampaign_api_credentials_source', + 'operator' => '=', + 'value' => 'default', + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'activecampaign_api_url', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'activecampaign_api_key', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->add_control( + 'activecampaign_tags', + [ + 'label' => esc_html__( 'Tags', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Add as many tags as you want, comma separated.', 'elementor-pro' ), + 'condition' => [ + 'activecampaign_list!' => '', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['activecampaign_api_credentials_source'], + $element['settings']['activecampaign_api_key'], + $element['settings']['activecampaign_api_url'], + $element['settings']['activecampaign_list'], + $element['settings']['activecampaign_fields_map'], + $element['settings']['activecampaign_tags'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->create_subscriber_object( $record ); + + if ( ! $subscriber ) { + throw new \Exception( 'Integration requires an email field and a selected list.' ); + } + + if ( 'default' === $form_settings['activecampaign_api_credentials_source'] ) { + $api_key = $this->get_global_api_key(); + $api_url = $this->get_global_api_url(); + } else { + $api_key = $form_settings['activecampaign_api_key']; + $api_url = $form_settings['activecampaign_api_url']; + } + + $handler = new Classes\Activecampaign_Handler( $api_key, $api_url ); + $handler->create_subscriber( $subscriber ); + } + + /** + * Create subscriber array from submitted data and form settings + * returns a subscriber array or false on error + * + * @param Form_Record $record + * + * @return array|bool + */ + private function create_subscriber_object( Form_Record $record ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->map_fields( $record ); + + if ( ! isset( $subscriber['email'] ) ) { + return false; + } + + if ( ! isset( $form_settings['activecampaign_list'] ) ) { + return false; + } + + $subscriber['ip4'] = Utils::get_client_ip(); + $list_id = $form_settings['activecampaign_list']; + $subscriber[ 'p[' . $list_id . ']' ] = $list_id; + + if ( isset( $form_settings['activecampaign_tags'] ) && ! empty( $form_settings['activecampaign_tags'] ) ) { + $subscriber['tags'] = $form_settings['activecampaign_tags']; + } + + if ( isset( $form_settings['form_id'] ) && ! empty( $form_settings['form_id'] ) ) { + $subscriber['form'] = $form_settings['form_id']; + } + + return $subscriber; + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( Form_Record $record ) { + $subscriber = []; + $fields = $record->get( 'fields' ); + + // Other form has a field mapping + foreach ( $record->get_form_settings( 'activecampaign_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + $subscriber[ $map_item['remote_id'] ] = $value; + } + + return $subscriber; + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + if ( ! empty( $data['api_cred'] ) && 'default' === $data['api_cred'] ) { + $api_key = $this->get_global_api_key(); + $api_url = $this->get_global_api_url(); + } elseif ( ! empty( $data['api_key'] ) && ! empty( $data['api_url'] ) ) { + $api_key = $data['api_key']; + $api_url = $data['api_url']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_key` is required.', 400 ); + } + + if ( empty( $api_url ) ) { + throw new \Exception( '`api_url` is required.', 400 ); + } + + $handler = new Classes\Activecampaign_Handler( $api_key, $api_url ); + + return $handler->get_lists(); + } + + public function ajax_validate_api_token() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) || ! isset( $_POST['api_url'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Classes\Activecampaign_Handler( + Utils::_unstable_get_super_global_value( $_POST, 'api_key' ), + Utils::_unstable_get_super_global_value( $_POST, 'api_url' ) + ); + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'activecampign', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'ActiveCampaign', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + ], + ], + self::OPTION_NAME_API_URL => [ + 'label' => esc_html__( 'API URL', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'url', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_token' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'activecampaign_list!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/activity-log.php b/modules/forms/actions/activity-log.php new file mode 100644 index 00000000..5df730cd --- /dev/null +++ b/modules/forms/actions/activity-log.php @@ -0,0 +1,47 @@ + 'New Record', + 'object_type' => 'Elementor Forms', + 'object_id' => $record->get_form_settings( 'id' ), + 'object_name' => $record->get_form_settings( 'form_name' ), + ] + ); + } + + public function __construct() { + add_filter( 'aal_init_roles', [ $this, 'aal_init_roles' ] ); + } +} diff --git a/modules/forms/actions/cf7db.php b/modules/forms/actions/cf7db.php new file mode 100644 index 00000000..29d3a7ba --- /dev/null +++ b/modules/forms/actions/cf7db.php @@ -0,0 +1,33 @@ + $record->get_form_settings( 'form_name' ), + 'posted_data' => $record->get_formatted_data( true ), + ]; + + // Call hook to submit data + do_action_ref_array( 'cfdb_submit', [ $data ] ); + } +} diff --git a/modules/forms/actions/convertkit.php b/modules/forms/actions/convertkit.php new file mode 100644 index 00000000..176f0db2 --- /dev/null +++ b/modules/forms/actions/convertkit.php @@ -0,0 +1,286 @@ +start_controls_section( + 'section_convertkit', + [ + 'label' => esc_html__( 'ConvertKit', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'ConvertKit API key', + [ + 'convertkit_api_key_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'convertkit_api_key_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'convertkit_custom_api_key', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'condition' => [ + 'convertkit_api_key_source' => 'custom', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'convertkit_form', + [ + 'label' => esc_html__( 'Form', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'convertkit_custom_api_key', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'convertkit_api_key_source', + 'operator' => '=', + 'value' => 'default', + ], + ], + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->add_control( + 'convertkit_tags', + [ + 'label' => esc_html__( 'Tags', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => [], + 'multiple' => true, + 'render_type' => 'none', + 'label_block' => true, + 'condition' => [ + 'convertkit_form!' => '', + ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['convertkit_api_key_source'], + $element['settings']['convertkit_custom_api_key'], + $element['settings']['convertkit_form'], + $element['settings']['convertkit_fields_map'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->create_subscriber_object( $record ); + + if ( ! $subscriber ) { + throw new \Exception( 'Integration requires an email field.' ); + } + + if ( 'default' === $form_settings['convertkit_api_key_source'] ) { + $api_key = $this->get_global_api_key(); + } else { + $api_key = $form_settings['convertkit_custom_api_key']; + } + + if ( '' !== $form_settings['convertkit_tags'] ) { + $subscriber['tags'] = $form_settings['convertkit_tags']; + } + + $handler = new ConvertKit_Handler( $api_key ); + $handler->create_subscriber( $form_settings['convertkit_form'], $subscriber ); + } + + /** + * Create subscriber array from submitted data and form settings + * returns a subscriber array or false on error + * + * @param Form_Record $record + * + * @return array|bool + */ + private function create_subscriber_object( Form_Record $record ) { + $subscriber = $this->map_fields( $record ); + + if ( ! isset( $subscriber['email'] ) ) { + return false; + } + + $subscriber['ipAddress'] = Utils::get_client_ip(); + + return $subscriber; + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( Form_Record $record ) { + $subscriber = []; + $fields = $record->get( 'fields' ); + + // Other form has a field mapping + foreach ( $record->get_form_settings( 'convertkit_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + if ( in_array( $map_item['remote_id'], [ 'first_name', 'email' ] ) ) { + $subscriber[ $map_item['remote_id'] ] = $value; + continue; + } + } + + return $subscriber; + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + if ( ! empty( $data['api_key'] ) && 'default' === $data['api_key'] ) { + $api_key = $this->get_global_api_key(); + } elseif ( ! empty( $data['custom_api_key'] ) ) { + $api_key = $data['custom_api_key']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_key` is required.', 400 ); + } + + $handler = new Convertkit_Handler( $api_key ); + + return $handler->get_forms_and_tags(); + } + + public function ajax_validate_api_token() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Convertkit_Handler( $_POST['api_key'] ); // phpcs:ignore -- No need to sanitize to support special characters. + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'convertkit', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'ConvertKit', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_token' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'convertkit_form!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/discord.php b/modules/forms/actions/discord.php new file mode 100644 index 00000000..4b0c3774 --- /dev/null +++ b/modules/forms/actions/discord.php @@ -0,0 +1,222 @@ +start_controls_section( + 'section_discord', + [ + 'label' => esc_html__( 'Discord', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'discord_webhook', + [ + 'label' => esc_html__( 'Webhook URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'https://discordapp.com/api/webhooks/', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'separator' => 'before', + 'description' => esc_html__( 'Enter the webhook URL that will receive the form\'s submitted data.', 'elementor-pro' ) . ' ' . sprintf( '%s.', 'https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks', esc_html__( 'Click here for Instructions', 'elementor-pro' ) ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'discord_username', + [ + 'label' => esc_html__( 'Username', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'discord_avatar_url', + [ + 'label' => esc_html__( 'Avatar URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'discord_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'discord_content', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'discord_form_data', + [ + 'label' => esc_html__( 'Form Data', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $widget->add_control( + 'discord_ts', + [ + 'label' => esc_html__( 'Timestamp', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $widget->add_control( + 'discord_webhook_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'alpha' => false, + 'default' => '#D30C5C', + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['discord_avatar_url'], + $element['discord_content'], + $element['discord_webhook_color'], + $element['discord_username'], + $element['discord_form_data'], + $element['discord_ts'], + $element['discord_title'], + $element['discord_webhook'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $settings = $record->get( 'form_settings' ); + + if ( empty( $settings['discord_webhook'] ) || false === strpos( $settings['discord_webhook'], 'https://discordapp.com/api/webhooks/' ) ) { + return; + } + + // PHPCS - The form is a visitor action and doesn't require a nonce. + $referrer = Utils::_unstable_get_super_global_value( $_POST, 'referrer' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + + $page_url = $referrer ? esc_url( $referrer ) : site_url(); + $color = isset( $settings['discord_webhook_color'] ) ? hexdec( ltrim( $settings['discord_webhook_color'], '#' ) ) : hexdec( '9c0244' ); + + // Build discord webhook data + $embeds = [ + 'title' => isset( $settings['discord_title'] ) ? $settings['discord_title'] : esc_html__( 'A new Submission', 'elementor-pro' ), + 'description' => isset( $settings['discord_content'] ) ? $settings['discord_content'] : esc_html__( 'A new Form Submission has been received', 'elementor-pro' ), + 'author' => [ + 'name' => isset( $settings['discord_username'] ) ? $settings['discord_username'] : esc_html__( 'Elementor Forms', 'elementor-pro' ), + 'url' => $page_url, + 'icon_url' => isset( $settings['discord_avatar_url'] ) ? $settings['discord_avatar_url'] : null, + ], + 'url' => $page_url, + 'color' => $color, + ]; + + if ( ! empty( $settings['discord_form_data'] ) && 'yes' === $settings['discord_form_data'] ) { + // prepare Form Data + $raw_fields = $record->get( 'fields' ); + $fields = []; + foreach ( $raw_fields as $id => $field ) { + $fields[] = [ + 'name' => $id, + 'value' => $field['value'], + 'inline' => false, + ]; + } + + $embeds['fields'] = array_values( $fields ); + } + + if ( ! empty( $settings['discord_ts'] ) && 'yes' === $settings['discord_ts'] ) { + $embeds['timestamp'] = gmdate( \DateTime::ISO8601 ); + $embeds['footer'] = [ + 'text' => sprintf( + /* translators: %s: Elementor. */ + esc_html__( 'Powered by %s', 'elementor-pro' ), + 'Elementor' + ), + 'icon_url' => is_ssl() ? ELEMENTOR_ASSETS_URL . 'images/logo-icon.png' : null, + ]; + } + + $webhook_data = [ + 'embeds' => array_values( [ $embeds ] ), + ]; + + $webhook_data = apply_filters( 'elementor_pro/forms/discord/webhook_args', $webhook_data ); + + $response = wp_safe_remote_post( $settings['discord_webhook'], [ + 'body' => wp_json_encode( $webhook_data ), + 'headers' => [ 'Content-Type' => 'application/json; charset=utf-8' ], + ]); + + if ( 204 !== (int) wp_remote_retrieve_response_code( $response ) ) { + throw new \Exception( 'Webhook error.' ); + } + } +} diff --git a/modules/forms/actions/drip.php b/modules/forms/actions/drip.php new file mode 100644 index 00000000..182337d8 --- /dev/null +++ b/modules/forms/actions/drip.php @@ -0,0 +1,349 @@ +start_controls_section( + 'section_drip', + [ + 'label' => esc_html__( 'Drip', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'Drip API Token', + [ + 'drip_api_token_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'drip_api_token_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'drip_custom_api_token', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'drip_api_token_source' => 'custom', + ], + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'drip_account', + [ + 'label' => esc_html__( 'Account', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'drip_custom_api_token', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'drip_api_token_source', + 'operator' => '=', + 'value' => 'default', + ], + ], + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->add_control( + 'drip_custom_field_heading', + [ + 'label' => esc_html__( 'Send Additional Data to Drip', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'drip_account!' => '', + ], + ] + ); + + $widget->add_control( + 'drip_custom_fields', + [ + 'label' => esc_html__( 'Form Fields', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'description' => esc_html__( 'Send all form fields to drip as custom fields', 'elementor-pro' ), + 'condition' => [ + 'drip_account!' => '', + ], + ] + ); + + $widget->add_control( + 'tags', + [ + 'label' => esc_html__( 'Tags', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Add as many tags as you want, comma separated.', 'elementor-pro' ), + 'condition' => [ + 'drip_account!' => '', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['drip_api_token_source'], + $element['settings']['drip_custom_api_token'], + $element['settings']['drip_account'], + $element['settings']['drip_fields_map'], + $element['settings']['tags'], + $element['settings']['drip_custom_fields'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->create_subscriber_object( $record ); + + if ( ! $subscriber ) { + throw new \Exception( 'Integration requires an email field.' ); + } + + if ( 'default' === $form_settings['drip_api_token_source'] ) { + $api_key = $this->get_global_api_key(); + } else { + $api_key = $form_settings['drip_custom_api_token']; + } + + $handler = new Drip_Handler( $api_key ); + $handler->create_subscriber( $form_settings['drip_account'], $subscriber ); + } + + /** + * Create subscriber array from submitted data and form settings + * returns a subscriber array or false on error + * + * @param Form_Record $record + * + * @return array|bool + */ + private function create_subscriber_object( Form_Record $record ) { + $form_settings = $record->get( 'form_settings' ); + $email = $this->map_email_field( $record ); + + if ( ! $email ) { + return false; + } + $subscriber = [ + 'ip_address' => Utils::get_client_ip(), + 'email' => $email, + ]; + + if ( isset( $form_settings['tags'] ) && ! empty( $form_settings['tags'] ) ) { + $tags = $record->replace_setting_shortcodes( $form_settings['tags'] ); + + $subscriber['tags'] = explode( ',', $tags ); + } + + $custom_fields = []; + if ( isset( $form_settings['drip_custom_fields'] ) && 'yes' === $form_settings['drip_custom_fields'] ) { + $custom_fields = $this->get_drip_custom_fields( $record ); + } + + $subscriber['custom_fields'] = $custom_fields; + + return $subscriber; + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function get_drip_custom_fields( Form_Record $record ) { + $local_email_id = ''; + foreach ( $record->get_form_settings( 'drip_fields_map' ) as $map_item ) { + if ( 'email' === $map_item['remote_id'] ) { + $local_email_id = $map_item['local_id']; + } + } + $custom_fields = []; + foreach ( $record->get( 'fields' ) as $id => $field ) { + if ( $local_email_id === $id ) { + continue; + } + $custom_fields[ $id ] = $field['value']; + } + + return $custom_fields; + } + + /** + * extracts Email field from form based on mapping + * returns email address or false if missing + * + * @param Form_Record $record + * + * @return bool + */ + private function map_email_field( Form_Record $record ) { + $fields = $record->get( 'fields' ); + foreach ( $record->get_form_settings( 'drip_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + if ( 'email' === $map_item['remote_id'] ) { + return $value; + } + } + + return false; + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + if ( ! empty( $data['api_token'] ) && 'default' === $data['api_token'] ) { + $api_key = $this->get_global_api_key(); + } elseif ( ! empty( $data['custom_api_token'] ) ) { + $api_key = $data['custom_api_token']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_token` is required.', 400 ); + } + + $handler = new Drip_Handler( $api_key ); + + return $handler->get_accounts(); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'drip', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'Drip', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + /** + * + */ + public function ajax_validate_api_token() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Drip_Handler( $_POST['api_key'] ); // phpcs:ignore -- No need to sanitize to support special characters. + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_token' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'drip_account!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/email.php b/modules/forms/actions/email.php new file mode 100644 index 00000000..84b6322e --- /dev/null +++ b/modules/forms/actions/email.php @@ -0,0 +1,497 @@ +start_controls_section( + $this->get_control_id( 'section_email' ), + [ + 'label' => $this->get_label(), + 'tab' => Controls_Manager::TAB_CONTENT, + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $this->maybe_add_site_mailer_notice( $widget ); + + $widget->add_control( + $this->get_control_id( 'email_to' ), + [ + 'label' => esc_html__( 'To', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => get_option( 'admin_email' ), + 'ai' => [ + 'active' => false, + ], + 'placeholder' => get_option( 'admin_email' ), + 'label_block' => true, + 'title' => esc_html__( 'Separate emails with commas', 'elementor-pro' ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + /* translators: %s: Site title. */ + $default_message = sprintf( __( 'New message from "%s"', 'elementor-pro' ), get_option( 'blogname' ) ); + + $widget->add_control( + $this->get_control_id( 'email_subject' ), + [ + 'label' => esc_html__( 'Subject', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_message, + 'ai' => [ + 'active' => false, + ], + 'placeholder' => $default_message, + 'label_block' => true, + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_content' ), + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => '[all-fields]', + 'ai' => [ + 'active' => false, + ], + 'placeholder' => '[all-fields]', + 'description' => sprintf( + /* translators: %s: The [all-fields] shortcode. */ + esc_html__( 'By default, all form fields are sent via %s shortcode. To customize sent fields, copy the shortcode that appears inside each field and paste it above.', 'elementor-pro' ), + '[all-fields]' + ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $site_domain = Utils::get_site_domain(); + + $widget->add_control( + $this->get_control_id( 'email_from' ), + [ + 'label' => esc_html__( 'From Email', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => 'email@' . $site_domain, + 'ai' => [ + 'active' => false, + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_from_name' ), + [ + 'label' => esc_html__( 'From Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => get_bloginfo( 'name' ), + 'ai' => [ + 'active' => false, + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_reply_to' ), + [ + 'label' => esc_html__( 'Reply-To', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => '', + ], + 'render_type' => 'none', + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_to_cc' ), + [ + 'label' => esc_html__( 'Cc', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'title' => esc_html__( 'Separate emails with commas', 'elementor-pro' ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_to_bcc' ), + [ + 'label' => esc_html__( 'Bcc', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'title' => esc_html__( 'Separate emails with commas', 'elementor-pro' ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + $this->get_control_id( 'form_metadata' ), + [ + 'label' => esc_html__( 'Meta Data', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'label_block' => true, + 'separator' => 'before', + 'default' => [ + 'date', + 'time', + 'page_url', + 'user_agent', + 'remote_ip', + 'credit', + ], + 'options' => [ + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'time' => esc_html__( 'Time', 'elementor-pro' ), + 'page_url' => esc_html__( 'Page URL', 'elementor-pro' ), + 'user_agent' => esc_html__( 'User Agent', 'elementor-pro' ), + 'remote_ip' => esc_html__( 'Remote IP', 'elementor-pro' ), + 'credit' => esc_html__( 'Credit', 'elementor-pro' ), + ], + 'render_type' => 'none', + ] + ); + + $widget->add_control( + $this->get_control_id( 'email_content_type' ), + [ + 'label' => esc_html__( 'Send As', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'html', + 'render_type' => 'none', + 'options' => [ + 'html' => esc_html__( 'HTML', 'elementor-pro' ), + 'plain' => esc_html__( 'Plain', 'elementor-pro' ), + ], + ] + ); + + $widget->end_controls_section(); + } + + public function maybe_add_site_mailer_notice( $widget ) { + $notice_id = 'site_mailer_forms_email_notice'; + if ( ! Hints::should_show_hint( $notice_id ) ) { + return; + } + $notice_content = esc_html__( 'Experiencing email deliverability issues? Get your emails delivered with Site Mailer.', 'elementor-pro' ); + + if ( 2 === Utils\Abtest::get_variation( 'plg_site_mailer_submission' ) ) { + $notice_content = esc_html__( 'Make sure your emails reach the inbox every time with Site Mailer', 'elementor-pro' ); + } + + $widget->add_control( + $this->get_control_id( 'site_mailer_promo' ), + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Hints::get_notice_template( [ + 'display' => ! Hints::is_dismissed( $notice_id ), + 'type' => 'info', + 'content' => $notice_content, + 'icon' => true, + 'dismissible' => $notice_id, + 'button_text' => Hints::is_plugin_installed( 'site-mailer' ) ? __( 'Activate Plugin', 'elementor-pro' ) : __( 'Install Plugin', 'elementor-pro' ), + 'button_event' => $notice_id, + 'button_data' => [ + 'action_url' => Hints::get_plugin_action_url( 'site-mailer' ), + ], + ], true ), + ] + ); + } + + public function on_export( $element ) { + $controls_to_unset = [ + 'email_to', + 'email_from', + 'email_from_name', + 'email_subject', + 'email_reply_to', + 'email_to_cc', + 'email_to_bcc', + ]; + + foreach ( $controls_to_unset as $base_id ) { + $control_id = $this->get_control_id( $base_id ); + unset( $element['settings'][ $control_id ] ); + } + + return $element; + } + + /** + * @param \ElementorPro\Modules\Forms\Classes\Form_Record $record + * @param \ElementorPro\Modules\Forms\Classes\Ajax_Handler $ajax_handler + */ + public function run( $record, $ajax_handler ) { + $settings = $record->get( 'form_settings' ); + $send_html = 'plain' !== $settings[ $this->get_control_id( 'email_content_type' ) ]; + $line_break = $send_html ? '
      ' : "\n"; + + $fields = [ + 'email_to' => get_option( 'admin_email' ), + /* translators: %s: Site title. */ + 'email_subject' => sprintf( esc_html__( 'New message from "%s"', 'elementor-pro' ), get_bloginfo( 'name' ) ), + 'email_content' => '[all-fields]', + 'email_from_name' => get_bloginfo( 'name' ), + 'email_from' => get_bloginfo( 'admin_email' ), + 'email_reply_to' => 'noreply@' . Utils::get_site_domain(), + 'email_to_cc' => '', + 'email_to_bcc' => '', + ]; + + foreach ( $fields as $key => $default ) { + $setting = trim( $settings[ $this->get_control_id( $key ) ] ); + $setting = $record->replace_setting_shortcodes( $setting ); + if ( ! empty( $setting ) ) { + $fields[ $key ] = $setting; + } + } + + $email_reply_to = $this->get_reply_to( $record, $fields ); + + $fields['email_content'] = $this->replace_content_shortcodes( $fields['email_content'], $record, $line_break ); + + $email_meta = ''; + + $form_metadata_settings = $settings[ $this->get_control_id( 'form_metadata' ) ]; + + foreach ( $record->get( 'meta' ) as $id => $field ) { + if ( in_array( $id, $form_metadata_settings ) ) { + $email_meta .= $this->field_formatted( $field ) . $line_break; + } + } + + if ( ! empty( $email_meta ) ) { + $fields['email_content'] .= $line_break . '---' . $line_break . $line_break . $email_meta; + } + + $headers = sprintf( 'From: %s <%s>' . "\r\n", $fields['email_from_name'], $fields['email_from'] ); + $headers .= sprintf( 'Reply-To: %s' . "\r\n", $email_reply_to ); + + if ( $send_html ) { + $headers .= 'Content-Type: text/html; charset=UTF-8' . "\r\n"; + } + + $cc_header = ''; + if ( ! empty( $fields['email_to_cc'] ) ) { + $cc_header = 'Cc: ' . $fields['email_to_cc'] . "\r\n"; + } + + /** + * Email headers. + * + * Filters the headers sent when an email is sent from Elementor forms. This + * hook allows developers to alter email headers triggered by Elementor forms. + * + * @since 1.0.0 + * + * @param string|array $headers Additional headers. + */ + $headers = apply_filters( 'elementor_pro/forms/wp_mail_headers', $headers ); + + /** + * Email content. + * + * Filters the content of the email sent by Elementor forms. This hook allows + * developers to alter the content of the email sent by Elementor forms. + * + * @since 1.0.0 + * + * @param string $email_content Email content. + */ + $fields['email_content'] = apply_filters( 'elementor_pro/forms/wp_mail_message', $fields['email_content'] ); + + $attachments_mode_attach = $this->get_file_by_attachment_type( $settings['form_fields'], $record, Upload::MODE_ATTACH ); + $attachments_mode_both = $this->get_file_by_attachment_type( $settings['form_fields'], $record, Upload::MODE_BOTH ); + + $email_sent = wp_mail( + $fields['email_to'], + $fields['email_subject'], + $fields['email_content'], + $headers . $cc_header, + array_merge( $attachments_mode_attach, $attachments_mode_both ) + ); + + if ( ! empty( $fields['email_to_bcc'] ) ) { + $bcc_emails = explode( ',', $fields['email_to_bcc'] ); + foreach ( $bcc_emails as $bcc_email ) { + wp_mail( + trim( $bcc_email ), + $fields['email_subject'], + $fields['email_content'], + $headers, + array_merge( $attachments_mode_attach, $attachments_mode_both ) + ); + } + } + + foreach ( $attachments_mode_attach as $file ) { + @unlink( $file ); + } + + /** + * Elementor form mail sent. + * + * Fires when an email was sent successfully by Elementor forms. This + * hook allows developers to add functionality after mail sending. + * + * @since 1.0.0 + * + * @param array $settings Form settings. + * @param Form_Record $record An instance of the form record. + */ + do_action( 'elementor_pro/forms/mail_sent', $settings, $record ); + + if ( ! $email_sent ) { + $message = Ajax_Handler::get_default_message( Ajax_Handler::SERVER_ERROR, $settings ); + + $ajax_handler->add_error_message( $message ); + + throw new \Exception( $message ); + } + } + + private function field_formatted( $field ) { + $formatted = ''; + if ( ! empty( $field['title'] ) ) { + $formatted = sprintf( '%s: %s', $field['title'], $field['value'] ); + } elseif ( ! empty( $field['value'] ) ) { + $formatted = sprintf( '%s', $field['value'] ); + } + + return $formatted; + } + + // Allow overwrite the control_id with a prefix, @see Email2 + protected function get_control_id( $control_id ) { + return $control_id; + } + + protected function get_reply_to( $record, $fields ) { + $email_reply_to = ''; + + if ( ! empty( $fields['email_reply_to'] ) ) { + $sent_data = $record->get( 'sent_data' ); + foreach ( $record->get( 'fields' ) as $field_index => $field ) { + if ( $field_index === $fields['email_reply_to'] && ! empty( $sent_data[ $field_index ] ) && is_email( $sent_data[ $field_index ] ) ) { + $email_reply_to = $sent_data[ $field_index ]; + break; + } + } + } + + return $email_reply_to; + } + + /** + * @param string $email_content + * @param Form_Record $record + * + * @return string + */ + private function replace_content_shortcodes( $email_content, $record, $line_break ) { + $email_content = do_shortcode( $email_content ); + $all_fields_shortcode = '[all-fields]'; + + if ( false !== strpos( $email_content, $all_fields_shortcode ) ) { + $text = ''; + foreach ( $record->get( 'fields' ) as $field ) { + // Skip upload fields that only attached to the email + if ( isset( $field['attachment_type'] ) && Upload::MODE_ATTACH === $field['attachment_type'] ) { + continue; + } + + $formatted = $this->field_formatted( $field ); + if ( ( 'textarea' === $field['type'] ) && ( '
      ' === $line_break ) ) { + $formatted = str_replace( [ "\r\n", "\n", "\r" ], '
      ', $formatted ); + } + + $text .= $formatted . $line_break; + } + + $email_content = str_replace( $all_fields_shortcode, $text, $email_content ); + + } + + return $email_content; + } + + /** + * @param array $form_fields + * @param Form_Record $record + * @param string $type + * + * @return array + */ + private function get_file_by_attachment_type( $form_fields, $record, $type ) { + return Collection::make( $form_fields ) + ->filter( function ( $field ) use ( $type ) { + return $type === $field['attachment_type']; + } ) + ->map( function ( $field ) use ( $record ) { + $id = $field['custom_id']; + + return $record->get( 'files' )[ $id ]['path'] ?? null; + } ) + ->filter() + ->flatten() + ->values(); + } +} diff --git a/modules/forms/actions/email2.php b/modules/forms/actions/email2.php new file mode 100644 index 00000000..565cd2fa --- /dev/null +++ b/modules/forms/actions/email2.php @@ -0,0 +1,52 @@ +update_control( + $this->get_control_id( 'email_reply_to' ), + [ + 'type' => Controls_Manager::TEXT, + 'default' => $admin_email, + 'placeholder' => $admin_email, + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->update_control( + $this->get_control_id( 'form_metadata' ), + [ + 'default' => [], + ] + ); + } +} diff --git a/modules/forms/actions/getresponse.php b/modules/forms/actions/getresponse.php new file mode 100644 index 00000000..eee8f65e --- /dev/null +++ b/modules/forms/actions/getresponse.php @@ -0,0 +1,334 @@ +start_controls_section( + 'section_getresponse', + [ + 'label' => esc_html__( 'GetResponse', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'GetResponse API key', + [ + 'getresponse_api_key_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'getresponse_api_key_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'getresponse_custom_api_key', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'condition' => [ + 'getresponse_api_key_source' => 'custom', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'getresponse_list', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'getresponse_custom_api_key', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'getresponse_api_key_source', + 'operator' => '=', + 'value' => 'default', + ], + ], + ], + ] + ); + + $widget->add_control( + 'getresponse_dayofcycle', + [ + 'label' => esc_html__( 'Day Of Cycle', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 0, + 'condition' => [ + 'getresponse_list!' => '', + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['getresponse_api_key_source'], + $element['settings']['getresponse_custom_api_key'], + $element['settings']['getresponse_list'], + $element['settings']['getresponse_fields_map'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->create_subscriber_object( $record ); + + if ( ! $subscriber ) { + throw new \Exception( 'Integration requires an email field.' ); + } + + if ( 'default' === $form_settings['getresponse_api_key_source'] ) { + $api_key = $this->get_global_api_key(); + } else { + $api_key = $form_settings['getresponse_custom_api_key']; + } + + try { + $handler = new Getresponse_Handler( $api_key ); + $handler->create_subscriber( $subscriber ); + } catch ( \Exception $exception ) { + foreach ( (array) $handler->rest_client->request_cache as $response ) { + if ( isset( $response['parsed'] ) || ! isset( $response['raw'] ) || ! isset( $response['raw']['response'] ) || ! isset( $response['raw']['response']['code'] ) ) { + continue; + } + if ( ! in_array( $response['raw']['response']['code'], [ 200, 202, 409 ] ) ) { + throw new \Exception( $exception->getMessage() ); + } + } + } + } + + /** + * Create subscriber array from submitted data and form settings + * returns a subscriber array or false on error + * + * @param Form_Record $record + * + * @return array|bool + */ + private function create_subscriber_object( Form_Record $record ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->map_fields( $record ); + + if ( ! isset( $subscriber['email'] ) ) { + return false; + } + + if ( isset( $form_settings['getresponse_dayofcycle'] ) ) { + $subscriber['dayOfCycle'] = intval( $form_settings['getresponse_dayofcycle'] ); + } + $subscriber['ipAddress'] = Utils::get_client_ip(); + $subscriber['campaign'] = [ 'campaignId' => $form_settings['getresponse_list'] ]; + + return $subscriber; + } + + + /** + * @param Form_Record $record + * + * @return array + */ + private function get_getresponse_custom_fields( Form_Record $record ) { + $local_email_id = ''; + $local_name_id = ''; + foreach ( $record->get_form_settings( 'getresponse_fields_map' ) as $map_item ) { + if ( 'email' === $map_item['remote_id'] ) { + $local_email_id = $map_item['local_id']; + } + if ( 'name' === $map_item['remote_id'] ) { + $local_name_id = $map_item['local_id']; + } + } + $custom_fields = []; + foreach ( $record->get( 'fields' ) as $id => $field ) { + if ( in_array( $id, [ $local_email_id, $local_name_id ] ) ) { + continue; + } + $custom_fields[ $id ] = $field['value']; + } + + return $custom_fields; + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( Form_Record $record ) { + $subscriber = []; + $custom_fields = []; + $fields = $record->get( 'fields' ); + + // Other form has a field mapping + foreach ( $record->get_form_settings( 'getresponse_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + if ( in_array( $map_item['remote_id'], [ 'name', 'email' ] ) ) { + $subscriber[ $map_item['remote_id'] ] = $value; + continue; + } + + $custom_fields[] = [ + 'customFieldId' => $map_item['remote_id'], + 'value' => [ $value ], + ]; + } + $subscriber['customFieldValues'] = $custom_fields; + + return $subscriber; + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + if ( ! empty( $data['api_key'] ) && 'default' === $data['api_key'] ) { + $api_key = $this->get_global_api_key(); + } elseif ( ! empty( $data['custom_api_key'] ) ) { + $api_key = $data['custom_api_key']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_key` is required.', 400 ); + } + + $handler = new Getresponse_Handler( $api_key ); + + if ( 'lists' === $data['getresponse_action'] ) { + return $handler->get_lists(); + } + + return $handler->get_fields(); + } + + public function ajax_validate_api_token() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Getresponse_Handler( $_POST['api_key'] ); // phpcs:ignore -- No need to sanitize to support special characters. + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'getresponse', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'GetResponse', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_token' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'getresponse_list!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/mailchimp.php b/modules/forms/actions/mailchimp.php new file mode 100644 index 00000000..a25ec5d7 --- /dev/null +++ b/modules/forms/actions/mailchimp.php @@ -0,0 +1,490 @@ +start_controls_section( + 'section_mailchimp', + [ + 'label' => esc_html__( 'MailChimp', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'MailChimp API Key', + [ + 'mailchimp_api_key_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'mailchimp_api_key_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'mailchimp_api_key', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'mailchimp_api_key_source' => 'custom', + ], + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'mailchimp_list', + [ + 'label' => esc_html__( 'Audience', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'mailchimp_api_key', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'mailchimp_api_key_source', + 'operator' => '=', + 'value' => 'default', + ], + ], + ], + ] + ); + + $widget->add_control( + 'mailchimp_groups', + [ + 'label' => esc_html__( 'Groups', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'render_type' => 'none', + 'condition' => [ + 'mailchimp_list!' => '', + ], + ] + ); + + $widget->add_control( + 'mailchimp_tags', + [ + 'label' => esc_html__( 'Tags', 'elementor-pro' ), + 'description' => esc_html__( 'Add comma separated tags', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'render_type' => 'none', + 'condition' => [ + 'mailchimp_list!' => '', + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'mailchimp_double_opt_in', + [ + 'label' => esc_html__( 'Double Opt-In', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'mailchimp_list!' => '', + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['mailchimp_api_key_source'], + $element['settings']['mailchimp_api_key'], + $element['settings']['mailchimp_list'], + $element['settings']['mailchimp_groups'], + $element['settings']['mailchimp_fields_map'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + + if ( 'default' === $form_settings['mailchimp_api_key_source'] ) { + $this->api_key = $this->get_global_api_key(); + } else { + $this->api_key = $form_settings['mailchimp_api_key']; + } + + // Data from the form in the frontend. + $subscriber_data = $this->map_fields( $record ); + + // Create or update a subscriber. + $subscriber = $this->create_or_update_subscriber( $subscriber_data, $form_settings ); + + // Parse the Mailchimp tags. + $tags = $this->parse_tags( $form_settings['mailchimp_tags'] ); + + // Set the subscriber tags only if he doesn't have them already. + if ( ! $this->subscriber_has_tags( $subscriber, $tags ) ) { + $this->set_subscriber_tags( $subscriber, $tags ); + } + } + + /** + * @param string $tags - List of comma separated tags from the forms settings ( i.e. 'tag-1, tag-2' ). + * + * @return array|string[] - Array of tags that were extracted from the input ( i.e. [ 'tag-1', 'tag-2' ] ). + */ + private function parse_tags( $tags ) { + $parsed_tags = []; + + if ( ! empty( $tags ) ) { + $parsed_tags = explode( ',', trim( $tags ) ); + + // Remove empty tags. + $parsed_tags = array_filter( $parsed_tags ); + + // Trim tags. + $parsed_tags = array_map( 'trim', $parsed_tags ); + } + + return $parsed_tags; + } + + /** + * Determine if a subscriber has specific tags, and ONLY those tags. + * + * @param array $subscriber - Subscriber data from an API response. + * @param array $tags - List of tags to check ( i.e. [ 'tag-1', 'tag-2' ] ). + * + * @return bool + */ + private function subscriber_has_tags( array $subscriber, array $tags ) { + // Extract current tags. + $subscriber_tags = []; + + foreach ( $subscriber['tags'] as $tag ) { + $subscriber_tags[] = $tag['name']; + } + + return array_diff( $tags, $subscriber_tags ) === array_diff( $subscriber_tags, $tags ); + } + + /** + * Set Mailchimp subscriber tags. + * + * @param array $subscriber - Subscriber data from a create/update request. + * @param array $tags - List of tags to set. + * + * @return void + */ + private function set_subscriber_tags( array $subscriber, array $tags ) { + // Build the request tags. + $request_tags = []; + + // Set current tags to active. + foreach ( $subscriber['tags'] as $tag ) { + $request_tags[] = [ + 'name' => $tag['name'], + 'status' => 'active', + ]; + } + + // Set new tags to active. + foreach ( $tags as $tag ) { + $request_tags[] = [ + 'name' => $tag, + 'status' => 'active', + ]; + } + + // Send the API request. + $endpoint = sprintf( 'lists/%s/members/%s/tags', $subscriber['list_id'], md5( strtolower( $subscriber['email_address'] ) ) ); + $args = [ + 'tags' => $request_tags, + ]; + + $handler = new Mailchimp_Handler( $this->api_key ); + $response = $handler->post( $endpoint, $args ); + + if ( 204 !== $response['code'] ) { + $error = ! empty( $response['body']['detail'] ) ? $response['body']['detail'] : ''; + $code = $response['code']; + + throw new \Exception( "HTTP {$code} - {$error}" ); + } + } + + /** + * Get Mailchimp subscriber data. + * + * @param string $list - Mailchimp List ID. + * @param string $email_hash - Subscriber's email hash (lowercase + MD5). + * + * @return array|null + */ + private function get_subscriber_data( $list, $email_hash ) { + $handler = new Mailchimp_Handler( $this->api_key ); + $end_point = sprintf( 'lists/%s/members/%s', $list, $email_hash ); + + try { + return $handler->query( $end_point ); + } catch ( \Exception $e ) { + return null; + } + } + + /** + * Set Mailchimp subscriber data. + * + * @param string $list - Mailchimp List ID. + * @param string $email_hash - Subscriber's email hash (lowercase + MD5). + * @param array $data - New subscriber data to set. + * + * @return array + */ + private function set_subscriber_data( $list, $email_hash, $data ) { + $handler = new Mailchimp_Handler( $this->api_key ); + + $end_point = sprintf( 'lists/%s/members/%s', $list, $email_hash ); + + $response = $handler->post( $end_point, $data, [ + 'method' => 'PUT', // Add or Update + ] ); + + if ( 200 !== $response['code'] ) { + $error = ! empty( $response['body']['detail'] ) ? $response['body']['detail'] : ''; + $code = $response['code']; + + throw new \Exception( "HTTP {$code} - {$error}" ); + } + + return $response['body']; + } + + /** + * Create or update a Mailchimp subscriber. + * + * @param array $subscriber - Subscriber data from the form in the frontend. + * @param array $form_settings - Settings from the editor. + * + * @return array - An array that contains the newly created subscriber's data. + */ + private function create_or_update_subscriber( array $subscriber, array $form_settings ) { + if ( ! empty( $form_settings['mailchimp_groups'] ) ) { + $subscriber['interests'] = []; + } + + if ( is_array( $form_settings['mailchimp_groups'] ) ) { + foreach ( $form_settings['mailchimp_groups'] as $mailchimp_group ) { + $subscriber['interests'][ $mailchimp_group ] = true; + } + } + + if ( ! empty( $form_settings['mailchimp_tags'] ) ) { + $subscriber['tags'] = explode( ',', trim( $form_settings['mailchimp_tags'] ) ); + } + + $list = $form_settings['mailchimp_list']; + $email_hash = md5( strtolower( $subscriber['email_address'] ) ); + $double_opt_in = ( 'yes' === $form_settings['mailchimp_double_opt_in'] ); + + $subscriber['status_if_new'] = $double_opt_in ? 'pending' : 'subscribed'; + + if ( $double_opt_in ) { + $subscriber_data = $this->get_subscriber_data( $list, $email_hash ); + + // Change the current status only if the user isn't subscribed already. + if ( $subscriber_data && 'subscribed' !== $subscriber_data['status'] ) { + $subscriber['status'] = 'pending'; + } + } else { + $subscriber['status'] = 'subscribed'; + } + + return $this->set_subscriber_data( $list, $email_hash, $subscriber ); + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( $record ) { + $subscriber = []; + $fields = $record->get( 'fields' ); + + // Other form has a field mapping + foreach ( $record->get_form_settings( 'mailchimp_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + if ( 'email' === $map_item['remote_id'] ) { + $subscriber['email_address'] = $value; + } else { + $subscriber['merge_fields'][ $map_item['remote_id'] ] = $value; + } + } + + return $subscriber; + } + + public function ajax_validate_api_token() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Mailchimp_Handler( $_POST['api_key'] ); // phpcs:ignore -- No need to sanitize to support special characters. + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function handle_panel_request( array $data ) { + if ( ! empty( $data['use_global_api_key'] ) && 'default' === $data['use_global_api_key'] ) { + $api_key = $this->get_global_api_key(); + } elseif ( ! empty( $data['api_key'] ) ) { + $api_key = $data['api_key']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_key` is required.', 400 ); + } + + $handler = new Mailchimp_Handler( $api_key ); + + switch ( $data['mailchimp_action'] ) { + case 'lists': + return $handler->get_lists(); + + case 'fields': + return $handler->get_fields( $data['mailchimp_list'] ); + + case 'groups': + return $handler->get_groups( $data['mailchimp_list'] ); + + default: + return $handler->get_list_details( $data['mailchimp_list'] ); + } + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'mailchimp', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'MailChimp', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 14 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_token' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'mailchimp_list!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/mailerlite.php b/modules/forms/actions/mailerlite.php new file mode 100644 index 00000000..322c5fd4 --- /dev/null +++ b/modules/forms/actions/mailerlite.php @@ -0,0 +1,303 @@ +start_controls_section( + 'section_mailerlite', + [ + 'label' => esc_html__( 'MailerLite', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + self::global_api_control( + $widget, + $this->get_global_api_key(), + 'MailerLite API Key', + [ + 'mailerlite_api_key_source' => 'default', + ], + $this->get_name() + ); + + $widget->add_control( + 'mailerlite_api_key_source', + [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + ] + ); + + $widget->add_control( + 'mailerlite_custom_api_key', + [ + 'label' => esc_html__( 'Custom API Key', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'mailerlite_api_key_source' => 'custom', + ], + 'description' => esc_html__( 'Use this field to set a custom API Key for the current form', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $widget->add_control( + 'mailerlite_group', + [ + 'label' => esc_html__( 'Group', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [], + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'mailerlite_custom_api_key', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'mailerlite_api_key_source', + 'operator' => '=', + 'value' => 'default', + ], + ], + ], + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->add_control( + 'allow_resubscribe', + [ + 'label' => esc_html__( 'Allow Resubscribe', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'mailerlite_group!' => '', + ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['mailerlite_api_key_source'], + $element['settings']['mailerlite_custom_api_key'], + $element['settings']['mailerlite_group'], + $element['settings']['mailerlite_fields_map'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $form_settings = $record->get( 'form_settings' ); + $subscriber = $this->create_subscriber_object( $record ); + + if ( ! $subscriber ) { + new \Exception( esc_html__( 'Integration requires an email field', 'elementor-pro' ) ); + } + + if ( 'default' === $form_settings['mailerlite_api_key_source'] ) { + $api_key = $this->get_global_api_key(); + } else { + $api_key = $form_settings['mailerlite_custom_api_key']; + } + + $handler = new Mailerlite_Handler( $api_key ); + $handler->create_subscriber( $form_settings['mailerlite_group'], $subscriber ); + } + + /** + * Create subscriber array from submitted data and form settings + * returns a subscriber array or false on error + * + * @param Form_Record $record + * + * @return array|bool + */ + private function create_subscriber_object( Form_Record $record ) { + $email = $this->get_mapped_field( $record, 'email' ); + + if ( ! $email ) { + return false; + } + + $subscriber = [ + 'email' => $email, + 'name' => $this->get_mapped_field( $record, 'name' ), + ]; + + $subscriber['fields'] = $this->get_mailerlite_custom_fields( $record ); + + // Allow re-subscribe + $allow_resubscribe = $record->get_form_settings( 'allow_resubscribe' ); + if ( ! empty( $allow_resubscribe ) && 'yes' === $allow_resubscribe ) { + $subscriber['resubscribe'] = true; + } + + return $subscriber; + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function get_mailerlite_custom_fields( Form_Record $record ) { + $custom_fields = []; + $form_fields = $record->get( 'fields' ); + $field_mapping = $record->get_form_settings( 'mailerlite_fields_map' ); + foreach ( $field_mapping as $map_item ) { + if ( in_array( $map_item['remote_id'], [ 'email', 'name' ] ) ) { + continue; + } + + if ( empty( $map_item['local_id'] ) ) { + continue; + } + + foreach ( $form_fields as $id => $field ) { + if ( $id !== $map_item['local_id'] ) { + continue; + } + $custom_fields[ $map_item['remote_id'] ] = $field['value']; + } + } + + return $custom_fields; + } + + private function get_mapped_field( Form_Record $record, $field_id ) { + $fields = $record->get( 'fields' ); + foreach ( $record->get_form_settings( 'mailerlite_fields_map' ) as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + if ( $field_id === $map_item['remote_id'] ) { + return $fields[ $map_item['local_id'] ]['value']; + } + } + + return ''; + } + + public function handle_panel_request( array $data ) { + if ( ! empty( $data['api_key'] ) && 'default' === $data['api_key'] ) { + $api_key = $this->get_global_api_key(); + } elseif ( ! empty( $data['custom_api_key'] ) ) { + $api_key = $data['custom_api_key']; + } + + if ( empty( $api_key ) ) { + throw new \Exception( '`api_key` is required.', 400 ); + } + + $handler = new Mailerlite_Handler( $api_key ); + if ( 'groups' === $data['mailerlite_action'] ) { + return $handler->get_groups(); + } + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'mailerlite', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'MailerLite', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_API_KEY => [ + 'label' => esc_html__( 'API Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To integrate with our forms you need an %1$sAPI Key%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_api_data' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::OPTION_NAME_API_KEY . '_validate', wp_create_nonce( self::OPTION_NAME_API_KEY ), esc_html__( 'Validate API Key', 'elementor-pro' ) ), + ], + ], + ], + ] ); + } + + public function ajax_validate_api_key() { + check_ajax_referer( self::OPTION_NAME_API_KEY, '_nonce' ); + if ( ! isset( $_POST['api_key'] ) ) { + wp_send_json_error(); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + try { + new Mailerlite_Handler( $_POST['api_key'] ); // phpcs:ignore -- No need to sanitize to support special characters. + } catch ( \Exception $exception ) { + wp_send_json_error(); + } + wp_send_json_success(); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + add_action( 'wp_ajax_' . self::OPTION_NAME_API_KEY . '_validate', [ $this, 'ajax_validate_api_key' ] ); + } + + protected function get_fields_map_control_options() { + return [ + 'condition' => [ + 'mailerlite_group!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/mailpoet.php b/modules/forms/actions/mailpoet.php new file mode 100644 index 00000000..0a085298 --- /dev/null +++ b/modules/forms/actions/mailpoet.php @@ -0,0 +1,129 @@ +start_controls_section( + 'section_mailpoet', + [ + 'label' => esc_html__( 'MailPoet', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + /** @var \WYSIJA_model_list $model_list */ + $model_list = \WYSIJA::get( 'list', 'model' ); + $mailpoet_lists = $model_list->get( [ 'name', 'list_id' ], [ 'is_enabled' => 1 ] ); + $options = []; + + foreach ( $mailpoet_lists as $list ) { + $options[ $list['list_id'] ] = $list['name']; + } + + $widget->add_control( + 'mailpoet_lists', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'label_block' => true, + 'options' => $options, + 'render_type' => 'none', + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( $element['mailpoet_lists'] ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $subscriber = $this->map_fields( $record ); + + /** @var \WYSIJA_help_user $helper_user */ + $helper_user = \WYSIJA::get( 'user', 'helper' ); + $helper_user->addSubscriber( $subscriber ); + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( $record ) { + $settings = $record->get( 'form_settings' ); + $fields = $record->get( 'fields' ); + + $subscriber = [ + 'user' => [ + 'email' => '', + ], + 'user_list' => [ 'list_ids' => (array) $settings['mailpoet_lists'] ], + ]; + + foreach ( $settings['mailpoet_fields_map'] as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $value = $fields[ $map_item['local_id'] ]['value']; + if ( 'email' === $map_item['remote_id'] ) { + $subscriber['user']['email'] = $value; + } else { + $subscriber['user'][ $map_item['remote_id'] ] = $value; + } + } + + return $subscriber; + } + + protected function get_fields_map_control_options() { + return [ + 'default' => [ + [ + 'remote_id' => 'firstname', + 'remote_label' => esc_html__( 'First Name', 'elementor-pro' ), + 'remote_type' => 'text', + ], + [ + 'remote_id' => 'lastname', + 'remote_label' => esc_html__( 'Last Name', 'elementor-pro' ), + 'remote_type' => 'text', + ], + [ + 'remote_id' => 'email', + 'remote_label' => esc_html__( 'Email', 'elementor-pro' ), + 'remote_type' => 'email', + 'remote_required' => true, + ], + ], + 'condition' => [ + 'mailpoet_lists!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/mailpoet3.php b/modules/forms/actions/mailpoet3.php new file mode 100644 index 00000000..ba60c3df --- /dev/null +++ b/modules/forms/actions/mailpoet3.php @@ -0,0 +1,152 @@ +start_controls_section( + 'section_mailpoet3', + [ + 'label' => esc_html__( 'MailPoet 3', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $mailpoet3_lists = API::MP( 'v1' )->getLists(); + $options = []; + + foreach ( $mailpoet3_lists as $list ) { + $options[ $list['id'] ] = $list['name']; + } + + $widget->add_control( + 'mailpoet3_lists', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'label_block' => true, + 'options' => $options, + 'render_type' => 'none', + ] + ); + + $this->register_fields_map_control( $widget ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( $element['mailpoet3_lists'] ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $settings = $record->get( 'form_settings' ); + $subscriber = $this->map_fields( $record ); + + $existing_subscriber = false; + + try { + API::MP( 'v1' )->addSubscriber( $subscriber, (array) $settings['mailpoet3_lists'] ); + $existing_subscriber = false; + } catch ( \Exception $exception ) { + $error_string = esc_html__( 'This subscriber already exists.', 'mailpoet' ); // phpcs:ignore WordPress.WP.I18n + + if ( $error_string === $exception->getMessage() ) { + $existing_subscriber = true; + } else { + throw $exception; + } + } + + if ( $existing_subscriber ) { + API::MP( 'v1' )->subscribeToLists( $subscriber['email'], (array) $settings['mailpoet3_lists'] ); + } + } + + /** + * @param Form_Record $record + * + * @return array + */ + private function map_fields( $record ) { + $settings = $record->get( 'form_settings' ); + $fields = $record->get( 'fields' ); + + $subscriber = []; + + foreach ( $settings['mailpoet3_fields_map'] as $map_item ) { + if ( empty( $fields[ $map_item['local_id'] ]['value'] ) ) { + continue; + } + + $subscriber[ $map_item['remote_id'] ] = $fields[ $map_item['local_id'] ]['value']; + } + + return $subscriber; + } + + protected function get_fields_map_control_options() { + $mailpoet_fields = [ + [ + 'remote_id' => 'first_name', + 'remote_label' => esc_html__( 'First Name', 'elementor-pro' ), + 'remote_type' => 'text', + ], + [ + 'remote_id' => 'last_name', + 'remote_label' => esc_html__( 'Last Name', 'elementor-pro' ), + 'remote_type' => 'text', + ], + [ + 'remote_id' => 'email', + 'remote_label' => esc_html__( 'Email', 'elementor-pro' ), + 'remote_type' => 'email', + 'remote_required' => true, + ], + ]; + + $fields = API::MP( 'v1' )->getSubscriberFields(); + + if ( ! empty( $fields ) && is_array( $fields ) ) { + foreach ( $fields as $index => $remote ) { + if ( in_array( $remote['id'], [ 'first_name', 'last_name', 'email' ] ) ) { + continue; + } + $mailpoet_fields[] = [ + 'remote_id' => $remote['id'], + 'remote_label' => $remote['name'], + 'remote_type' => 'text', + ]; + } + } + + return [ + 'default' => $mailpoet_fields, + 'condition' => [ + 'mailpoet3_lists!' => '', + ], + ]; + } +} diff --git a/modules/forms/actions/redirect.php b/modules/forms/actions/redirect.php new file mode 100644 index 00000000..f315c8f8 --- /dev/null +++ b/modules/forms/actions/redirect.php @@ -0,0 +1,79 @@ +start_controls_section( + 'section_redirect', + [ + 'label' => esc_html__( 'Redirect', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'redirect_to', + [ + 'label' => esc_html__( 'Redirect To', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'https://your-link.com', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::POST_META_CATEGORY, + TagsModule::TEXT_CATEGORY, + TagsModule::URL_CATEGORY, + ], + ], + 'label_block' => true, + 'render_type' => 'none', + 'classes' => 'elementor-control-direction-ltr', + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['redirect_to'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $redirect_to = $record->get_form_settings( 'redirect_to' ); + + $redirect_to = $record->replace_setting_shortcodes( $redirect_to, true ); + + $redirect_to = esc_url_raw( $redirect_to ); + + if ( ! empty( $redirect_to ) && filter_var( $redirect_to, FILTER_VALIDATE_URL ) ) { + $ajax_handler->add_response_data( 'redirect_url', $redirect_to ); + } + } +} diff --git a/modules/forms/actions/slack.php b/modules/forms/actions/slack.php new file mode 100644 index 00000000..6d3d765d --- /dev/null +++ b/modules/forms/actions/slack.php @@ -0,0 +1,252 @@ +start_controls_section( + 'section_slack', + [ + 'label' => esc_html__( 'Slack', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'slack_webhook', + [ + 'label' => esc_html__( 'Webhook URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'https://hooks.slack.com/services/', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'separator' => 'before', + 'description' => esc_html__( 'Enter the webhook URL that will receive the form\'s submitted data.', 'elementor-pro' ) . ' ' . sprintf( '%s.', 'https://slack.com/apps/A0F7XDUAZ-incoming-webhooks/', esc_html__( 'Click here for Instructions', 'elementor-pro' ) ), + 'render_type' => 'none', + 'classes' => 'elementor-control-direction-ltr', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_channel', + [ + 'label' => esc_html__( 'Channel', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_username', + [ + 'label' => esc_html__( 'Username', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_pretext', + [ + 'label' => esc_html__( 'Pre Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_text', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'slack_add_fields', + [ + 'label' => esc_html__( 'Form Data', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $widget->add_control( + 'slack_add_ts', + [ + 'label' => esc_html__( 'Timestamp', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $widget->add_control( + 'slack_webhook_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'alpha' => false, + 'default' => '#D30C5C', + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['slack_add_ts'], + $element['slack_add_fields'], + $element['slack_webhook_color'], + $element['slack_text'], + $element['slack_pretext'], + $element['slack_title'], + $element['slack_username'], + $element['slack_webhook'], + $element['slack_channel'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $settings = $record->get( 'form_settings' ); + + if ( empty( $settings['slack_webhook'] ) || false === strpos( $settings['slack_webhook'], 'https://hooks.slack.com/services/' ) ) { + return; + } + + // Build slack webhook data + $webhook_data = [ + 'username' => isset( $settings['slack_username'] ) ? $settings['slack_username'] : '', + ]; + + if ( ! empty( $settings['slack_channel'] ) ) { + $webhook_data['channel'] = $settings['slack_channel']; + } + + // The nonce already validated + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $referrer = Utils::_unstable_get_super_global_value( $_POST, 'referrer' ); + + $attachment = [ + 'text' => esc_html__( 'A new Form Submission has been received', 'elementor-pro' ), + 'title' => esc_html__( 'A new Submission', 'elementor-pro' ), + 'color' => isset( $settings['slack_webhook_color'] ) ? $settings['slack_webhook_color'] : '#D30C5C', + 'title_link' => esc_url( $referrer ?? site_url() ), + ]; + + if ( ! empty( $settings['slack_title'] ) ) { + $attachment['title'] = $settings['slack_title']; + } + + if ( ! empty( $settings['slack_text'] ) ) { + $attachment['text'] = $settings['slack_text']; + } + + if ( ! empty( $settings['slack_pretext'] ) ) { + $attachment['pretext'] = $settings['slack_pretext']; + } + + if ( ! empty( $settings['slack_add_fields'] ) && 'yes' === $settings['slack_add_fields'] ) { + // prepare Form Data + $raw_fields = $record->get( 'fields' ); + $fields = []; + foreach ( $raw_fields as $id => $field ) { + $fields[] = [ + 'title' => $field['title'] ? $field['title'] : $id, + 'value' => $field['value'], + 'short' => false, + ]; + } + + $attachment['fields'] = $fields; + } + + if ( ! empty( $settings['slack_add_ts'] ) && 'yes' === $settings['slack_add_ts'] ) { + $attachment = array_merge( $attachment, [ + 'footer' => sprintf( + /* translators: %s: PRO Elements. */ + esc_html__( 'Powered by %s', 'elementor-pro' ), + 'PRO Elements' + ), + 'footer_icon' => is_ssl() ? ELEMENTOR_ASSETS_URL . 'images/logo-icon.png' : null, + 'ts' => time(), + ] ); + } + + $webhook_data['attachments'] = [ $attachment ]; + + $webhook_data = apply_filters( 'elementor_pro/forms/slack/webhook_args', $webhook_data ); + + $response = wp_safe_remote_post( $settings['slack_webhook'], [ + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'body' => wp_json_encode( $webhook_data ), + ] ); + + if ( 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { + throw new \Exception( 'Webhook error.' ); + } + } +} diff --git a/modules/forms/actions/webhook.php b/modules/forms/actions/webhook.php new file mode 100644 index 00000000..582ea3bf --- /dev/null +++ b/modules/forms/actions/webhook.php @@ -0,0 +1,123 @@ +start_controls_section( + 'section_webhook', + [ + 'label' => esc_html__( 'Webhook', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'webhooks', + [ + 'label' => esc_html__( 'Webhook URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'https://your-webhook-url.com', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'separator' => 'before', + 'description' => esc_html__( 'Enter the integration URL (like Zapier) that will receive the form\'s submitted data.', 'elementor-pro' ), + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $widget->add_control( + 'webhooks_advanced_data', + [ + 'label' => esc_html__( 'Advanced Data', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'render_type' => 'none', + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) {} + + public function run( $record, $ajax_handler ) { + $settings = $record->get( 'form_settings' ); + + if ( empty( $settings['webhooks'] ) ) { + return; + } + + if ( isset( $settings['webhooks_advanced_data'] ) && 'yes' === $settings['webhooks_advanced_data'] ) { + $body['form'] = [ + 'id' => $settings['id'], + 'name' => $settings['form_name'], + ]; + + $body['fields'] = $record->get( 'fields' ); + $body['meta'] = $record->get( 'meta' ); + } else { + $body = $record->get_formatted_data( true ); + $body['form_id'] = $settings['id']; + $body['form_name'] = $settings['form_name']; + } + + $args = [ + 'body' => $body, + ]; + + /** + * Forms webhook request arguments. + * + * Filters the request arguments delivered by the form webhook when executing + * an ajax request. + * + * @since 1.0.0 + * + * @param array $args Webhook request arguments. + * @param Form_Record $record An instance of the form record. + */ + $args = apply_filters( 'elementor_pro/forms/webhooks/request_args', $args, $record ); + + $response = wp_safe_remote_post( $settings['webhooks'], $args ); + + /** + * Elementor form webhook response. + * + * Fires when the webhook response is retrieved by Elementor forms. This hook + * allows developers to add functionality after recieving webhook responses. + * + * @since 1.0.0 + * + * @param \WP_Error|array $response The response or WP_Error on failure. + * @param Form_Record $record An instance of the form record. + */ + do_action( 'elementor_pro/forms/webhooks/response', $response, $record ); + + if ( 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { + throw new \Exception( 'Webhook error.' ); + } + } +} diff --git a/modules/forms/classes/action-base.php b/modules/forms/classes/action-base.php new file mode 100644 index 00000000..202727cd --- /dev/null +++ b/modules/forms/classes/action-base.php @@ -0,0 +1,44 @@ +get_name(); + } + + /** + * @param Form_Record $record + * @param Ajax_Handler $ajax_handler + */ + abstract public function run( $record, $ajax_handler ); + + /** + * @param Form $form + */ + abstract public function register_settings_section( $form ); + + /** + * @param array $element + */ + abstract public function on_export( $element ); +} diff --git a/modules/forms/classes/activecampaign-handler.php b/modules/forms/classes/activecampaign-handler.php new file mode 100644 index 00000000..0b63178c --- /dev/null +++ b/modules/forms/classes/activecampaign-handler.php @@ -0,0 +1,149 @@ +init_rest_client( $api_key, $base_url ); + + if ( ! $this->is_valid_api_key() ) { + throw new \Exception( 'Invalid API key or URL.' ); + } + } + + private function init_rest_client( $api_key, $base_url ) { + $this->api_key = $api_key; + $this->rest_client = new Rest_Client( trailingslashit( $base_url ) . 'admin/api.php' ); + } + + /** + * validate api key + * + * @return bool + * @throws \Exception + */ + private function is_valid_api_key() { + $lists = $this->get_lists(); + + if ( ! empty( $lists ) ) { + return true; + } + + $this->api_key = ''; + + return false; + } + + /** + * get ActiveCampaign lists associated with API key + * @return array + * @throws \Exception + */ + public function get_lists() { + $results = $this->rest_client->get( '?api_action=list_list', [ + 'api_key' => $this->api_key, + 'ids' => 'all', + 'api_output' => 'json', + ] ); + + $lists = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $results['body'] ) ) { + foreach ( $results['body'] as $index => $list ) { + if ( ! is_array( $list ) ) { + continue; + } + + $lists[ $list['id'] ] = $list['name']; + } + } + + $return_array = [ + 'lists' => $lists, + 'fields' => $this->get_fields(), + ]; + + return $return_array; + } + + /** + * get ActiveCampaign custom fields associated with API key + * @return array + * @throws \Exception + */ + private function get_fields() { + $results = $this->rest_client->get( '?api_action=list_field_view', [ + 'api_key' => $this->api_key, + 'ids' => 'all', + 'api_output' => 'json', + ] ); + + $fields = []; + + if ( ! empty( $results['body'] ) ) { + foreach ( $results['body'] as $index => $field ) { + if ( ! is_array( $field ) ) { + continue; + } + $fields[] = [ + 'remote_label' => $field['title'], + 'remote_type' => $this->normalize_type( $field['type'] ), + 'remote_id' => 'field[' . $field['id'] . ',0]', + 'remote_required' => (bool) $field['isrequired'], + ]; + } + } + + return $fields; + } + + private function normalize_type( $type ) { + static $types = [ + 'text' => 'text', + 'number' => 'number', + 'address' => 'text', + 'phone' => 'text', + 'date' => 'text', + 'url' => 'url', + 'imageurl' => 'url', + 'radio' => 'radio', + 'dropdown' => 'select', + 'birthday' => 'text', + 'zip' => 'text', + ]; + + return $types[ $type ]; + } + + /** + * create contact at Activecampaign via api + * + * @param array $subscriber_data + * + * @return array|mixed + * @throws \Exception + */ + public function create_subscriber( $subscriber_data = [] ) { + $end_point = '?api_action=contact_sync&api_key=' . $this->api_key . '&api_output=json'; + + return $this->rest_client->request( 'POST', $end_point, $subscriber_data ); + } +} diff --git a/modules/forms/classes/ajax-handler.php b/modules/forms/classes/ajax-handler.php new file mode 100644 index 00000000..eadbf91d --- /dev/null +++ b/modules/forms/classes/ajax-handler.php @@ -0,0 +1,310 @@ + [], + 'error' => [], + 'admin_error' => [], + ]; + public $data = []; + public $errors = []; + + private $current_form; + + const SUCCESS = 'success'; + const ERROR = 'error'; + const FIELD_REQUIRED = 'required_field'; + const INVALID_FORM = 'invalid_form'; + const SERVER_ERROR = 'server_error'; + const SUBSCRIBER_ALREADY_EXISTS = 'subscriber_already_exists'; + + public static function is_form_submitted() { + // PHPCS - No nonce is required, all visitors may send the form. + return wp_doing_ajax() && isset( $_POST['action'] ) && 'elementor_pro_forms_send_form' === $_POST['action']; // phpcs:ignore WordPress.Security.NonceVerification.Missing + } + + public static function get_default_messages() { + return [ + self::SUCCESS => esc_html__( 'Your submission was successful.', 'elementor-pro' ), + self::ERROR => esc_html__( 'Your submission failed because of an error.', 'elementor-pro' ), + self::FIELD_REQUIRED => esc_html__( 'This field is required.', 'elementor-pro' ), + self::INVALID_FORM => esc_html__( 'Your submission failed because the form is invalid.', 'elementor-pro' ), + self::SERVER_ERROR => esc_html__( 'Your submission failed because of a server error.', 'elementor-pro' ), + self::SUBSCRIBER_ALREADY_EXISTS => esc_html__( 'Subscriber already exists.', 'elementor-pro' ), + ]; + } + + public static function get_default_message( $id, $settings ) { + if ( ! empty( $settings['custom_messages'] ) ) { + $field_id = $id . '_message'; + if ( isset( $settings[ $field_id ] ) ) { + return $settings[ $field_id ]; + } + } + + $default_messages = self::get_default_messages(); + + return isset( $default_messages[ $id ] ) ? $default_messages[ $id ] : esc_html__( 'Unknown error.', 'elementor-pro' ); + } + + public function ajax_send_form() { + $post_data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing + // $post_id that holds the form settings. + $post_id = $post_data['post_id']; + + // $queried_id the post for dynamic values data. + if ( isset( $post_data['queried_id'] ) ) { + $queried_id = $post_data['queried_id']; + } else { + $queried_id = $post_id; + } + + // Make the post as global post for dynamic values. + Plugin::elementor()->db->switch_to_post( $queried_id ); + + $form_id = $post_data['form_id']; + + $elementor = Plugin::elementor(); + $document = $elementor->documents->get( $post_id ); + $form = null; + $template_id = null; + + if ( $document ) { + $form = Module::find_element_recursive( $document->get_elements_data(), $form_id ); + } + + if ( ! empty( $form['templateID'] ) ) { + $template = Plugin::elementor()->documents->get( $form['templateID'] ); + + if ( ! $template ) { + return false; + } + + $template_id = $template->get_id(); + $form = $template->get_elements_data()[0]; + } + + if ( empty( $form ) ) { + $this + ->add_error_message( self::get_default_message( self::INVALID_FORM, [] ) ) + ->send(); + } + + // restore default values + $widget = $elementor->elements_manager->create_element_instance( $form ); + $form['settings'] = $widget->get_settings_for_display(); + $form['settings']['id'] = $form_id; + $form['settings']['form_post_id'] = $template_id ? $template_id : $post_id; + + // TODO: Should be removed if there is an ability to edit "global widgets" + $form['settings']['edit_post_id'] = $post_id; + + $this->current_form = $form; + + if ( empty( $form['settings']['form_fields'] ) ) { + $this + ->add_error_message( self::get_default_message( self::INVALID_FORM, $form['settings'] ) ) + ->send(); + } + + $record = new Form_Record( $post_data['form_fields'], $form ); + + if ( ! $record->validate( $this ) ) { + $this + ->add_error( $record->get( 'errors' ) ) + ->add_error_message( self::get_default_message( self::ERROR, $form['settings'] ) ) + ->send(); + } + + $record->process_fields( $this ); + //check for process errors + if ( ! empty( $this->errors ) ) { + $this->send(); + } + + $module = Module::instance(); + + $actions = $module->actions_registrar->get(); + $errors = array_merge( $this->messages['error'], $this->messages['admin_error'] ); + + /** + * Filters the record before it sent to actions after submit. + * + * @since 3.3.0 + * + * @param Form_Record $record The form record. + * @param Ajax_Handler $this The class that handle the submission of the record + */ + $record = apply_filters( 'elementor_pro/forms/record/actions_before', $record, $this ); + + foreach ( $actions as $action ) { + if ( ! in_array( $action->get_name(), $form['settings']['submit_actions'], true ) ) { + continue; + } + + $exception = null; + + try { + $action->run( $record, $this ); + + $this->handle_bc_errors( $errors ); + } catch ( \Exception $e ) { + $exception = $e; + + // Add an admin error. + if ( ! in_array( $exception->getMessage(), $this->messages['admin_error'], true ) ) { + $this->add_admin_error_message( "{$action->get_label()} {$exception->getMessage()}" ); + } + + // Add a user error. + $this->add_error_message( $this->get_default_message( self::ERROR, $this->current_form['settings'] ) ); + } + + $errors = array_merge( $this->messages['error'], $this->messages['admin_error'] ); + + /** + * After form actions run. + * + * Fires after Elementor forms run actions. This hook allows + * developers to add functionality after certain actions run. + * + * @param Action_Base $action An instance of form action. + * @param \Exception|null $exception An instance of the exception. + */ + do_action( 'elementor_pro/forms/actions/after_run', $action, $exception ); + } + + $activity_log = $module->get_component( 'activity_log' ); + if ( $activity_log ) { + $activity_log->run( $record, $this ); + } + + $cf7db = $module->get_component( 'cf7db' ); + if ( $cf7db ) { + $cf7db->run( $record, $this ); + } + + /** + * New Elementor form record. + * + * Fires before a new form record is sent by ajax. This hook allows + * developers to add functionality before a new form record is sent. + * + * @since 1.0.0 + * + * @param Form_Record $record An instance of the form record. + * @param Ajax_Handler $this An instance of the ajax handler. + */ + do_action( 'elementor_pro/forms/new_record', $record, $this ); + + $this->send(); + } + + public function add_success_message( $message ) { + $this->messages['success'][] = $message; + + return $this; + } + + public function add_response_data( $key, $data ) { + $this->data[ $key ] = $data; + + return $this; + } + + public function add_error_message( $message ) { + $this->messages['error'][] = $message; + $this->set_success( false ); + + return $this; + } + + public function add_error( $field, $message = '' ) { + if ( is_array( $field ) ) { + $this->errors += $field; + } else { + $this->errors[ $field ] = $message; + } + + $this->set_success( false ); + + return $this; + } + + public function add_admin_error_message( $message ) { + $this->messages['admin_error'][] = $message; + $this->set_success( false ); + + return $this; + } + + public function set_success( $bool ) { + $this->is_success = $bool; + + return $this; + } + + public function send() { + if ( $this->is_success ) { + wp_send_json_success( [ + 'message' => $this->get_default_message( self::SUCCESS, $this->current_form['settings'] ), + 'data' => $this->data, + ] ); + } + + if ( empty( $this->messages['error'] ) && ! empty( $this->errors ) ) { + $this->add_error_message( $this->get_default_message( self::INVALID_FORM, $this->current_form['settings'] ) ); + } + + $post_id = Utils::_unstable_get_super_global_value( $_POST, 'post_id' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + + $error_msg = implode( '
      ', $this->messages['error'] ); + if ( current_user_can( 'edit_post', $post_id ) && ! empty( $this->messages['admin_error'] ) ) { + $this->add_admin_error_message( esc_html__( 'This message is not visible to site visitors.', 'elementor-pro' ) ); + $error_msg .= '
      ' . implode( '
      ', $this->messages['admin_error'] ) . '
      '; + } + + wp_send_json_error( [ + 'message' => $error_msg, + 'errors' => $this->errors, + 'data' => $this->data, + ] ); + } + + public function get_current_form() { + return $this->current_form; + } + + /** + * BC: checks if the current action add some errors to the errors array + * if it add an error the "run" method treat it as a failed action. + * + * @param $errors + * + * @throws \Exception + */ + private function handle_bc_errors( $errors ) { + $current_errors = array_merge( $this->messages['error'], $this->messages['admin_error'] ); + $errors_diff = array_diff( $current_errors, $errors ); + + if ( count( $errors_diff ) > 0 ) { + throw new \Exception( implode( ', ', $errors_diff ) ); + } + } + + public function __construct() { + add_action( 'wp_ajax_elementor_pro_forms_send_form', [ $this, 'ajax_send_form' ] ); + add_action( 'wp_ajax_nopriv_elementor_pro_forms_send_form', [ $this, 'ajax_send_form' ] ); + } +} diff --git a/modules/forms/classes/akismet.php b/modules/forms/classes/akismet.php new file mode 100644 index 00000000..87ec9350 --- /dev/null +++ b/modules/forms/classes/akismet.php @@ -0,0 +1,210 @@ +is_akismet_active() ) { + return; + } + + $form->start_controls_section( + 'section_akismet', + [ + 'label' => esc_html__( 'Akismet Spam Protection', 'elementor-pro' ), + ] + ); + + $form->add_control( + 'akismet_enabled', + [ + 'label' => esc_html__( 'Akismet Spam Protection', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $form->add_control( + 'akismet_info', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Assign shortcodes to the fields below to enable spam protection on your form. %1$sShow me how%2$s', 'elementor-pro' ), + '', + '' + ), + 'condition' => [ + 'akismet_enabled' => 'yes', + ], + ] + ); + + $form->add_control( + 'akismet_author', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'e.g. [field id="name"]', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'render_type' => 'none', + 'condition' => [ + 'akismet_enabled' => 'yes', + ], + ] + ); + + $form->add_control( + 'akismet_author_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'e.g. [field id="url"]', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'render_type' => 'none', + 'condition' => [ + 'akismet_enabled' => 'yes', + ], + ] + ); + + $form->add_control( + 'akismet_author_email', + [ + 'label' => esc_html__( 'Email', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'e.g. [field id="email"]', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'render_type' => 'none', + 'condition' => [ + 'akismet_enabled' => 'yes', + ], + ] + ); + + $form->add_control( + 'akismet_content', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => 'e.g. [field id="message"]', + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'render_type' => 'none', + 'condition' => [ + 'akismet_enabled' => 'yes', + ], + ] + ); + + $form->end_controls_section(); + } + + private function is_akismet_active() : bool { + $akismet_key = \Akismet::get_api_key(); + + return ! empty( $akismet_key ); + } + + /** + * @param Form_Record $record + * @param Ajax_Handler $ajax_handler + */ + public function validation( $record, $ajax_handler ) { + if ( ! $this->is_akismet_active() ) { + return; + } + + if ( ! $this->is_spammed( $record ) ) { + return; + } + + $ajax_handler->add_error_message( + esc_html__( 'We couldn’t submit your responses because they seem like spam.', 'elementor-pro' ) + ); + + $ajax_handler->add_error( 'akismet', esc_html__( 'Spam detected', 'elementor-pro' ) ); + } + + private function is_spammed( Form_Record $record ) : bool { + $settings = $record->get( 'form_settings' ); + + if ( empty( $settings['akismet_enabled'] ) ) { + return false; + } + + $params = []; + + $params['comment_author'] = $this->get_parsed_content( $record, $settings['akismet_author'] ); + $params['comment_author_email'] = $this->get_parsed_content( $record, $settings['akismet_author_email'] ); + $params['comment_author_url'] = $this->get_parsed_content( $record, $settings['akismet_author_url'] ); + $params['comment_content'] = $this->get_parsed_content( $record, $settings['akismet_content'] ); + + $params['blog'] = get_option( 'home' ); + $params['blog_lang'] = get_locale(); + $params['blog_charset'] = get_option( 'blog_charset' ); + + $params['user_ip'] = Utils::get_client_ip(); + $params['referrer'] = wp_get_referer(); + + if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) { + $params['user_agent'] = sanitize_textarea_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ); + } + + // http://blog.akismet.com/2012/06/19/pro-tip-tell-us-your-comment_type/ + $params['comment_type'] = 'contact-form'; + + $ignore = [ 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' ]; + foreach ( $_SERVER as $key => $value ) { + if ( ! in_array( $key, $ignore ) && is_string( $value ) ) { + $params[ $key ] = $value; + } + } + + return $this->remote_check_is_spam( $params ); + } + + private function get_parsed_content( $record, $content ) { + $setting = trim( $content ); + + return $record->replace_setting_shortcodes( $setting ); + } + + private function remote_check_is_spam( $params ) { + $response = \Akismet::http_post( _http_build_query( $params, '', '&' ), 'comment-check' ); + + return ( 'true' === $response[1] ); + } +} diff --git a/modules/forms/classes/convertkit-handler.php b/modules/forms/classes/convertkit-handler.php new file mode 100644 index 00000000..590373c6 --- /dev/null +++ b/modules/forms/classes/convertkit-handler.php @@ -0,0 +1,132 @@ +init_rest_client( $api_key ); + + if ( ! $this->is_valid_api_key() ) { + throw new \Exception( 'Invalid API key.' ); + } + } + + private function init_rest_client( $api_key ) { + $this->api_key = $api_key; + $this->rest_client = new Rest_Client( 'https://api.convertkit.com/v3/' ); + } + + /** + * validate api key + * + * @return bool + * @throws \Exception + */ + private function is_valid_api_key() { + $forms = $this->get_forms(); + if ( ! empty( $forms ) ) { + return true; + } + $this->api_key = ''; + + return false; + } + + public function get_forms_and_tags() { + $forms = $this->get_forms(); + $tags = $this->get_tags(); + + return [ + 'data' => [ + 'forms' => $forms['forms'], + 'tags' => $tags['tags'], + ], + ]; + } + + /** + * get GetResponse lists associated with API key + * @return array + * @throws \Exception + */ + public function get_forms() { + $results = $this->rest_client->get( 'forms/?api_key=' . $this->api_key ); + + $forms = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $results['body']['forms'] ) ) { + foreach ( $results['body']['forms'] as $index => $form ) { + if ( ! is_array( $form ) ) { + continue; + } + $forms[ $form['id'] ] = $form['name']; + } + } + + $return_array = [ + 'forms' => $forms, + ]; + + return $return_array; + } + + public function get_tags() { + $results = $this->rest_client->get( 'tags/?api_key=' . $this->api_key ); + + $tags = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $results['body']['tags'] ) ) { + foreach ( $results['body']['tags'] as $index => $tag ) { + if ( ! is_array( $tag ) ) { + continue; + } + $tags[ $tag['id'] ] = $tag['name']; + } + } + + $return_array = [ + 'tags' => $tags, + ]; + + return $return_array; + } + + /** + * create contact at ConvertKit via api + * + * @param array $subscriber_data + * + * @return array|mixed + * @throws \Exception + */ + public function create_subscriber( $form_id, $subscriber_data = [] ) { + $endpoint = sprintf( 'forms/' . $form_id . '/subscribe?api_key=%s', $this->api_key ); + $this->rest_client->add_headers( 'Content-Type', 'application/json' ); + + return $this->rest_client->post( $endpoint, $subscriber_data ); + } +} diff --git a/modules/forms/classes/drip-handler.php b/modules/forms/classes/drip-handler.php new file mode 100644 index 00000000..4d8d45b3 --- /dev/null +++ b/modules/forms/classes/drip-handler.php @@ -0,0 +1,93 @@ +init_rest_client( $api_token ); + if ( ! $this->is_valid_api_token() ) { + throw new \Exception( 'Invalid API key.' ); + } + } + + private function init_rest_client( $api_token ) { + $this->api_token = $api_token; + $this->rest_client = new Rest_Client( 'https://api.getdrip.com/v2/' ); + $this->rest_client->add_headers( [ + 'Authorization' => 'Basic ' . base64_encode( $this->api_token ), + 'Content-Type' => 'application/vnd.api+json', + ] ); + } + + /** + * validate api token + * + * @return bool + * @throws \Exception + */ + private function is_valid_api_token() { + $accounts = $this->get_accounts(); + if ( ! empty( $accounts ) ) { + return true; + } + $this->api_token = ''; + + return false; + } + + /** + * get drip accounts associated with API token + * @return array + * @throws \Exception + */ + public function get_accounts() { + $results = $this->rest_client->get( 'accounts' ); + + $accounts = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $results['body']['accounts'] ) ) { + foreach ( $results['body']['accounts'] as $index => $account ) { + $accounts[ $account['id'] ] = $account['name']; + } + } + + $return_array = [ + 'accounts' => $accounts, + ]; + + return $return_array; + } + + /** + * create subscriber at drip via api + * + * @param string $account_id + * @param array $subscriber_data + * + * @return array|mixed + * @throws \Exception + */ + public function create_subscriber( $account_id = '', $subscriber_data = [] ) { + $end_point = sprintf( '%s/subscribers/', $account_id ); + + return $this->rest_client->post( $end_point, [ 'subscribers' => [ $subscriber_data ] ] ); + } +} diff --git a/modules/forms/classes/form-base.php b/modules/forms/classes/form-base.php new file mode 100644 index 00000000..6e4231a5 --- /dev/null +++ b/modules/forms/classes/form-base.php @@ -0,0 +1,268 @@ +actions_registrar->get(); + + foreach ( $actions as $action ) { + $new_element_data = $action->on_export( $element ); + if ( null !== $new_element_data ) { + $element = $new_element_data; + } + } + + return $element; + } + + public static function get_button_sizes() { + return [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ]; + } + + protected function make_textarea_field( $item, $item_index ) { + $this->add_render_attribute( 'textarea' . $item_index, [ + 'class' => [ + 'elementor-field-textual', + 'elementor-field', + esc_attr( $item['css_classes'] ), + 'elementor-size-' . $item['input_size'], + ], + 'name' => $this->get_attribute_name( $item ), + 'id' => $this->get_attribute_id( $item ), + 'rows' => $item['rows'], + ] ); + + if ( $item['placeholder'] ) { + $this->add_render_attribute( 'textarea' . $item_index, 'placeholder', $item['placeholder'] ); + } + + if ( $item['required'] ) { + $this->add_render_attribute( 'textarea' . $item_index, 'required', 'required' ); + } + + $value = empty( $item['field_value'] ) ? '' : $item['field_value']; + + return ''; + } + + protected function make_select_field( $item, $i ) { + $this->add_render_attribute( + [ + 'select-wrapper' . $i => [ + 'class' => [ + 'elementor-field', + 'elementor-select-wrapper', + 'remove-before', + esc_attr( $item['css_classes'] ), + ], + ], + 'select' . $i => [ + 'name' => $this->get_attribute_name( $item ) . ( ! empty( $item['allow_multiple'] ) ? '[]' : '' ), + 'id' => $this->get_attribute_id( $item ), + 'class' => [ + 'elementor-field-textual', + 'elementor-size-' . $item['input_size'], + ], + ], + ] + ); + + if ( $item['required'] ) { + $this->add_render_attribute( 'select' . $i, 'required', 'required' ); + } + + if ( $item['allow_multiple'] ) { + $this->add_render_attribute( 'select' . $i, 'multiple' ); + if ( ! empty( $item['select_size'] ) ) { + $this->add_render_attribute( 'select' . $i, 'size', $item['select_size'] ); + } + } + + $options = preg_split( "/\\r\\n|\\r|\\n/", $item['field_options'] ); + + if ( ! $options ) { + return ''; + } + + ob_start(); + ?> +
      print_render_attribute_string( 'select-wrapper' . $i ); ?>> +
      + 'eicons', + 'value' => 'eicon-caret-down', + 'position' => 'right', + ]; + Icons_Manager::render_icon( $icon, [ 'aria-hidden' => 'true' ] ); + } + ?> +
      + +
      + '; + foreach ( $options as $key => $option ) { + $element_id = esc_attr( $item['custom_id'] ) . $key; + $html_id = $this->get_attribute_id( $item ) . '-' . $key; + $option_label = $option; + $option_value = $option; + if ( false !== strpos( $option, '|' ) ) { + list( $option_label, $option_value ) = explode( '|', $option ); + } + + $this->add_render_attribute( + $element_id, + [ + 'type' => $type, + 'value' => $option_value, + 'id' => $html_id, + 'name' => $this->get_attribute_name( $item ) . ( ( 'checkbox' === $type && count( $options ) > 1 ) ? '[]' : '' ), + ] + ); + + if ( ! empty( $item['field_value'] ) && $option_value === $item['field_value'] ) { + $this->add_render_attribute( $element_id, 'checked', 'checked' ); + } + + if ( $item['required'] && 'radio' === $type ) { + $this->add_render_attribute( $element_id, 'required', 'required' ); + } + + $html .= 'get_render_attribute_string( $element_id ) . '> '; + } + $html .= '
      '; + } + + return $html; + } + + protected function form_fields_render_attributes( $i, $instance, $item ) { + $this->add_render_attribute( + [ + 'field-group' . $i => [ + 'class' => [ + 'elementor-field-type-' . $item['field_type'], + 'elementor-field-group', + 'elementor-column', + 'elementor-field-group-' . $item['custom_id'], + ], + ], + 'input' . $i => [ + 'type' => $item['field_type'], + 'name' => $this->get_attribute_name( $item ), + 'id' => $this->get_attribute_id( $item ), + 'class' => [ + 'elementor-field', + 'elementor-size-' . $item['input_size'], + empty( $item['css_classes'] ) ? '' : esc_attr( $item['css_classes'] ), + ], + ], + 'label' . $i => [ + 'for' => $this->get_attribute_id( $item ), + 'class' => 'elementor-field-label', + ], + ] + ); + + if ( empty( $item['width'] ) ) { + $item['width'] = '100'; + } + + $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-col-' . $item['width'] ); + + if ( ! empty( $item['width_tablet'] ) ) { + $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-md-' . $item['width_tablet'] ); + } + + if ( $item['allow_multiple'] ) { + $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-field-type-' . $item['field_type'] . '-multiple' ); + } + + if ( ! empty( $item['width_mobile'] ) ) { + $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-sm-' . $item['width_mobile'] ); + } + + // Allow zero as placeholder. + if ( ! Utils::is_empty( $item['placeholder'] ) ) { + $this->add_render_attribute( 'input' . $i, 'placeholder', $item['placeholder'] ); + } + + if ( ! empty( $item['field_value'] ) ) { + $this->add_render_attribute( 'input' . $i, 'value', $item['field_value'] ); + } + + if ( ! $instance['show_labels'] ) { + $this->add_render_attribute( 'label' . $i, 'class', 'elementor-screen-only' ); + } + + if ( ! empty( $item['required'] ) ) { + $class = 'elementor-field-required'; + if ( ! empty( $instance['mark_required'] ) ) { + $class .= ' elementor-mark-required'; + } + $this->add_render_attribute( 'field-group' . $i, 'class', $class ); + $this->add_render_attribute( 'input' . $i, 'required', 'required' ); + } + } + + public function render_plain_content() {} + + public function get_attribute_name( $item ) { + return "form_fields[{$item['custom_id']}]"; + } + + public function get_attribute_id( $item ) { + return 'form-field-' . esc_attr( $item['custom_id'] ); + } +} diff --git a/modules/forms/classes/form-record.php b/modules/forms/classes/form-record.php new file mode 100644 index 00000000..14e3cdaf --- /dev/null +++ b/modules/forms/classes/form-record.php @@ -0,0 +1,347 @@ +fields; + + if ( $with_meta ) { + $fields = array_merge( $fields, $this->meta ); + } + + foreach ( $fields as $key => $field ) { + if ( empty( $field['title'] ) ) { + $formatted[ $no_label . ' ' . $key ] = $field['value']; + } else { + $formatted[ $field['title'] ] = $field['value']; + } + } + + return $formatted; + } + + /** + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + * + * @return bool + */ + public function validate( $ajax_handler ) { + foreach ( $this->fields as $id => $field ) { + $field_type = $field['type']; + if ( ! empty( $field['required'] ) && '' === $field['value'] && 'upload' !== $field_type ) { + $ajax_handler->add_error( $id, Ajax_Handler::get_default_message( Ajax_Handler::FIELD_REQUIRED, $this->form_settings ) ); + } + + /** + * Elementor form field validation. + * + * Fires when a single form field is being validated. This hook allows developers + * to validate individual field types. + * + * The dynamic portion of the hook name, `$field_type`, refers to the field type. + * + * @since 2.0.0 + * + * @param array $field Form field. + * @param Form_Record $this An instance of the form record. + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + */ + do_action( "elementor_pro/forms/validation/{$field_type}", $field, $this, $ajax_handler ); + } + + /** + * Elementor form validation. + * + * Fires when form fields are being validated. This hook allows developers + * to validate all form fields. + * + * @since 2.0.0 + * + * @param Form_Record $this An instance of the form record. + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + */ + do_action( 'elementor_pro/forms/validation', $this, $ajax_handler ); + + return empty( $ajax_handler->errors ); + } + + /** + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + * + */ + public function process_fields( $ajax_handler ) { + foreach ( $this->fields as $id => $field ) { + $field_type = $field['type']; + + /** + * Elementor form field process. + * + * Fires when a single form field is being processed. This hook allows developers + * to process individual field types. + * + * The dynamic portion of the hook name, `$field_type`, refers to the field type. + * + * @since 2.0.0 + * + * @param array $field Form field. + * @param Form_Record $this An instance of the form record. + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + */ + do_action( "elementor_pro/forms/process/{$field_type}", $field, $this, $ajax_handler ); + } + + /** + * Elementor form process. + * + * Fires when form fields are being processed. This hook allows developers + * to process all form fields. + * + * @since 2.0.0 + * + * @param Form_Record $this An instance of the form record. + * @param Ajax_Handler $ajax_handler An instance of the ajax handler. + */ + do_action( 'elementor_pro/forms/process', $this, $ajax_handler ); + } + + public function get( $property ) { + if ( isset( $this->{$property} ) ) { + return $this->{$property}; + } + + return null; + } + + public function set( $property, $value ) { + $this->{$property} = $value; + } + + public function get_form_settings( $setting ) { + if ( isset( $this->form_settings[ $setting ] ) ) { + return $this->form_settings[ $setting ]; + } + + return null; + } + + public function get_field( $args ) { + return wp_list_filter( $this->fields, $args ); + } + + public function remove_field( $id ) { + unset( $this->fields[ $id ] ); + } + + public function update_field( $field_id, $property, $value ) { + if ( ! isset( $this->fields[ $field_id ] ) || ! isset( $this->fields[ $field_id ][ $property ] ) ) { + return; + } + $this->fields[ $field_id ][ $property ] = $value; + } + + public function get_form_meta( $meta_keys = [] ) { + $result = []; + + foreach ( $meta_keys as $metadata_type ) { + switch ( $metadata_type ) { + case 'date': + $result['date'] = [ + 'title' => esc_html__( 'Date', 'elementor-pro' ), + 'value' => date_i18n( get_option( 'date_format' ) ), + ]; + break; + + case 'time': + $result['time'] = [ + 'title' => esc_html__( 'Time', 'elementor-pro' ), + 'value' => date_i18n( get_option( 'time_format' ) ), + ]; + break; + + case 'page_url': + $result['page_url'] = [ + 'title' => esc_html__( 'Page URL', 'elementor-pro' ), + 'value' => isset( $_POST['referrer'] ) ? esc_url_raw( wp_unslash( $_POST['referrer'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing + ]; + break; + + case 'page_title': + $result['page_title'] = [ + 'title' => esc_html__( 'Page Title', 'elementor-pro' ), + 'value' => isset( $_POST['referer_title'] ) ? sanitize_text_field( wp_unslash( $_POST['referer_title'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing + ]; + break; + + case 'user_agent': + $result['user_agent'] = [ + 'title' => esc_html__( 'User Agent', 'elementor-pro' ), + 'value' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_textarea_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '', + ]; + break; + + case 'remote_ip': + $result['remote_ip'] = [ + 'title' => esc_html__( 'Remote IP', 'elementor-pro' ), + 'value' => Utils::get_client_ip(), + ]; + break; + case 'credit': + $result['credit'] = [ + 'title' => esc_html__( 'Powered by', 'elementor-pro' ), + 'value' => esc_html__( 'PRO Elements', 'elementor-pro' ), + ]; + break; + } + } + + return $result; + } + + private function set_meta() { + $form_metadata = $this->form_settings['form_metadata']; + + if ( empty( $form_metadata ) ) { + return; + } + + $this->meta = $this->get_form_meta( $form_metadata ); + } + + private function set_fields() { + foreach ( $this->form_settings['form_fields'] as $form_field ) { + $field = [ + 'id' => $form_field['custom_id'], + 'type' => $form_field['field_type'], + 'title' => $form_field['field_label'], + 'value' => '', + 'raw_value' => '', + 'required' => ! empty( $form_field['required'] ), + ]; + + if ( 'upload' === $field['type'] ) { + $field['file_sizes'] = $form_field['file_sizes'] ?? ''; + $field['file_types'] = $form_field['file_types'] ?? ''; + $field['max_files'] = $form_field['max_files'] ?? ''; + $field['attachment_type'] = $form_field['attachment_type'] ?? ''; + } + + if ( isset( $this->sent_data[ $form_field['custom_id'] ] ) ) { + $field['raw_value'] = $this->sent_data[ $form_field['custom_id'] ]; + + $value = $field['raw_value']; + + if ( is_array( $value ) ) { + $value = implode( ', ', $value ); + } + + $field['value'] = $this->sanitize_field( $field, $value ); + } + $this->fields[ $form_field['custom_id'] ] = $field; + } + } + + private function sanitize_field( $field, $value ) { + $field_type = $field['type']; + switch ( $field_type ) { + case 'text': + case 'password': + case 'hidden': + case 'search': + case 'checkbox': + case 'radio': + case 'select': + $value = sanitize_text_field( $value ); + break; + case 'url': + $value = esc_url_raw( $value ); + break; + case 'textarea': + $value = sanitize_textarea_field( $value ); + break; + case 'email': + $value = sanitize_email( $value ); + break; + default: + /** + * Sanitize field value. + * + * Filters the value of the form field for sanitization purpose. This hook allows + * developers to add custom sanitization for field values. + * + * The dynamic portion of the hook name, `$field_type`, refers to the field type. + * + * @since 1.0.0 + * + * @param string $value The field value. + * @param array $field The field array. + */ + $value = apply_filters( "elementor_pro/forms/sanitize/{$field_type}", $value, $field ); + } + + return $value; + } + + public function replace_setting_shortcodes( $setting, $urlencode = false ) { + // Shortcode can be `[field id="fds21fd"]` or `[field title="Email" id="fds21fd"]`, multiple shortcodes are allowed + return preg_replace_callback( '/(\[field[^]]*id="(\w+)"[^]]*\])/', function( $matches ) use ( $urlencode ) { + $value = ''; + + if ( isset( $this->fields[ $matches[2] ] ) ) { + $value = $this->fields[ $matches[2] ]['value']; + } + + if ( $urlencode ) { + $value = urlencode( $value ); + } + return $value; + }, $setting ); + } + + public function add_file( $id, $index, $filename ) { + if ( ! isset( $this->files[ $id ] ) || ! is_array( $this->files[ $id ] ) ) { + $this->files[ $id ] = [ + 'url' => [], + 'path' => [], + ]; + } + + $attachment_type = $this->fields[ $id ]['attachment_type']; + $this->files[ $id ]['url'][ $index ] = Upload::MODE_ATTACH === $attachment_type ? 'attached' : $filename['url']; + $this->files[ $id ]['path'][ $index ] = $filename['path']; + } + + public function has_field_type( $type ) { + foreach ( $this->fields as $id => $field ) { + if ( $type === $field['field_type'] ) { + return true; + } + } + + return false; + } + + public function __construct( $sent_data, $form ) { + $this->form_type = $form['widgetType']; + $this->form_settings = $form['settings']; + $this->sent_data = stripslashes_deep( $sent_data ); + + $this->set_fields(); + $this->set_meta(); + } +} diff --git a/modules/forms/classes/getresponse-handler.php b/modules/forms/classes/getresponse-handler.php new file mode 100644 index 00000000..59806ab3 --- /dev/null +++ b/modules/forms/classes/getresponse-handler.php @@ -0,0 +1,146 @@ +init_rest_client( $api_key ); + + if ( ! $this->is_valid_api_key() ) { + throw new \Exception( 'Invalid API key.' ); + } + } + + private function init_rest_client( $api_key ) { + $this->api_key = $api_key; + $this->rest_client = new Rest_Client( 'https://api.getresponse.com/v3/' ); + $this->rest_client->add_headers( [ + 'X-Auth-Token' => 'api-key ' . $api_key, + 'Content-Type' => 'application/json', + ] ); + } + + /** + * validate api key + * + * @return bool + * @throws \Exception + */ + private function is_valid_api_key() { + $lists = $this->get_lists(); + if ( ! empty( $lists ) ) { + return true; + } + $this->api_key = ''; + + return false; + } + + /** + * get GetResponse lists associated with API key + * @return array + * @throws \Exception + */ + public function get_lists() { + $results = $this->rest_client->get( 'campaigns' ); + + $lists = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( ! empty( $results['body'] ) ) { + foreach ( $results['body'] as $index => $list ) { + if ( ! is_array( $list ) ) { + continue; + } + $lists[ $list['campaignId'] ] = $list['name']; + } + } + + $return_array = [ + 'lists' => $lists, + ]; + + return $return_array; + } + + public function get_fields() { + $results = $this->rest_client->get( 'custom-fields' ); + + $fields = [ + [ + 'remote_label' => esc_html__( 'Email', 'elementor-pro' ), + 'remote_type' => 'email', + 'remote_id' => 'email', + 'remote_required' => true, + ], + [ + 'remote_label' => esc_html__( 'Name', 'elementor-pro' ), + 'remote_type' => 'text', + 'remote_id' => 'name', + 'remote_required' => false, + ], + ]; + + if ( ! empty( $results['body'] ) ) { + foreach ( $results['body'] as $field ) { + $fields[] = [ + 'remote_label' => $field['name'], + 'remote_type' => $this->normalize_type( $field['type'] ), + 'remote_id' => $field['customFieldId'], + 'remote_required' => false, + ]; + } + } + + $return_array = [ + 'fields' => $fields, + ]; + + return $return_array; + } + + private function normalize_type( $type ) { + static $types = [ + 'text' => 'text', + 'number' => 'number', + 'address' => 'text', + 'phone' => 'text', + 'date' => 'text', + 'url' => 'url', + 'imageurl' => 'url', + 'radio' => 'radio', + 'dropdown' => 'select', + 'single_select' => 'select', + 'textarea' => 'text', + 'birthday' => 'text', + 'zip' => 'text', + 'country' => 'text', + 'gender' => 'text', + ]; + + return $types[ $type ]; + } + + /** + * create contact at GetResponse via api + * + * @param array $subscriber_data + * + * @return array|mixed + * @throws \Exception + */ + public function create_subscriber( $subscriber_data = [] ) { + return $this->rest_client->request( 'POST', 'contacts', wp_json_encode( $subscriber_data ), 202 ); + } +} diff --git a/modules/forms/classes/honeypot-handler.php b/modules/forms/classes/honeypot-handler.php new file mode 100644 index 00000000..268acad3 --- /dev/null +++ b/modules/forms/classes/honeypot-handler.php @@ -0,0 +1,100 @@ +set_render_attribute( 'field-group' . $item_index, 'class', 'elementor-field-type-text' ); + $item['field_label'] = false; + } + + return $item; + } + + /** + * @param string $item + * @param integer $item_index + * @param Widget_Base $widget + */ + public function render_field( $item, $item_index, $widget ) { + $widget->set_render_attribute( 'input' . $item_index, 'type', 'text' ); + $widget->add_render_attribute( 'input' . $item_index, 'style', 'display:none !important;' ); + + echo 'print_render_attribute_string( 'input' . $item_index ); + echo '>'; + } + + /** + * @param Form_Record $record + * @param Ajax_Handler $ajax_handler + */ + public function validation( $record, $ajax_handler ) { + $fields = $record->get_field( [ + 'type' => 'honeypot', + ] ); + + if ( empty( $fields ) ) { + return; + } + + foreach ( $fields as $field ) { + if ( ! empty( $field['value'] ) ) { + $ajax_handler->add_error( 'invalid_form', esc_html__( 'Invalid Form.', 'elementor-pro' ) ); + } else { + // If success - remove the field form list (don't send it in emails and etc ) + $record->remove_field( $field['id'] ); + } + } + + } + + public function update_controls( Widget_Base $widget ) { + $elementor = Plugin::elementor(); + + $control_data = $elementor->controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + foreach ( $control_data['fields'] as $index => $field ) { + if ( 'required' === $field['name'] || 'width' === $field['name'] ) { + $control_data['fields'][ $index ]['conditions']['terms'][] = [ + 'name' => 'field_type', + 'operator' => '!in', + 'value' => [ + 'honeypot', + ], + ]; + } + } + + $widget->update_control( 'form_fields', $control_data ); + } + + public function __construct() { + add_filter( 'elementor_pro/forms/field_types', [ $this, 'add_field_type' ] ); + add_action( 'elementor_pro/forms/render/item', [ $this, 'hide_label' ], 10, 3 ); + add_action( 'elementor_pro/forms/render_field/honeypot', [ $this, 'render_field' ], 10, 3 ); + add_action( 'elementor_pro/forms/validation', [ $this, 'validation' ], 10, 2 ); + add_action( 'elementor/element/form/section_form_fields/before_section_end', [ $this, 'update_controls' ] ); + } +} diff --git a/modules/forms/classes/integration-base.php b/modules/forms/classes/integration-base.php new file mode 100644 index 00000000..f35c0b0f --- /dev/null +++ b/modules/forms/classes/integration-base.php @@ -0,0 +1,75 @@ +', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ); + $alert_type = 'warning'; + } else { + $content = sprintf( + /* translators: 1: Integration label, 2: Link opening tag, 3: Link closing tag. */ + esc_html__( 'You are using %1$s set in the %2$sIntegrations Settings%3$s.', 'elementor-pro' ), + $label, + sprintf( '', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ); + $alert_type = 'info'; + } + + /* translators: %s: Integration label. */ + $content .= ' ' . sprintf( esc_html__( 'You can also set a different %s by choosing "Custom".', 'elementor-pro' ), $label ); + + $widget->add_control( + $id . '_api_key_msg', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => $alert_type, + 'content' => $content, + 'condition' => $condition, + ] + ); + } + + protected function get_fields_map_control_options() { + return []; + } + + final protected function register_fields_map_control( Form $form ) { + $repeater = new Repeater(); + + $repeater->add_control( 'remote_id', [ 'type' => Controls_Manager::HIDDEN ] ); + + $repeater->add_control( 'local_id', [ 'type' => Controls_Manager::SELECT ] ); + + $fields_map_control_options = [ + 'label' => esc_html__( 'Field Mapping', 'elementor-pro' ), + 'type' => Fields_Map::CONTROL_TYPE, + 'separator' => 'before', + 'fields' => $repeater->get_controls(), + ]; + + $fields_map_control_options = array_merge( $fields_map_control_options, $this->get_fields_map_control_options() ); + + $form->add_control( $this->get_name() . '_fields_map', $fields_map_control_options ); + } +} diff --git a/modules/forms/classes/mailchimp-handler.php b/modules/forms/classes/mailchimp-handler.php new file mode 100644 index 00000000..d8b58a55 --- /dev/null +++ b/modules/forms/classes/mailchimp-handler.php @@ -0,0 +1,179 @@ +api_key = $api_key; + $this->api_base_url = 'https://' . $key_parts[1] . '.api.mailchimp.com/3.0/'; + $this->api_request_args = [ + 'headers' => [ + 'Authorization' => 'Basic ' . base64_encode( 'user:' . $this->api_key ), + ], + ]; + } + + public function query( $end_point ) { + $response = wp_safe_remote_get( $this->api_base_url . $end_point, $this->api_request_args ); + + if ( is_wp_error( $response ) || 200 != (int) wp_remote_retrieve_response_code( $response ) ) { + throw new \Exception( 'Mailchimp error.' ); + } + + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + + if ( ! is_array( $body ) ) { + throw new \Exception( 'Mailchimp error.' ); + } + + return $body; + } + + public function post( $end_point, $data, $request_args = [] ) { + $this->api_request_args += $request_args; + $this->api_request_args['headers']['Content-Type'] = 'application/json; charset=utf-8'; + $this->api_request_args['body'] = wp_json_encode( $data ); + $response = wp_safe_remote_post( $this->api_base_url . $end_point, $this->api_request_args ); + + if ( is_wp_error( $response ) ) { + throw new \Exception( 'Mailchimp error.' ); + } + + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + $code = (int) wp_remote_retrieve_response_code( $response ); + + // Throw an exception if there is no response body. + // NOTE: HTTP 204 doesn't have a body. + if ( 204 !== $code && ! is_array( $body ) ) { + throw new \Exception( 'Mailchimp error.' ); + } + + return [ + 'code' => $code, + 'body' => $body, + ]; + } + + public function get_lists() { + $results = $this->query( 'lists?count=999' ); + + $lists = [ + '' => 'Select...', + ]; + + if ( ! empty( $results['lists'] ) ) { + foreach ( $results['lists'] as $list ) { + $lists[ $list['id'] ] = $list['name']; + } + } + + $return_array = [ + 'lists' => $lists, + ]; + + return $return_array; + } + + public function get_groups( $list_id ) { + $results = $this->query( 'lists/' . $list_id . '/interest-categories?count=999' ); + $groups = []; + + if ( ! empty( $results['categories'] ) ) { + foreach ( $results['categories'] as $category ) { + $interests_results = $this->query( 'lists/' . $list_id . '/interest-categories/' . $category['id'] . '/interests?count=999' ); + + foreach ( $interests_results['interests'] as $interest ) { + $groups[ $interest['id'] ] = $category['title'] . ' - ' . $interest['name']; + } + } + } + + $return_array = [ + 'groups' => $groups, + ]; + + return $return_array; + } + + public function get_fields( $list_id ) { + $results = $this->query( 'lists/' . $list_id . '/merge-fields?count=999' ); + + $fields = [ + [ + 'remote_label' => 'Email', + 'remote_type' => 'email', + 'remote_id' => 'email', + 'remote_required' => true, + ], + ]; + + if ( ! empty( $results['merge_fields'] ) ) { + foreach ( $results['merge_fields'] as $field ) { + $fields[] = [ + 'remote_label' => $field['name'], + 'remote_type' => $this->normalize_type( $field['type'] ), + 'remote_id' => $field['tag'], + 'remote_required' => $field['required'], + ]; + } + } + + $return_array = [ + 'fields' => $fields, + ]; + + return $return_array; + } + + public function get_list_details( $list_id ) { + $groups = $this->get_groups( $list_id ); + $fields = $this->get_fields( $list_id ); + + return [ + 'list_details' => $groups + $fields, + ]; + } + + private function normalize_type( $type ) { + static $types = [ + 'text' => 'text', + 'number' => 'number', + 'address' => 'text', + 'phone' => 'text', + 'date' => 'text', + 'url' => 'url', + 'imageurl' => 'url', + 'radio' => 'radio', + 'dropdown' => 'select', + 'birthday' => 'text', + 'zip' => 'text', + ]; + + return $types[ $type ]; + } +} diff --git a/modules/forms/classes/mailerlite-handler.php b/modules/forms/classes/mailerlite-handler.php new file mode 100644 index 00000000..89921931 --- /dev/null +++ b/modules/forms/classes/mailerlite-handler.php @@ -0,0 +1,123 @@ +init_rest_client( $api_key ); + if ( ! $this->is_valid_api_key() ) { + throw new \Exception( 'Invalid API key.' ); + } + } + + private function init_rest_client( $api_key ) { + $this->api_key = $api_key; + $this->rest_client = new Rest_Client( 'https://api.mailerlite.com/api/v2/' ); + $this->rest_client->add_headers( [ + 'X-MailerLite-ApiKey' => $api_key, + 'Content-Type' => 'application/json', + ] ); + } + + /** + * validate api key + * + * @return bool + * @throws \Exception + */ + private function is_valid_api_key() { + $groups = $this->rest_client->get( 'groups' ); + if ( ! empty( $groups ) ) { + return true; + } + $this->api_key = ''; + + return false; + } + + /** + * get MailerLite groups associated with API key + * @return array + * @throws \Exception + */ + public function get_groups() { + $results = $this->rest_client->get( 'groups' ); + + $groups = [ + '' => esc_html__( 'Select...', 'elementor-pro' ), + ]; + + if ( 200 === $results['code'] ) { + foreach ( $results['body'] as $index => $group ) { + $groups[ $group['id'] ] = $group['name']; + } + } + + $return_array = [ + 'groups' => $groups, + 'fields' => $this->get_fields(), + ]; + + return $return_array; + } + + /** + * get MailerLite fields associated with API key + * @return array + * @throws \Exception + */ + public function get_fields() { + $results = $this->rest_client->get( 'fields' ); + + $fields = []; + if ( ! empty( $results['body'] ) ) { + foreach ( $results['body'] as $index => $field ) { + if ( ! is_array( $field ) || empty( $field['date_updated'] ) ) { + continue; + } + $fields[] = [ + 'remote_label' => $field['title'], + 'remote_type' => strtolower( $field['type'] ), + 'remote_id' => $field['key'], + 'remote_required' => false, + ]; + } + } + + return $fields; + } + + /** + * create subscriber at drip via api + * + * @param string $group + * @param array $subscriber_data + * + * @return array|mixed + * @throws \Exception + */ + public function create_subscriber( $group = '', $subscriber_data = [] ) { + $end_point = sprintf( 'groups/%s/subscribers', $group ); + + return $this->rest_client->post( $end_point, $subscriber_data ); + } +} diff --git a/modules/forms/classes/recaptcha-handler.php b/modules/forms/classes/recaptcha-handler.php new file mode 100644 index 00000000..fbfc694a --- /dev/null +++ b/modules/forms/classes/recaptcha-handler.php @@ -0,0 +1,301 @@ + Elementor > Settings > Integrations > reCAPTCHA.', 'elementor-pro' ); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, static::get_recaptcha_name(), [ + 'label' => esc_html__( 'reCAPTCHA', 'elementor-pro' ), + 'callback' => function () { + echo sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( '%1$sreCAPTCHA%2$s is a free service by Google that protects your website from spam and abuse. It does this while letting your valid users pass through with ease.', 'elementor-pro' ), + '', + '' + ); + }, + 'fields' => [ + 'pro_recaptcha_site_key' => [ + 'label' => esc_html__( 'Site Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + ], + ], + 'pro_recaptcha_secret_key' => [ + 'label' => esc_html__( 'Secret Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + ], + ], + ], + ] ); + } + + public function localize_settings( $settings ) { + $settings = array_replace_recursive( $settings, [ + 'forms' => [ + static::get_recaptcha_name() => [ + 'enabled' => static::is_enabled(), + 'type' => static::get_recaptcha_type(), + 'site_key' => static::get_site_key(), + 'setup_message' => static::get_setup_message(), + ], + ], + ] ); + + return $settings; + } + + protected static function get_script_render_param() { + return 'explicit'; + } + + protected static function get_script_name() { + return 'elementor-' . static::get_recaptcha_name() . '-api'; + } + + public function register_scripts() { + $script_name = static::get_script_name(); + $src = 'https://www.google.com/recaptcha/api.js?render=explicit'; + wp_register_script( $script_name, $src, [], ELEMENTOR_PRO_VERSION, true ); + } + + public function enqueue_scripts() { + if ( Plugin::elementor()->preview->is_preview_mode() ) { + return; + } + $script_name = static::get_script_name(); + wp_enqueue_script( $script_name ); + } + + /** + * @param Form_Record $record + * @param Ajax_Handler $ajax_handler + */ + public function validation( $record, $ajax_handler ) { + $fields = $record->get_field( [ + 'type' => static::get_recaptcha_name(), + ] ); + + if ( empty( $fields ) ) { + return; + } + + $field = current( $fields ); + + // PHPCS - response protected by recaptcha secret + $recaptcha_response = Utils::_unstable_get_super_global_value( $_POST, 'g-recaptcha-response' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + + if ( empty( $recaptcha_response ) ) { + $ajax_handler->add_error( $field['id'], esc_html__( 'The Captcha field cannot be blank. Please enter a value.', 'elementor-pro' ) ); + + return; + } + + $recaptcha_errors = [ + 'missing-input-secret' => esc_html__( 'The secret parameter is missing.', 'elementor-pro' ), + 'invalid-input-secret' => esc_html__( 'The secret parameter is invalid or malformed.', 'elementor-pro' ), + 'missing-input-response' => esc_html__( 'The response parameter is missing.', 'elementor-pro' ), + 'invalid-input-response' => esc_html__( 'The response parameter is invalid or malformed.', 'elementor-pro' ), + ]; + + $recaptcha_secret = static::get_secret_key(); + $client_ip = Utils::get_client_ip(); + + $request = [ + 'body' => [ + 'secret' => $recaptcha_secret, + 'response' => $recaptcha_response, + 'remoteip' => $client_ip, + ], + ]; + + $response = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $request ); + + $response_code = wp_remote_retrieve_response_code( $response ); + + if ( 200 !== (int) $response_code ) { + /* translators: %d: Response code. */ + $ajax_handler->add_error( $field['id'], sprintf( esc_html__( 'Can not connect to the reCAPTCHA server (%d).', 'elementor-pro' ), $response_code ) ); + + return; + } + + $body = wp_remote_retrieve_body( $response ); + + $result = json_decode( $body, true ); + + if ( ! $this->validate_result( $result, $field ) ) { + $message = esc_html__( 'Invalid form, reCAPTCHA validation failed.', 'elementor-pro' ); + + if ( isset( $result['error-codes'] ) ) { + $result_errors = array_flip( $result['error-codes'] ); + + foreach ( $recaptcha_errors as $error_key => $error_desc ) { + if ( isset( $result_errors[ $error_key ] ) ) { + $message = $recaptcha_errors[ $error_key ]; + break; + } + } + } + + $this->add_error( $ajax_handler, $field, $message ); + + } + + // If success - remove the field form list (don't send it in emails and etc ) + $record->remove_field( $field['id'] ); + + } + + /** + * @param Ajax_Handler $ajax_handler + * @param $field + * @param $message + */ + protected function add_error( $ajax_handler, $field, $message ) { + $ajax_handler->add_error( $field['id'], $message ); + } + + protected function validate_result( $result, $field ) { + if ( ! $result['success'] ) { + return false; + } + + return true; + } + + /** + * @param $item + * @param $item_index + * @param $widget Widget_Base + */ + public function render_field( $item, $item_index, $widget ) { + $recaptcha_html = '
      '; + + $recaptcha_name = static::get_recaptcha_name(); + + if ( static::is_enabled() ) { + $this->enqueue_scripts(); + $this->add_render_attributes( $item, $item_index, $widget ); + $recaptcha_html .= '
      get_render_attribute_string( $recaptcha_name . $item_index ) . '>
      '; + } elseif ( current_user_can( 'manage_options' ) ) { + $recaptcha_html .= '
      '; + $recaptcha_html .= static::get_setup_message(); + $recaptcha_html .= '
      '; + } + + $recaptcha_html .= '
      '; + + // PHPCS - It's all escaped + echo $recaptcha_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + /** + * @param $item + * @param $item_index + * @param $widget Widget_Base + */ + protected function add_render_attributes( $item, $item_index, $widget ) { + $recaptcha_name = static::get_recaptcha_name(); + + $widget->add_render_attribute( [ + $recaptcha_name . $item_index => [ + 'class' => 'elementor-g-recaptcha', + 'data-sitekey' => static::get_site_key(), + 'data-type' => static::get_recaptcha_type(), + ], + ] ); + + $this->add_version_specific_render_attributes( $item, $item_index, $widget ); + } + + /** + * @param $item + * @param $item_index + * @param $widget Widget_Base + */ + protected function add_version_specific_render_attributes( $item, $item_index, $widget ) { + $recaptcha_name = static::get_recaptcha_name(); + $widget->add_render_attribute( $recaptcha_name . $item_index, [ + 'data-theme' => $item['recaptcha_style'], + 'data-size' => $item['recaptcha_size'], + ] ); + } + + public function add_field_type( $field_types ) { + $field_types['recaptcha'] = esc_html__( 'reCAPTCHA', 'elementor-pro' ); + + return $field_types; + } + + public function filter_field_item( $item ) { + if ( static::get_recaptcha_name() === $item['field_type'] ) { + $item['field_label'] = false; + } + + return $item; + } + + public function __construct() { + $this->register_scripts(); + + add_filter( 'elementor_pro/forms/field_types', [ $this, 'add_field_type' ] ); + add_action( 'elementor_pro/forms/render_field/' . static::get_recaptcha_name(), [ $this, 'render_field' ], 10, 3 ); + add_filter( 'elementor_pro/forms/render/item', [ $this, 'filter_field_item' ] ); + add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'localize_settings' ] ); + + if ( static::is_enabled() ) { + add_action( 'elementor_pro/forms/validation', [ $this, 'validation' ], 10, 2 ); + add_action( 'elementor/preview/enqueue_scripts', [ $this, 'enqueue_scripts' ] ); + } + + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ] ); + } + } +} diff --git a/modules/forms/classes/recaptcha-v3-handler.php b/modules/forms/classes/recaptcha-v3-handler.php new file mode 100644 index 00000000..c7d3680b --- /dev/null +++ b/modules/forms/classes/recaptcha-v3-handler.php @@ -0,0 +1,152 @@ + $threshold || 1 < $threshold ) { + return self::V3_DEFAULT_THRESHOLD; + } + return $threshold; + } + + public static function is_enabled() { + return static::get_site_key() && static::get_secret_key(); + } + + public static function get_setup_message() { + return esc_html__( 'To use reCAPTCHA V3, you need to add the API Key and complete the setup process in Dashboard > Elementor > Settings > Integrations > reCAPTCHA V3.', 'elementor-pro' ); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'recaptcha_v3', [ + 'label' => esc_html__( 'reCAPTCHA V3', 'elementor-pro' ), + 'callback' => function() { + echo sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( '%1$sreCAPTCHA V3%2$s is a free service by Google that protects your website from spam and abuse. It does this while letting your valid users pass through with ease.', 'elementor-pro' ), + '', + '' + ); + }, + 'fields' => [ + 'pro_recaptcha_v3_site_key' => [ + 'label' => esc_html__( 'Site Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + ], + ], + 'pro_recaptcha_v3_secret_key' => [ + 'label' => esc_html__( 'Secret Key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + ], + ], + 'pro_recaptcha_v3_threshold' => [ + 'label' => esc_html__( 'Score Threshold', 'elementor-pro' ), + 'field_args' => [ + 'attributes' => [ + 'min' => 0, + 'max' => 1, + 'placeholder' => '0.5', + 'step' => '0.1', + ], + 'std' => 0.5, + 'type' => 'number', + 'desc' => esc_html__( 'Score threshold should be a value between 0 and 1, default: 0.5', 'elementor-pro' ), + ], + ], + ], + ] ); + } + + /** + * @param $item + * @param $item_index + * @param $widget Widget_Base + */ + protected function add_version_specific_render_attributes( $item, $item_index, $widget ) { + $recaptcha_name = static::get_recaptcha_name(); + $widget->add_render_attribute( $recaptcha_name . $item_index, [ + 'data-action' => self::V3_DEFAULT_ACTION, + 'data-badge' => $item['recaptcha_badge'], + 'data-size' => 'invisible', + ] ); + } + + /** + * @param Ajax_Handler $ajax_handler + * @param $field + * @param $message + */ + protected function add_error( $ajax_handler, $field, $message ) { + parent::add_error( $ajax_handler, $field, $message ); + $ajax_handler->add_error_message( esc_html__( 'reCAPTCHA V3 validation failed, suspected as abusive usage', 'elementor-pro' ) ); + } + + protected function validate_result( $result, $field ) { + $action = self::V3_DEFAULT_ACTION; + $action_ok = ! isset( $result['action'] ) ? true : $action === $result['action']; + return $action_ok && ( $result['score'] > self::get_recaptcha_threshold() ); + } + + public function add_field_type( $field_types ) { + $field_types['recaptcha_v3'] = esc_html__( 'reCAPTCHA V3', 'elementor-pro' ); + + return $field_types; + } + + /** + * @param $item + * @param $item_index + * @param Widget_Base $widget + * + * @return $item + */ + public function filter_recaptcha_item( $item, $item_index, $widget ) { + $widget->add_render_attribute( 'field-group' . $item_index, 'class', [ + self::get_recaptcha_name() . '-' . $item['recaptcha_badge'], + ] ); + + return $item; + } + + public function __construct() { + parent::__construct(); + add_filter( 'elementor_pro/forms/render/item/' . self::get_recaptcha_name(), [ $this, 'filter_recaptcha_item' ], 10, 3 ); + } +} diff --git a/modules/forms/classes/rest-client.php b/modules/forms/classes/rest-client.php new file mode 100644 index 00000000..b773fa1c --- /dev/null +++ b/modules/forms/classes/rest-client.php @@ -0,0 +1,170 @@ +api_base_url = $rest_base_url; + //setup defaults + $this->set_request_arg( 'timeout', 30 ) + ->set_request_arg( 'sslverify', false ) + ->add_headers( 'User-Agent', $this->user_agent ); + + /** + * Initiate Elementor form REST API client. + * + * Fires when Elementor forms are initiated on REST API client. + * + * @since 2.4.0 + * + * @param Rest_Client $this An instance of form REST API client. + */ + do_action( 'elementor-pro/forms/rest_client/init', $this ); + + return $this; + } + + /** + * Set REST API base url. + * + * @param string $url + */ + public function set_base_url( $url ) { + $this->api_base_url = $url; + } + + /** + * Get REST API base url. + * + * @return string + */ + public function get_base_url() { + return $this->api_base_url; + } + + /** + * Add headers to REST API. + * + * @param $key Header key. + * @param $value Optional. Header value. Default is null. + * + * @return $this An instance of REST API client. + */ + public function add_headers( $key, $value = null ) { + if ( ! is_array( $key ) ) { + $this->headers[ $key ] = $value; + + return $this; + } + foreach ( $key as $header => $header_value ) { + $this->headers[ $header ] = $header_value; + } + + return $this; + } + + /** + * Set REST API request arguments. + * + * @param string $name Optional. Request argument name. Default is ''. + * @param null $value Optional. Request argument value. Default is null. + * + * @return $this An instance of REST API client. + */ + public function set_request_arg( $name = '', $value = null ) { + $this->request_args[ $name ] = $value; + + return $this; + } + + /** + * @uses request + * + * @param string $endpoint Optional. Default is ''. + * @param null $data Optional. Default is null. + * + * @return array|mixed + * @throws \Exception + */ + public function post( $endpoint = '', $data = null ) { + $request_body = wp_json_encode( $data ); + + return $this->request( 'POST', $endpoint, $request_body ); + } + + /** + * @uses request + * + * @param string $endpoint Optional. Default is ''. + * @param null $data Optional. Default is null. + * + * @return array|mixed + * @throws \Exception + */ + public function get( $endpoint = '', $data = null ) { + return $this->request( 'GET', $endpoint, $data ); + } + + /** + * @param string $method Optional. Default is 'GET'. + * @param string $endpoint Optional. Default is ''. + * @param null $request_body Optional. Default is null. + * @param int $valid_response_code Optional. Default is '200'. + * + * @return array + * @throws \Exception + */ + public function request( $method = 'GET', $endpoint = '', $request_body = null, $valid_response_code = 200 ) { + $request_url = $this->api_base_url . $endpoint; + $base_args = [ + 'method' => $method, + 'headers' => $this->headers, + ]; + $api_request_args = array_merge( $base_args, $this->request_args ); + if ( null !== $request_body ) { + if ( in_array( $method, [ 'POST', 'PUT' ] ) ) { + $api_request_args['body'] = $request_body; + } else { + $request_url = add_query_arg( $request_body, $request_url ); + } + } + + $cache_key = md5( $method . $endpoint . json_encode( $api_request_args ) ); + if ( isset( $this->request_cache[ $cache_key ] ) && isset( $this->request_cache[ $cache_key ]['parsed'] ) ) { + $this->request_cache[ $cache_key ]['parsed']; + } + + $response = wp_safe_remote_request( $request_url, $api_request_args ); + $response_code = (int) wp_remote_retrieve_response_code( $response ); + + $this->request_cache[ $cache_key ]['raw'] = $response; + + if ( is_wp_error( $response ) || $valid_response_code !== $response_code ) { + throw new \Exception( "Rest Client Error: response code {$response_code}." ); + } + + $response_body = json_decode( wp_remote_retrieve_body( $response ), true ); + + if ( ! is_array( $response_body ) ) { + throw new \Exception( 'Rest Client Error: unexpected response type.' ); + } + + $return = [ + 'code' => $response_code, + 'body' => $response_body, + ]; + $this->request_cache[ $cache_key ]['parsed'] = $return; + + return $return; + } +} diff --git a/modules/forms/controls/fields-map.php b/modules/forms/controls/fields-map.php new file mode 100644 index 00000000..677fb66c --- /dev/null +++ b/modules/forms/controls/fields-map.php @@ -0,0 +1,45 @@ + 'none', + 'fields' => [ + [ + 'name' => 'remote_id', + 'type' => Controls_Manager::HIDDEN, + ], + [ + 'name' => 'local_id', + 'type' => Controls_Manager::SELECT, + ], + ], + ] ); + } +} diff --git a/modules/forms/controls/fields-repeater.php b/modules/forms/controls/fields-repeater.php new file mode 100644 index 00000000..d377bd56 --- /dev/null +++ b/modules/forms/controls/fields-repeater.php @@ -0,0 +1,18 @@ +controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'acceptance_text' => [ + 'name' => 'acceptance_text', + 'label' => esc_html__( 'Acceptance Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'checked_by_default' => [ + 'name' => 'checked_by_default', + 'label' => esc_html__( 'Checked by Default', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + $widget->update_control( 'form_fields', $control_data ); + } + + public function render( $item, $item_index, $form ) { + $label = ''; + $form->add_render_attribute( 'input' . $item_index, 'class', 'elementor-acceptance-field' ); + $form->add_render_attribute( 'input' . $item_index, 'type', 'checkbox', true ); + + if ( ! empty( $item['acceptance_text'] ) ) { + $label = ''; + } + + if ( ! empty( $item['checked_by_default'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'checked', 'checked' ); + } + + ?> +
      + + print_render_attribute_string( 'input' . $item_index ); ?>> + + +
      + add_render_attribute( 'input' . $item_index, 'class', 'elementor-field-textual elementor-date-field' ); + $form->add_render_attribute( 'input' . $item_index, 'pattern', '[0-9]{4}-[0-9]{2}-[0-9]{2}' ); + if ( isset( $item['use_native_date'] ) && 'yes' === $item['use_native_date'] ) { + $form->add_render_attribute( 'input' . $item_index, 'class', 'elementor-use-native' ); + } + + if ( ! empty( $item['min_date'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'min', esc_attr( $item['min_date'] ) ); + } + + if ( ! empty( $item['max_date'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'max', esc_attr( $item['max_date'] ) ); + } + ?> + + print_render_attribute_string( 'input' . $item_index ); ?>> + controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'min_date' => [ + 'name' => 'min_date', + 'label' => esc_html__( 'Min. Date', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'label_block' => false, + 'picker_options' => [ + 'enableTime' => false, + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'max_date' => [ + 'name' => 'max_date', + 'label' => esc_html__( 'Max. Date', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'label_block' => false, + 'picker_options' => [ + 'enableTime' => false, + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'use_native_date' => [ + 'name' => 'use_native_date', + 'label' => esc_html__( 'Native HTML5', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + foreach ( $control_data['fields'] as $index => $field ) { + if ( 'placeholder' !== $field['name'] ) { + continue; + } + foreach ( $field['conditions']['terms'] as $condition_index => $terms ) { + if ( ! isset( $terms['name'] ) || 'field_type' !== $terms['name'] || ! isset( $terms['operator'] ) || 'in' !== $terms['operator'] ) { + continue; + } + $control_data['fields'][ $index ]['conditions']['terms'][ $condition_index ]['value'][] = $this->get_type(); + break; + } + break; + } + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + $widget->update_control( 'form_fields', $control_data ); + } +} diff --git a/modules/forms/fields/field-base.php b/modules/forms/fields/field-base.php new file mode 100644 index 00000000..56c9ed60 --- /dev/null +++ b/modules/forms/fields/field-base.php @@ -0,0 +1,112 @@ +get_type(); + } + + abstract public function render( $item, $item_index, $form ); + + public function validation( $field, Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) {} + + public function process_field( $field, Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) {} + + public function add_assets_depends( $form ) { + foreach ( $this->get_script_depends() as $script ) { + wp_enqueue_script( $script ); + } + + foreach ( $this->get_style_depends() as $style ) { + wp_enqueue_style( $style ); + } + } + + public function get_script_depends(): array { + return (array) $this->depended_scripts; + } + + public function get_style_depends(): array { + return (array) $this->depended_styles; + } + + public function add_preview_depends() { + foreach ( $this->get_script_depends() as $script ) { + wp_enqueue_script( $script ); + } + + foreach ( $this->get_style_depends() as $style ) { + wp_enqueue_style( $style ); + } + } + + public function add_field_type( $field_types ) { + if ( ! in_array( $this->get_type(), $field_types ) ) { + $field_types[ $this->get_type() ] = $this->get_name(); + } + + return $field_types; + } + + public function field_render( $item, $item_index, $form ) { + $this->add_assets_depends( $form ); + $this->render( $item, $item_index, $form ); + } + + public function sanitize_field( $value, $field ) { + return sanitize_text_field( $value ); + } + + public function inject_field_controls( $array, $controls_to_inject ) { + $keys = array_keys( $array ); + $key_index = array_search( 'required', $keys ) + 1; + + return array_merge( array_slice( $array, 0, $key_index, true ), + $controls_to_inject, + array_slice( $array, $key_index, null, true ) + ); + } + + public function __construct() { + $field_type = $this->get_type(); + add_action( "elementor_pro/forms/render_field/{$field_type}", [ $this, 'field_render' ], 10, 3 ); + add_action( "elementor_pro/forms/validation/{$field_type}", [ $this, 'validation' ], 10, 3 ); + add_action( "elementor_pro/forms/process/{$field_type}", [ $this, 'process_field' ], 10, 3 ); + add_filter( 'elementor_pro/forms/field_types', [ $this, 'add_field_type' ] ); + add_filter( "elementor_pro/forms/sanitize/{$field_type}", [ $this, 'sanitize_field' ], 10, 2 ); + add_action( 'elementor/preview/enqueue_scripts', [ $this, 'add_preview_depends' ] ); + if ( method_exists( $this, 'update_controls' ) ) { + add_action( 'elementor/element/form/section_form_fields/before_section_end', [ $this, 'update_controls' ] ); + } + } +} diff --git a/modules/forms/fields/number.php b/modules/forms/fields/number.php new file mode 100644 index 00000000..6aa356d8 --- /dev/null +++ b/modules/forms/fields/number.php @@ -0,0 +1,95 @@ +add_render_attribute( 'input' . $item_index, 'class', 'elementor-field-textual' ); + + if ( isset( $item['field_min'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'min', esc_attr( $item['field_min'] ) ); + } + if ( isset( $item['field_max'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'max', esc_attr( $item['field_max'] ) ); + } + + ?> + print_render_attribute_string( 'input' . $item_index ); ?> > + controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'field_min' => [ + 'name' => 'field_min', + 'label' => esc_html__( 'Min. Value', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'field_max' => [ + 'name' => 'field_max', + 'label' => esc_html__( 'Max. Value', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + $widget->update_control( 'form_fields', $control_data ); + } + + public function validation( $field, Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) { + + if ( ! empty( $field['field_max'] ) && $field['field_max'] < (int) $field['value'] ) { + /* translators: %s: The value of max field. */ + $ajax_handler->add_error( $field['id'], sprintf( esc_html__( 'The field value must be less than or equal to %s.', 'elementor-pro' ), $field['field_max'] ) ); + } + + if ( ! empty( $field['field_min'] ) && $field['field_min'] > (int) $field['value'] ) { + /* translators: %s: The value of min field. */ + $ajax_handler->add_error( $field['id'], sprintf( esc_html__( 'The field value must be greater than or equal to %s.', 'elementor-pro' ), $field['field_min'] ) ); + } + } + + public function sanitize_field( $value, $field ) { + return intval( $value ); + } +} diff --git a/modules/forms/fields/step.php b/modules/forms/fields/step.php new file mode 100644 index 00000000..684dde42 --- /dev/null +++ b/modules/forms/fields/step.php @@ -0,0 +1,133 @@ +experiments->is_feature_active( 'e_font_icon_svg' ) && $item['selected_icon']['value'] ) { + if ( 'svg' === $item['selected_icon']['library'] ) { + $font_icon = Icons_Manager::render_uploaded_svg_icon( $item['selected_icon']['value'] ); + } else { + $font_icon = Icons_Manager::render_font_icon( $item['selected_icon'] ); + } + } + + $form->add_render_attribute( 'step' . $item_index, [ + 'class' => 'e-field-step elementor-hidden', + 'data-label' => $item['field_label'], + 'data-previousButton' => $item['previous_button'], + 'data-nextButton' => $item['next_button'], + 'data-iconUrl' => 'svg' === $item['selected_icon']['library'] && $item['selected_icon']['value'] ? $item['selected_icon']['value']['url'] : '', + 'data-iconLibrary' => 'svg' !== $item['selected_icon']['library'] && $item['selected_icon']['value'] ? $item['selected_icon']['value'] : '', + 'data-icon' => $font_icon, + ] ); + + ?> +
      print_render_attribute_string( 'step' . $item_index ); ?> >
      + + controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'previous_button' => [ + 'name' => 'previous_button', + 'label' => esc_html__( 'Previous Button', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'next_button' => [ + 'name' => 'next_button', + 'label' => esc_html__( 'Next Button', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'selected_icon' => [ + 'name' => 'selected_icon', + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'description' => esc_html__( 'Visible only if selected step type contains "Icon"', 'elementor-pro' ), + 'default' => [ + 'value' => 'fas fa-star', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-down', + 'angle-down', + 'angle-double-down', + 'caret-down', + 'caret-square-down', + ], + 'fa-regular' => [ + 'caret-square-down', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + $widget->update_control( 'form_fields', $control_data ); + } +} diff --git a/modules/forms/fields/tel.php b/modules/forms/fields/tel.php new file mode 100644 index 00000000..eab80064 --- /dev/null +++ b/modules/forms/fields/tel.php @@ -0,0 +1,38 @@ +add_render_attribute( 'input' . $item_index, 'class', 'elementor-field-textual' ); + $form->add_render_attribute( 'input' . $item_index, 'pattern', '[0-9()#&+*-=.]+' ); + $form->add_render_attribute( 'input' . $item_index, 'title', esc_html__( 'Only numbers and phone characters (#, -, *, etc) are accepted.', 'elementor-pro' ) ); + ?> + print_render_attribute_string( 'input' . $item_index ); ?>> + + add_error( $field['id'], esc_html__( 'The field accepts only numbers and phone characters (#, -, *, etc).', 'elementor-pro' ) ); + } + } +} diff --git a/modules/forms/fields/time.php b/modules/forms/fields/time.php new file mode 100644 index 00000000..4bc89ab9 --- /dev/null +++ b/modules/forms/fields/time.php @@ -0,0 +1,91 @@ +controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'use_native_time' => [ + 'name' => 'use_native_time', + 'label' => esc_html__( 'Native HTML5', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + foreach ( $control_data['fields'] as $index => $field ) { + if ( 'placeholder' !== $field['name'] ) { + continue; + } + foreach ( $field['conditions']['terms'] as $condition_index => $terms ) { + if ( ! isset( $terms['name'] ) || 'field_type' !== $terms['name'] || ! isset( $terms['operator'] ) || 'in' !== $terms['operator'] ) { + continue; + } + $control_data['fields'][ $index ]['conditions']['terms'][ $condition_index ]['value'][] = $this->get_type(); + break; + } + break; + } + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + + $widget->update_control( 'form_fields', $control_data ); + } + + public function render( $item, $item_index, $form ) { + $form->add_render_attribute( 'input' . $item_index, 'class', 'elementor-field-textual elementor-time-field' ); + if ( isset( $item['use_native_time'] ) && 'yes' === $item['use_native_time'] ) { + $form->add_render_attribute( 'input' . $item_index, 'class', 'elementor-use-native' ); + } + ?> + print_render_attribute_string( 'input' . $item_index ); ?>> + add_error( $field['id'], esc_html__( 'The field should be in HH:MM format.', 'elementor-pro' ) ); + } + } +} diff --git a/modules/forms/fields/upload.php b/modules/forms/fields/upload.php new file mode 100644 index 00000000..79ecaa31 --- /dev/null +++ b/modules/forms/fields/upload.php @@ -0,0 +1,543 @@ +controls_manager->get_control_from_stack( $widget->get_unique_name(), 'form_fields' ); + + if ( is_wp_error( $control_data ) ) { + return; + } + + $field_controls = [ + 'attachment_type' => [ + 'name' => 'attachment_type', + 'label' => esc_html__( 'Send files', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'options' => [ + self::MODE_LINK => esc_html__( 'Email with link', 'elementor-pro' ), + self::MODE_ATTACH => esc_html__( 'Email with attachment', 'elementor-pro' ), + self::MODE_BOTH => esc_html__( 'Email with both', 'elementor-pro' ), + ], + 'default' => self::MODE_LINK, + 'description' => esc_html__( "Uploads you receive via link are stored on your server. However, uploads via attachment won't be saved on your server, and under Submissions", 'elementor-pro' ), + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'file_sizes' => [ + 'name' => 'file_sizes', + 'label' => esc_html__( 'Max. File Size', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Size in MB', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 1, + 'max' => wp_max_upload_size() / pow( 1024, 2 ), + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'description' => esc_html__( 'Size is in MB. If you need to increase max upload size please contact your hosting.', 'elementor-pro' ), + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + 'title' => esc_html__( 'Size in MB', 'elementor-pro' ), + ], + 'file_types' => [ + 'name' => 'file_types', + 'label' => esc_html__( 'Allowed File Types', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'description' => esc_html__( 'Enter the allowed file types, separated by a comma (jpg, gif, pdf, etc).', 'elementor-pro' ), + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'allow_multiple_upload' => [ + 'name' => 'allow_multiple_upload', + 'label' => esc_html__( 'Multiple Files', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'field_type' => $this->get_type(), + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + 'max_files' => [ + 'name' => 'max_files', + 'label' => esc_html__( 'Max. Files', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'condition' => [ + 'field_type' => $this->get_type(), + 'allow_multiple_upload' => 'yes', + ], + 'tab' => 'content', + 'inner_tab' => 'form_fields_content_tab', + 'tabs_wrapper' => 'form_fields_tabs', + ], + ]; + + $control_data['fields'] = $this->inject_field_controls( $control_data['fields'], $field_controls ); + $widget->update_control( 'form_fields', $control_data ); + } + + /** + * @param $item + * @param $item_index + * @param Form $form + */ + public function render( $item, $item_index, $form ) { + $form->add_render_attribute( 'input' . $item_index, 'class', 'elementor-upload-field' ); + $form->add_render_attribute( 'input' . $item_index, 'type', 'file', true ); + + if ( ! empty( $item['allow_multiple_upload'] ) ) { + $form->add_render_attribute( 'input' . $item_index, 'multiple', 'multiple' ); + $form->add_render_attribute( 'input' . $item_index, 'name', $form->get_attribute_name( $item ) . '[]', true ); + } + + if ( ! empty( $item['file_sizes'] ) ) { + $form->add_render_attribute( + 'input' . $item_index, + [ + 'data-maxsize' => $item['file_sizes'], //MB + 'data-maxsize-message' => esc_html__( 'This file exceeds the maximum allowed size.', 'elementor-pro' ), + ] + ); + } + ?> + print_render_attribute_string( 'input' . $item_index ); ?>> + + fixed_files_indices ) { + return; + } + // a mapping of $_FILES indices for validity checking + $names = [ + 'name', + 'type', + 'tmp_name', + 'error', + 'size', + ]; + $files = $_FILES['form_fields']; // phpcs:ignore -- escaped when processing the file later on. + // iterate over each uploaded file + foreach ( $files as $key => $part ) { + $key = (string) $key; + if ( in_array( $key, $names, true ) && is_array( $part ) ) { + foreach ( $part as $position => $value ) { + if ( is_array( $value ) ) { + foreach ( $value as $index => $inner_val ) { + $files[ $position ][ $index ][ $key ] = $inner_val; + } + } else { + $files[ $position ][0][ $key ] = $value; + } + } + } + + // remove original key reference + unset( $files[ $key ] ); + } + $_FILES['form_fields'] = $files; + $this->fixed_files_indices = true; + } + + /** + * validate uploaded file size against allowed file size + * + * @param array $field + * @param $file + * + * @return bool + */ + private function is_file_size_valid( $field, $file ) { + $allowed_size = ( ! empty( $field['file_sizes'] ) ) ? $field['file_sizes'] : wp_max_upload_size() / pow( 1024, 2 ); + // File size validation + $file_size_meta = $allowed_size * pow( 1024, 2 ); + $upload_file_size = $file['size']; + + return ( $upload_file_size < $file_size_meta ); + } + + /** + * validates uploaded file type against allowed file types + * + * @param array $field + * @param $file + * + * @return bool + */ + private function is_file_type_valid( $field, $file ) { + // File type validation + if ( empty( $field['file_types'] ) ) { + $field['file_types'] = 'jpg,jpeg,png,gif,pdf,doc,docx,ppt,pptx,odt,avi,ogg,m4a,mov,mp3,mp4,mpg,wav,wmv'; + } + + $file_extension = pathinfo( $file['name'], PATHINFO_EXTENSION ); + $file_types_meta = explode( ',', $field['file_types'] ); + $file_types_meta = array_map( 'trim', $file_types_meta ); + + $file_types_meta = array_map( 'strtolower', $file_types_meta ); + $file_extension = strtolower( $file_extension ); + + return ( in_array( $file_extension, $file_types_meta ) && ! in_array( $file_extension, $this->get_blacklist_file_ext() ) ); + } + + /** + * A blacklist of file extensions. + * + * @return array + */ + private function get_blacklist_file_ext() { + static $blacklist = false; + if ( ! $blacklist ) { + $blacklist = [ + 'php', + 'php3', + 'php4', + 'php5', + 'php6', + 'phps', + 'php7', + 'phtml', + 'shtml', + 'pht', + 'swf', + 'html', + 'asp', + 'aspx', + 'cmd', + 'csh', + 'bat', + 'htm', + 'hta', + 'jar', + 'exe', + 'com', + 'js', + 'lnk', + 'htaccess', + 'htpasswd', + 'phtml', + 'ps1', + 'ps2', + 'py', + 'rb', + 'tmp', + 'cgi', + 'svg', + 'php2', + 'phtm', + 'phar', + 'hphp', + 'phpt', + 'svgz', + ]; + + /** + * Elementor forms blacklisted file extensions. + * + * Filters the list of file types that won't be uploaded using Elementor forms. + * + * By default Elementor forms doesn't upload some file types for security reasons. + * This hook allows developers to alter this list, either add more file types to + * strengthen the security or remove file types to increase flexibility. + * + * @since 1.0.0 + * + * @param array $blacklist A blacklist of file extensions. + */ + $blacklist = apply_filters( 'elementor_pro/forms/filetypes/blacklist', $blacklist ); + } + + return $blacklist; + } + + /** + * validate uploaded file field + * + * @param array $field + * @param Classes\Form_Record $record + * @param Classes\Ajax_Handler $ajax_handler + */ + public function validation( $field, Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) { + static $upload_errors = false; + + if ( ! $upload_errors ) { + $upload_errors = [ + UPLOAD_ERR_OK => esc_html__( 'There is no error, the file uploaded with success.', 'elementor-pro' ), + /* translators: 1: upload_max_filesize, 2: php.ini */ + UPLOAD_ERR_INI_SIZE => sprintf( esc_html__( 'The uploaded file exceeds the %1$s directive in %2$s.', 'elementor-pro' ), 'upload_max_filesize', 'php.ini' ), + /* translators: %s: MAX_FILE_SIZE */ + UPLOAD_ERR_FORM_SIZE => sprintf( esc_html__( 'The uploaded file exceeds the %s directive that was specified in the HTML form.', 'elementor-pro' ), 'MAX_FILE_SIZE' ), + UPLOAD_ERR_PARTIAL => esc_html__( 'The uploaded file was only partially uploaded.', 'elementor-pro' ), + UPLOAD_ERR_NO_FILE => esc_html__( 'No file was uploaded.', 'elementor-pro' ), + UPLOAD_ERR_NO_TMP_DIR => esc_html__( 'Missing a temporary folder.', 'elementor-pro' ), + UPLOAD_ERR_CANT_WRITE => esc_html__( 'Failed to write file to disk.', 'elementor-pro' ), + /* translators: %s: phpinfo() */ + UPLOAD_ERR_EXTENSION => sprintf( esc_html__( 'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with %s may help.', 'elementor-pro' ), 'phpinfo()' ), + ]; + } + + $this->fix_file_indices(); + + $id = $field['id']; + $files = Utils::_unstable_get_super_global_value( $_FILES, 'form_fields' ); + + if ( ! empty( $field['max_files'] ) ) { + if ( count( $files[ $id ] ) > $field['max_files'] ) { + $error_message = sprintf( + /* translators: %d: The number of allowed files. */ + _n( 'You can upload only %d file.', 'You can upload up to %d files.', intval( $field['max_files'] ), 'elementor-pro' ), + intval( $field['max_files'] ) + ); + $ajax_handler->add_error( $id, $error_message ); + + return; + } + } + + foreach ( $files[ $id ] as $index => $file ) { + // not uploaded + if ( ! $field['required'] && UPLOAD_ERR_NO_FILE === $file['error'] ) { + return; + } + + // is the file required and missing? + if ( $field['required'] && UPLOAD_ERR_NO_FILE === $file['error'] ) { + $ajax_handler->add_error( $id, $upload_errors[ $file['error'] ] ); + + return; + } + + // Has any error with upload the file? + if ( $file['error'] > UPLOAD_ERR_OK ) { + $ajax_handler->add_error( $id, $upload_errors[ $file['error'] ] ); + + return; + } + + // valid file type? + if ( ! $this->is_file_type_valid( $field, $file ) ) { + $ajax_handler->add_error( $id, esc_html__( 'This file type is not allowed.', 'elementor-pro' ) ); + } + + // allowed file size? + if ( ! $this->is_file_size_valid( $field, $file ) ) { + $ajax_handler->add_error( $id, esc_html__( 'This file exceeds the maximum allowed size.', 'elementor-pro' ) ); + } + } + } + + /** + * Gets the path to uploaded file. + * + * @return string + */ + private function get_upload_dir() { + $wp_upload_dir = wp_upload_dir(); + $path = $wp_upload_dir['basedir'] . '/elementor/forms'; + + /** + * Elementor forms upload file path. + * + * Filters the path to a file uploaded using Elementor forms. + * + * By default Elementor forms defines a path to uploaded file. This + * hook allows developers to alter this path. + * + * @since 1.0.0 + * + * @param string $path Path to uploaded files. + */ + $path = apply_filters( 'elementor_pro/forms/upload_path', $path ); + + return $path; + } + + /** + * Gets the URL to uploaded file. + * + * @param $file_name + * + * @return string + */ + private function get_file_url( $file_name ) { + $wp_upload_dir = wp_upload_dir(); + $url = $wp_upload_dir['baseurl'] . '/elementor/forms/' . $file_name; + + /** + * Elementor forms upload file URL. + * + * Filters the URL to a file uploaded using Elementor forms. + * + * By default Elementor forms defines a URL to uploaded file. This + * hook allows developers to alter this URL. + * + * @since 1.0.0 + * + * @param string $url Upload file URL. + * @param string $file_name Upload file name. + */ + $url = apply_filters( 'elementor_pro/forms/upload_url', $url, $file_name ); + + return $url; + } + + /** + * This function returns the uploads folder after making sure + * it is created and has protection files + * @return string + */ + private function get_ensure_upload_dir() { + $path = $this->get_upload_dir(); + if ( file_exists( $path . '/index.php' ) ) { + return $path; + } + + wp_mkdir_p( $path ); + + $files = [ + [ + 'file' => 'index.php', + 'content' => [ + ' '.htaccess', + 'content' => [ + 'Options -Indexes', + '', + ' ', + ' Header set Content-Disposition attachment', + ' ', + '', + ], + ], + ]; + + foreach ( $files as $file ) { + if ( ! file_exists( trailingslashit( $path ) . $file['file'] ) ) { + $content = implode( PHP_EOL, $file['content'] ); + @ file_put_contents( trailingslashit( $path ) . $file['file'], $content ); + } + } + + return $path; + } + + + /** + * process file and move it to uploads directory + * + * @param array $field + * @param Classes\Form_Record $record + * @param Classes\Ajax_Handler $ajax_handler + */ + public function process_field( $field, Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) { + $id = $field['id']; + $files = Utils::_unstable_get_super_global_value( $_FILES, 'form_fields' ); + + foreach ( $files[ $id ] as $index => $file ) { + if ( UPLOAD_ERR_NO_FILE === $file['error'] ) { + continue; + } + + $uploads_dir = $this->get_ensure_upload_dir(); + $file_extension = pathinfo( $file['name'], PATHINFO_EXTENSION ); + $filename = uniqid() . '.' . $file_extension; + $filename = wp_unique_filename( $uploads_dir, $filename ); + $new_file = trailingslashit( $uploads_dir ) . $filename; + + if ( is_dir( $uploads_dir ) && is_writable( $uploads_dir ) ) { + $move_new_file = Plugin::instance()->php_api->move_uploaded_file( $file['tmp_name'], $new_file ); + if ( false !== $move_new_file ) { + // Set correct file permissions. + $perms = 0644; + @ chmod( $new_file, $perms ); + + $record->add_file( $id, $index, + [ + 'path' => $new_file, + 'url' => $this->get_file_url( $filename ), + ] + ); + } else { + $ajax_handler->add_error( $id, esc_html__( 'There was an error while trying to upload your file.', 'elementor-pro' ) ); + } + } else { + $ajax_handler->add_admin_error_message( esc_html__( 'Upload directory is not writable or does not exist.', 'elementor-pro' ) ); + } + } + } + + /** + * Used to set the upload filed values with + * value => file url + * raw_value => file path + * + * @param Classes\Form_Record $record + * @param Classes\Ajax_Handler $ajax_handler + */ + public function set_file_fields_values( Classes\Form_Record $record, Classes\Ajax_Handler $ajax_handler ) { + $files = $record->get( 'files' ); + if ( empty( $files ) ) { + return; + } + foreach ( $files as $id => $files_array ) { + $record->update_field( $id, 'value', implode( ' , ', $files_array['url'] ) ); + $record->update_field( $id, 'raw_value', implode( ' , ', $files_array['path'] ) ); + } + } + + public function __construct() { + parent::__construct(); + add_action( 'elementor_pro/forms/process', [ $this, 'set_file_fields_values' ], 10, 2 ); + } +} diff --git a/modules/forms/module.php b/modules/forms/module.php new file mode 100644 index 00000000..43660b0c --- /dev/null +++ b/modules/forms/module.php @@ -0,0 +1,278 @@ + 'Form', + 'login' => 'Login', + ]; + + public function get_name() { + return 'forms'; + } + + public function get_widgets() { + return API::filter_active_features( static::WIDGET_NAME_CLASS_NAME_MAP ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/forms/assets/scss/frontend.scss` + * to `/assets/css/widget-forms.min.css`. + * + * @return void + */ + public function register_styles() { + $widget_styles = $this->get_widgets_style_list(); + + foreach ( $widget_styles as $widget_style_name ) { + wp_register_style( + $widget_style_name, + $this->get_css_assets_url( $widget_style_name, null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + } + + private function get_widgets_style_list(): array { + return [ + 'widget-form', + 'widget-login', + ]; + } + + public static function find_element_recursive( $elements, $form_id ) { + foreach ( $elements as $element ) { + if ( $form_id === $element['id'] ) { + return $element; + } + + if ( ! empty( $element['elements'] ) ) { + $element = self::find_element_recursive( $element['elements'], $form_id ); + + if ( $element ) { + return $element; + } + } + } + + return false; + } + + public function register_controls( Controls_Manager $controls_manager ) { + $controls_manager->register( new Fields_Repeater() ); + $controls_manager->register( new Fields_Map() ); + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function forms_panel_action_data( array $data ) { + $document = Utils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + if ( empty( $data['service'] ) ) { + throw new \Exception( 'Service required.' ); + } + + /** @var \ElementorPro\Modules\Forms\Classes\Integration_Base $integration */ + $integration = $this->actions_registrar->get( $data['service'] ); + + if ( ! $integration ) { + throw new \Exception( 'Action not found.' ); + } + + return $integration->handle_panel_request( $data ); + } + + /** + * @deprecated 3.5.0 Use `fields_registrar->register()` instead. + */ + public function add_form_field_type( $type, $instance ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( + __METHOD__, + '3.5.0', + 'fields_registrar->register()' + ); + + $this->fields_registrar->register( $instance, $type ); + } + + /** + * @deprecated 3.5.0 Use `actions_registrar->register()` instead. + */ + public function add_form_action( $id, $instance ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( + __METHOD__, + '3.5.0', + 'actions_registrar->register()' + ); + + $this->actions_registrar->register( $instance, $id ); + } + + /** + * @deprecated 3.5.0 Use `actions_registrar->get()` instead. + */ + public function get_form_actions( $id = null ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( + __METHOD__, + '3.5.0', + 'actions_registrar->get()' + ); + + return $this->actions_registrar->get( $id ); + } + + public function register_ajax_actions( Ajax $ajax ) { + $ajax->register_ajax_action( 'pro_forms_panel_action_data', [ $this, 'forms_panel_action_data' ] ); + } + + /** + * Register submissions + */ + private function register_submissions_component() { + $name = Form_Submissions_Component::NAME; + + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_submissions_admin_fields' ] ); + } + + if ( '1' === get_option( 'elementor_' . $name ) ) { + return; + } + + $this->add_component( $name, new Form_Submissions_Component() ); + } + + public function register_submissions_admin_fields( Settings $settings ) { + $settings->add_field( + Settings::TAB_ADVANCED, + Settings::TAB_ADVANCED, + Form_Submissions_Component::NAME, + [ + 'label' => esc_html__( 'Form Submissions', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'select', + 'std' => '', + 'options' => [ + '' => esc_html__( 'Enable', 'elementor-pro' ), + '1' => esc_html__( 'Disable', 'elementor-pro' ), + ], + 'desc' => esc_html__( 'Never lose another submission! Using “Actions After Submit” you can now choose to save all submissions to an internal database.', 'elementor-pro' ), + ], + ], + ); + } + + /** + * Module constructor. + */ + public function __construct() { + parent::__construct(); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + add_action( 'elementor/controls/register', [ $this, 'register_controls' ] ); + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + $this->add_component( 'recaptcha', new Classes\Recaptcha_Handler() ); + $this->add_component( 'recaptcha_v3', new Classes\Recaptcha_V3_Handler() ); + $this->add_component( 'honeypot', new Classes\Honeypot_Handler() ); + + // Akismet + if ( class_exists( '\Akismet' ) && API::is_licence_has_feature( static::AKISMET_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'akismet', new Classes\Akismet() ); + } + + if ( API::is_licence_has_feature( Form_Submissions_Component::NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->register_submissions_component(); + } else { + add_action( 'elementor/admin/menu/register', function( $admin_menu ) { + $admin_menu->register( Form_Submissions_Component::PAGE_ID, new Submissions_Promotion_Menu_Item() ); + }, 9 /* After "Settings" */ ); + } + + // Initialize registrars. + $this->actions_registrar = new Form_Actions_Registrar(); + $this->fields_registrar = new Form_Fields_Registrar(); + + // Add Actions as components, that runs manually in the Ajax_Handler + + // Activity Log + if ( function_exists( 'aal_insert_log' ) && API::is_licence_has_feature( static::ACTIVITY_LOG_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'activity_log', new Actions\Activity_Log() ); + } + + // Contact Form to Database + if ( function_exists( 'CF7DBPlugin_init' ) && API::is_licence_has_feature( static::CF7DB_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->add_component( 'cf7db', new Actions\CF7DB() ); + } + + // Ajax Handler + if ( Classes\Ajax_Handler::is_form_submitted() ) { + $this->add_component( 'ajax_handler', new Classes\Ajax_Handler() ); + + /** + * Elementor form submitted. + * + * Fires when the form is submitted. This hook allows developers + * to add functionality after form submission. + * + * @since 2.0.0 + * + * @param Module $this An instance of the form module. + */ + do_action( 'elementor_pro/forms/form_submitted', $this ); + } + } +} diff --git a/modules/forms/registrars/form-actions-registrar.php b/modules/forms/registrars/form-actions-registrar.php new file mode 100644 index 00000000..5ec19109 --- /dev/null +++ b/modules/forms/registrars/form-actions-registrar.php @@ -0,0 +1,96 @@ + 'Email', + 'email2' => 'Email2', + 'redirect' => 'Redirect', + 'webhook' => 'Webhook', + 'mailchimp' => 'Mailchimp', + 'drip' => 'Drip', + 'activecampaign' => 'Activecampaign', + 'getresponse' => 'Getresponse', + 'convertkit' => 'Convertkit', + 'mailerlite' => 'Mailerlite', + 'slack' => 'Slack', + 'discord' => 'Discord', + ]; + + /** + * Form_Actions_Registrar constructor. + * + * @return void + */ + public function __construct() { + parent::__construct(); + + $this->init(); + } + + /** + * Initialize the default fields. + * + * @return void + */ + public function init() { + // Register the actions handlers using a hook since some actions need to be registered before those actions (e.g: save-to-database). + add_action( 'elementor_pro/forms/actions/register', function ( Form_Actions_Registrar $actions_registrar ) { + $form_actions = API::filter_active_features( static::FEATURE_NAME_CLASS_NAME_MAP ); + + foreach ( $form_actions as $action ) { + $class_name = 'ElementorPro\Modules\Forms\Actions\\' . $action; + $actions_registrar->register( new $class_name() ); + } + } ); + + /** + * Deprecated actions registration hook. + * + * @deprecated 3.5.0 Use `elementor_pro/forms/actions/register` instead. + */ + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->do_deprecated_action( + 'elementor_pro/forms/register_action', + [ $this ], + '3.5.0', + 'elementor_pro/forms/actions/register' + ); + + /** + * Elementor Pro form actions registration. + * + * Fires when a new form action is registered. This hook allows developers to + * register new form actions. + * + * @since 3.5.0 + * + * @param Form_Actions_Registrar $this An instance of form actions registration + * manager. + */ + do_action( 'elementor_pro/forms/actions/register', $this ); + + // MailPoet + if ( class_exists( '\WYSIJA' ) ) { + $this->register( new Actions\Mailpoet() ); + } + + // MailPoet + if ( class_exists( '\MailPoet\API\API' ) ) { + $this->register( new Actions\Mailpoet3() ); + } + } +} diff --git a/modules/forms/registrars/form-fields-registrar.php b/modules/forms/registrars/form-fields-registrar.php new file mode 100644 index 00000000..0adbd650 --- /dev/null +++ b/modules/forms/registrars/form-fields-registrar.php @@ -0,0 +1,55 @@ +init(); + } + + /** + * Initialize the default fields. + * + * @return void + */ + public function init() { + $this->register( new Fields\Time() ); + $this->register( new Fields\Date() ); + $this->register( new Fields\Tel() ); + $this->register( new Fields\Number() ); + $this->register( new Fields\Acceptance() ); + $this->register( new Fields\Upload() ); + $this->register( new Fields\Step() ); + + /** + * Elementor Pro form fields registration. + * + * Fires when a new form field is registered. This hook allows developers to + * register new form fields. + * + * @since 3.5.0 + * + * @param Form_Actions_Registrar $this An instance of form fields registration + * manager. + */ + do_action( 'elementor_pro/forms/fields/register', $this ); + } +} diff --git a/modules/forms/submissions/actions/save-to-database.php b/modules/forms/submissions/actions/save-to-database.php new file mode 100644 index 00000000..e1ed0ad3 --- /dev/null +++ b/modules/forms/submissions/actions/save-to-database.php @@ -0,0 +1,197 @@ +start_controls_section( + 'section_submissions', + [ + 'label' => esc_html__( 'Collect Submissions', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'submissions_action_message', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + /* translators: 1: Link open tag, 2: Link open tag, 3: Link close tag. */ + esc_html__( 'Collected Submissions will be saved to Elementor > %1$s Submissions %2$s', 'elementor-pro' ), + sprintf( '', self_admin_url( 'admin.php?page=' . Component::PAGE_ID ) ), + '', + ), + ] + ); + + $widget->add_control( + 'submissions_metadata', + [ + 'label' => esc_html__( 'Metadata', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'remote_ip' => esc_html__( 'User IP', 'elementor-pro' ), + 'user_agent' => esc_html__( 'User Agent', 'elementor-pro' ), + ], + 'render_type' => 'none', + 'label_block' => true, + 'default' => [ 'remote_ip', 'user_agent' ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + // This action does not have to do nothing on export. + } + + /** + * @param \ElementorPro\Modules\Forms\Classes\Form_Record $record + * @param \ElementorPro\Modules\Forms\Classes\Ajax_Handler $ajax_handler + */ + public function run( $record, $ajax_handler ) { + $meta_keys = array_merge( [ 'page_url', 'page_title' ], $record->get_form_settings( 'submissions_metadata' ) ); + $meta = $record->get_form_meta( $meta_keys ); + + $actions_count = ( new Collection( $record->get_form_settings( 'submit_actions' ) ) ) + ->filter(function ( $value ) { + return $value !== $this->get_name(); + }) + ->count(); + + $post_id = $record->get_form_settings( 'form_post_id' ); + $element_id = $ajax_handler->get_current_form()['id']; + $form_name = $record->get_form_settings( 'form_name' ); + + $this->submission_id = Query::get_instance()->add_submission( [ + 'main_meta_id' => 0, + 'post_id' => $post_id, + 'referer' => remove_query_arg( + [ 'preview_id', 'preview_nonce', 'preview' ], + $meta['page_url']['value'] + ), + 'referer_title' => $meta['page_title']['value'], + 'element_id' => $element_id, + 'form_name' => $form_name, + 'campaign_id' => 0, + 'user_id' => get_current_user_id(), + 'user_ip' => ! empty( $meta['remote_ip'] ) ? $meta['remote_ip']['value'] : '', + 'user_agent' => ! empty( $meta['user_agent'] ) ? $meta['user_agent']['value'] : '', + 'actions_count' => $actions_count, + 'actions_succeeded_count' => 0, + 'meta' => wp_json_encode( [ + // TODO: Should be removed if there is an ability to edit "global widgets" + 'edit_post_id' => $record->get_form_settings( 'edit_post_id' ), + ] ), + ], $record->get_field( null ) ); + + /** @var Form $form_instance */ + $form_instance = Plugin::elementor()->elements_manager->create_element_instance( $ajax_handler->get_current_form() ); + $fields = $record->get_form_settings( 'form_fields' ); + + // When created new submission, it should also update or create + // a form snapshot to save to new state of the form in case the form changed or will + // be deleted later. + Form_Snapshot_Repository::instance() + ->create_or_update( $post_id, $element_id, [ + 'name' => $form_name, + 'fields' => array_map( function ( $field, $index ) use ( $form_instance ) { + // Apply filters to demonstrate the same behavior as the render behavior. (adding select fields dynamically, etc.) + // Ref: modules/forms/widgets/form.php:2116 + $field = apply_filters( 'elementor_pro/forms/render/item', $field, $index, $form_instance ); + $field = apply_filters( "elementor_pro/forms/render/item/{$field['field_type']}", $field, $index, $form_instance ); + + $mapped_field = [ + 'id' => $field['custom_id'], + 'type' => $field['field_type'], + 'label' => $field['field_label'], + ]; + + if ( isset( $field['field_options'] ) ) { + $mapped_field['options'] = preg_split( '/(\r\n|\n|\r)/', $field['field_options'] ); + } + + if ( isset( $field['allow_multiple'] ) ) { + $mapped_field['is_multiple'] = 'true' === $field['allow_multiple']; + } + + return $mapped_field; + }, $fields, array_keys( $fields ) ), + ] ); + } + + /** + * It listen for all the form actions and log the result into the database. + * + * @param Action_Base $action Should be class based on ActionBase (do not type hint to support third party plugins) + * @param \Exception|null $exception + */ + private function save_action_log( $action, ?\Exception $exception = null ) { + if ( ! $this->submission_id || $action->get_name() === $this->get_name() ) { + return; + } + + $query = Query::get_instance(); + $error_message = null; + + if ( $exception ) { + $error_message = $exception->getMessage(); + + $status = Query::ACTIONS_LOG_STATUS_FAILED; + } else { + $this->actions_succeeded_count += 1; + + $query->update_submission( $this->submission_id, [ + 'actions_succeeded_count' => $this->actions_succeeded_count, + ] ); + + $status = Query::ACTIONS_LOG_STATUS_SUCCESS; + } + + $query->add_action_log( + $this->submission_id, + $action, + $status, + $error_message + ); + } + + /** + * Save_To_Database constructor. + */ + public function __construct() { + add_action( 'elementor_pro/forms/actions/after_run', function ( Action_Base $action, ?\Exception $exception = null ) { + $this->save_action_log( $action, $exception ); + }, 10, 2 ); + } +} diff --git a/modules/forms/submissions/admin-menu-items/submissions-menu-item.php b/modules/forms/submissions/admin-menu-items/submissions-menu-item.php new file mode 100644 index 00000000..02512175 --- /dev/null +++ b/modules/forms/submissions/admin-menu-items/submissions-menu-item.php @@ -0,0 +1,140 @@ +maybe_render_hints(); + ?> +
      +

      +
      +
      +
      + has_submissions() ) { + return; + } + + if ( $this->should_show_send_app_hint() ) { + $this->render_send_app_notice(); + return; + } + + if ( $this->should_show_site_mailer_hint() ) { + $this->render_site_mailer_notice(); + } + } + + private function render_site_mailer_notice() { + /** + * @var Admin_Notices $admin_notices + */ + $admin_notices = Plugin::elementor()->admin->get_component( 'admin-notices' ); + + $notice_options = [ + 'description' => esc_html__( 'Experiencing email deliverability issues? Get your emails delivered with Site Mailer.', 'elementor-pro' ), + 'id' => 'site_mailer_forms_submissions_notice', + 'type' => 'cta', + 'button_secondary' => [ + 'text' => Hints::is_plugin_installed( 'site-mailer' ) ? esc_html__( 'Activate Plugin', 'elementor-pro' ) : esc_html__( 'Install Plugin', 'elementor-pro' ), + 'url' => Hints::get_plugin_action_url( 'site-mailer' ), + 'type' => 'cta', + ], + ]; + + if ( 2 === Abtest::get_variation( 'plg_site_mailer_submission' ) ) { + $notice_options['title'] = esc_html__( 'Get Your Emails Delivered With Site Mailer', 'elementor-pro' ); + $notice_options['description'] = esc_html__( 'Make sure emails reach the inbox every time with improved deliverability, detailed email logs, and an easy setup with no need for an SMTP plugin.', 'elementor-pro' ); + } + + $admin_notices->print_admin_notice( $notice_options ); + } + + private function render_send_app_notice() { + /** + * @var Admin_Notices $admin_notices + */ + $admin_notices = Plugin::elementor()->admin->get_component( 'admin-notices' ); + + $send_app_notice_options = [ + 'title' => esc_html__( 'Forms are just the beginning', 'elementor-pro' ), + 'description' => esc_html__( 'Turn submissions into leads with automated replies, welcome series, and smart tagging — all inside WordPress. +With Send, you build relationships from the first interaction.', 'elementor-pro' ), + 'id' => 'send_app_forms_submissions_notice', + 'type' => 'cta', + 'button_secondary' => [ + 'text' => Hints::is_plugin_installed( 'send-app' ) ? esc_html__( 'Activate Send Now', 'elementor-pro' ) : esc_html__( 'Install Send Now', 'elementor-pro' ), + 'url' => Hints::get_plugin_action_url( 'send-app' ), + 'type' => 'cta', + ], + ]; + + $admin_notices->print_admin_notice( $send_app_notice_options ); + } + + public function has_submissions( $min_count = 1 ): bool { + global $wpdb; + $table = $wpdb->prefix . Query::E_SUBMISSIONS; + // The placeholder ignores can be removed when %i is supported by WPCS. + // See https://core.trac.wordpress.org/ticket/56091#comment:11 + // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber + $submissions_count = (int) $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i LIMIT %d', $table, $min_count ) ); + return $min_count <= $submissions_count; + } + + public function should_show_site_mailer_hint(): bool { + return ( Hints::should_show_hint( 'site_mailer_forms_submissions_notice' ) + && ! User::is_user_notice_viewed( 'site_mailer_forms_submissions_notice' ) + ); + } + + public function should_show_send_app_hint(): bool { + if ( Hints::is_plugin_active( 'woocommerce' ) || ! $this->should_show_site_mailer_hint() ) { + if ( ! User::is_user_notice_viewed( 'send_app_forms_submissions_notice' ) ) { + return Hints::should_show_hint( 'send_app_forms_submissions_notice' ); + } + } + + return false; + } +} diff --git a/modules/forms/submissions/admin-menu-items/submissions-promotion-menu-item.php b/modules/forms/submissions/admin-menu-items/submissions-promotion-menu-item.php new file mode 100644 index 00000000..c66fd35d --- /dev/null +++ b/modules/forms/submissions/admin-menu-items/submissions-promotion-menu-item.php @@ -0,0 +1,71 @@ +get_page_title(); + } + + public function get_page_title(): string { + return esc_html__( 'Submissions', 'elementor-pro' ); + } + + protected function get_promotion_title(): string { + return esc_html__( 'Seal the deal on your Form Submissions', 'elementor-pro' ) . '
      '; + } + + protected function get_content_lines():array { + return [ + esc_html__( 'Integrate your favorite marketing software', 'elementor-pro' ), + esc_html__( 'Collect lead submissions directly within your WordPress Admin to manage, analyze and perform bulk actions on the submitted lead', 'elementor-pro' ), + ]; + } + + protected function get_video_url(): string { + return 'https://www.youtube-nocookie.com/embed/LNfnwba9C-8?si=JLHk3UAexnvTfU1a'; + } + + public function get_cta_text() { + if ( ! API::active_licence_has_feature( Form_Submissions_Component::NAME ) ) { + return esc_html__( 'Upgrade Now', 'elementor-pro' ); + } + + return API::is_license_expired() + ? esc_html__( 'Renew now', 'elementor-pro' ) + : esc_html__( 'Connect & Activate', 'elementor-pro' ); + } + + protected function get_cta_url(): string { + if ( ! API::active_licence_has_feature( Form_Submissions_Component::NAME ) ) { + $upgrade_url = 'https://go.elementor.com/go-pro-advanced-form-submissions/'; + + return $upgrade_url; + } + + $connect_url = Plugin::instance()->license_admin->get_connect_url( [ + 'utm_source' => 'wp-dash-submissions', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + ] ); + + $renew_url = 'https://go.elementor.com/renew-submissions/'; + + return API::is_license_expired() + ? $renew_url + : $connect_url; + } +} diff --git a/modules/forms/submissions/component.php b/modules/forms/submissions/component.php new file mode 100644 index 00000000..e23732c1 --- /dev/null +++ b/modules/forms/submissions/component.php @@ -0,0 +1,220 @@ +add_submenu( [ + 'menu_title' => $this->get_title(), + 'menu_slug' => self::PAGE_ID, + 'function' => function () { + $this->render_admin_page(); + }, + 'index' => 35, + ] ); + } + + /** + * Register admin menu + */ + private function register_admin_menu_legacy( Admin_Menu_Manager $admin_menu ) { + $admin_menu->register( static::PAGE_ID, + $this->can_use_submissions() + ? new Submissions_Menu_Item() + : new Submissions_Promotion_Menu_Item() + ); + } + + private function can_use_submissions() : bool { + return API::is_license_active() && API::active_licence_has_feature( static::NAME ); + } + + private function render_admin_page() { + ?> +
      +

      +
      +
      +
      + get_css_assets_url( 'e-select2', '../elementor/assets/lib/e-select2/css/' ), + [], + '4.0.6-rc.1' + ); + + wp_enqueue_style( + 'elementor-app-base', + $this->get_css_assets_url( 'modules/forms/submissions/admin', null, 'default', true ), + [ 'select2' ], + ELEMENTOR_PRO_VERSION + ); + + wp_register_script( + 'select2', + $this->get_js_assets_url( 'e-select2.full', '../elementor/assets/lib/e-select2/js/' ), + [ + 'jquery', + ], + '4.0.6-rc.1', + true + ); + + wp_enqueue_script( + 'form-submission-admin', + $this->get_js_assets_url( 'form-submission-admin' ), + [ + 'select2', + 'wp-url', + 'wp-i18n', + 'wp-date', + 'react', + 'react-dom', + ], + ELEMENTOR_PRO_VERSION, + true + ); + + $is_trash_enabled = (int) ( EMPTY_TRASH_DAYS !== 0 ); + + wp_add_inline_script( + 'form-submission-admin', + "window.elementorSubmissionsConfig = { isTrashEnabled: {$is_trash_enabled} };", + 'before' + ); + + wp_set_script_translations( 'form-submission-admin', 'elementor-pro' ); + } + + private function scheduled_submissions_delete() { + $query = Query::get_instance(); + $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS ); + + $ids = $query->get_trashed_submission_ids_to_delete( $delete_timestamp ); + + foreach ( $ids as $id ) { + $query->delete_submission( $id ); + } + } + + private function get_title() { + return esc_html__( 'Submissions', 'elementor-pro' ); + } + + /** + * Component constructor. + */ + public function __construct() { + parent::__construct(); + + Plugin::elementor()->data_manager->register_controller( Controller::class ); + Plugin::elementor()->data_manager->register_controller( Forms_Controller::class ); + + new Personal_Data(); + + add_action( 'admin_init', function () { + Migration::install(); + } ); + + add_action( 'elementor_pro/forms/actions/register', function ( Form_Actions_Registrar $actions_registrar ) { + $actions_registrar->register( new Save_To_Database() ); + }, 0 /* Before all the actions */ ); + + add_filter( 'elementor_pro/forms/default_submit_actions', function ( $actions ) { + return array_merge( $actions, [ 'save-to-database' ] ); + } ); + + add_action( 'wp_scheduled_delete', function () { + $this->scheduled_submissions_delete(); + } ); + + if ( Plugin::elementor()->experiments->is_feature_active( 'admin_menu_rearrangement' ) ) { + add_action( 'elementor/admin/menu_registered/elementor', function( MainMenu $menu ) { + $this->register_admin_menu( $menu ); + } ); + } else { + add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) { + $this->register_admin_menu_legacy( $admin_menu ); + }, 9 /* After "Settings" */ ); + + // TODO: BC - Remove after `Admin_Menu_Manager` will be the standard. + add_action( 'admin_menu', function () { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + $title = $this->get_title(); + + add_submenu_page( + Settings::PAGE_ID, + $title, + $title, + 'manage_options', + self::PAGE_ID, + function () { + $this->render_admin_page(); + } + ); + }, 21 /* after Elementor page */ ); + } + + if ( $this->is_current() ) { + add_action( 'admin_enqueue_scripts', function () { + $this->enqueue_scripts(); + } ); + } + } +} diff --git a/modules/forms/submissions/data/controller.php b/modules/forms/submissions/data/controller.php new file mode 100644 index 00000000..bafa26b5 --- /dev/null +++ b/modules/forms/submissions/data/controller.php @@ -0,0 +1,364 @@ +get_collection_params(); + + foreach ( $collection_params as $collection_param_key => $collection_param ) { + if ( isset( $collection_param['additionalProperties']['context'] ) && $context === $collection_param['additionalProperties']['context'] ) { + $result[ $collection_param_key ] = $collection_param; + } + } + + return $result; + } + + public function get_collection_params() { + $default_collection_params = parent::get_collection_params(); + + return array_merge( $default_collection_params, [ + 'page' => [ + 'description' => 'Current page of the collection.', + 'type' => 'integer', + 'default' => 1, + 'minimum' => 1, + 'required' => false, + ], + 'per_page' => [ + 'description' => 'Maximum number of items to be returned in result set.', + 'type' => 'integer', + 'default' => 50, + 'minimum' => 1, + 'maximum' => 100, + 'required' => false, + ], + 'order' => [ + 'description' => 'Order sort attribute ascending or descending.', + 'type' => 'string', + 'default' => 'desc', + 'enum' => [ + 'asc', + 'desc', + ], + 'required' => false, + ], + 'order_by' => [ + 'description' => 'Sort collection by object attribute.', + 'type' => 'string', + 'default' => 'created_at', + 'enum' => [ + 'created_at', + 'id', + 'main_meta_id', + ], + 'required' => false, + ], + 'status' => [ + 'description' => 'Limit result set to submissions assigned one or more statuses.', + 'type' => 'string', + 'default' => 'all', + 'enum' => [ + 'all', + 'unread', + 'read', + 'trash', + ], + 'additionalProperties' => [ + 'context' => 'filter', + ], + 'required' => false, + ], + 'search' => [ + 'description' => 'Limit results to those matching a string.', + 'type' => 'string', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'form' => [ + 'description' => 'Limit result set to submissions assigned to specific forms. The form id should follow this pattern {post_id}_{element_id} e.g: 10_476d0ce', + 'type' => 'string', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'referer' => [ + 'description' => 'Limit result set to submissions assigned to specific referer.', + 'type' => 'string', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'after' => [ + 'description' => 'Limit response to submissions sent after a given ISO8601 compliant date.', + 'type' => 'string', + 'format' => 'date', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'before' => [ + 'description' => 'Limit response to submissions sent before a given ISO8601 compliant date.', + 'type' => 'string', + 'format' => 'date', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + ] ); + } + + public function get_items( $request ) { + $filters = []; + + // Get & set filters with values. + foreach ( $this->get_collection_params_by_additional_props_context( 'filter' ) as $collection_param_name => $collection_param_values ) { + $request_filter_value = $request->get_param( $collection_param_name ); + + if ( null !== $request_filter_value ) { + $collection_param_values['value'] = $request_filter_value; + + $filters[ $collection_param_name ] = $collection_param_values; + } + } + + $result = $this->query->get_submissions( [ + 'page' => $request->get_param( 'page' ), + 'per_page' => $request->get_param( 'per_page' ), + 'filters' => $filters, + 'order' => [ + 'order' => $request->get_param( 'order' ), + 'by' => $request->get_param( 'order_by' ), + ], + ] ); + + $result['meta']['count'] = $this->query + ->count_submissions_by_status( $filters ) + ->all(); + + return $result; + } + + public function get_item( $request ) { + return $this->query->get_submission( (int) $request->get_param( 'id' ) ); + } + + /** + * @param \WP_REST_Request $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function delete_items( $request ) { + return $this->delete( + $request->get_param( 'ids' ), + $request->get_param( 'force' ) + ); + } + + /** + * Delete single submission + * + * @param \WP_REST_Request $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function delete_item( $request ) { + return $this->delete( + [ $request->get_param( 'id' ) ], + $request->get_param( 'force' ) + ); + } + + /** + * Update a single submission. + * + * @param \WP_REST_Request $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function update_item( $request ) { + return $this->update( + [ (int) $request->get_param( 'id' ) ], + $request + ); + } + + /** + * Update multiple submissions. + * + * @param $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function update_items( $request ) { + return $this->update( + $request->get_param( 'ids' ), + $request + ); + } + + public function get_permission_callback( $request ) { + return current_user_can( 'manage_options' ); + } + + public function register_endpoints() { + $this->register_endpoint( Endpoints\Restore::class ); + $this->register_endpoint( Endpoints\Export::class ); + $this->register_endpoint( Endpoints\Referer::class ); + } + + protected function register_internal_endpoints() { + // Register as internal to remove the default endpoint generated by the base controller. + $this->register_endpoint( Endpoints\Index::class ); + } + + protected function register() { + parent::register(); + + $this->query = Query::get_instance(); + } + + /** + * Delete one or more submissions. + * + * @param array $ids + * @param false $force + * + * @return Query_Failed_Response|\WP_Error|\WP_REST_Response + */ + private function delete( array $ids, $force = false ) { + $affected = 0; + $failed = 0; + + foreach ( $ids as $id ) { + if ( $force ) { + $affected_rows = $this->query->delete_submission( $id ); + } else { + $affected_rows = $this->query->move_to_trash_submission( $id ); + } + + if ( false === $affected_rows ) { + $failed++; + } else { + $affected += $affected_rows; + } + } + + if ( count( $ids ) === $failed ) { + return new Query_Failed_Response( + $this->query->get_last_error() + ); + } + + if ( 1 === count( $ids ) && 0 === $affected ) { + return new \WP_Error( + 'rest_not_found', + __( 'Submission not found.', 'elementor-pro' ), + [ 'status' => 404 ] + ); + } + + return new \WP_REST_Response( [ + 'data' => [], + 'meta' => [ + 'affected' => $affected, + 'failed' => $failed, + ], + ], 200 ); + } + + /** + * Update one or more submissions. + * + * @param array $ids + * @param \WP_REST_Request $request + * + * @return Query_Failed_Response|\WP_Error|\WP_REST_Response + */ + private function update( array $ids, \WP_REST_Request $request ) { + $allowed_args = ( new Collection( $request->get_attributes()['args'] ) ) + ->except( [ 'id', 'ids', 'values' ] ) + ->keys() + ->all(); + + $data = ( new Collection( $request->get_body_params() ) ) + ->only( $allowed_args ) + ->all(); + + $values = $request->get_param( 'values' ); + + $affected = 0; + $failed = 0; + + foreach ( $ids as $id ) { + $affected_rows = $this->query->update_submission( $id, $data, $values ); + + if ( false === $affected_rows ) { + $failed++; + } else { + $affected += $affected_rows; + } + } + + if ( count( $ids ) === $failed ) { + return new Query_Failed_Response( + $this->query->get_last_error() + ); + } + + if ( 1 === count( $ids ) ) { + if ( 0 === $affected ) { + return new \WP_Error( + 'rest_not_found', + __( 'Submission not found.', 'elementor-pro' ), + [ 'status' => 404 ] + ); + } + + return new \WP_REST_Response( $this->query->get_submission( $ids[0] ) ); + } + + return new \WP_REST_Response( [ + 'data' => [], + 'meta' => [ + 'affected' => $affected, + 'failed' => $failed, + ], + ], 200 ); + } +} diff --git a/modules/forms/submissions/data/endpoints/export.php b/modules/forms/submissions/data/endpoints/export.php new file mode 100644 index 00000000..337eb7fe --- /dev/null +++ b/modules/forms/submissions/data/endpoints/export.php @@ -0,0 +1,134 @@ +register_route( + '', + \WP_REST_Server::READABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::READABLE, $request, true ); + }, + array_merge( $this->controller->get_collection_params(), [ + 'ids' => [ + 'description' => 'Unique identifiers for the objects.', + 'type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'format' => [ + 'description' => 'The format of the export (for now only csv).', + 'types' => 'string', + 'enum' => [ + 'csv', + ], + 'default' => 'csv', + 'required' => false, + ], + 'per_page' => [ + 'description' => 'Maximum number of items to be returned in result set.', + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 10000, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ], + ] ) + ); + } + + /** + * @param \WP_REST_Request $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function get_items( $request ) { + wp_raise_memory_limit( 'admin' ); + + $submissions = new Collection( + $this->get_submissions_by_filter( $request ) + ); + + if ( 0 === $submissions->count() ) { + return new \WP_Error( + 'nothing_to_export', + __( 'There is nothing to export.', 'elementor-pro' ), + [ 'status' => 400 ] + ); + } + + $response = $submissions + ->group_by( 'element_id' ) + ->map( function ( array $submissions_by_form ) { + $exporter = new CSV_Export( + new Collection( $submissions_by_form ) + ); + + return $exporter->prepare_for_json_response(); + } ); + + return new \WP_REST_Response([ + 'data' => $response->values(), + ] ); + } + + /** + * Get submissions by filter. + * + * @param $request + * + * @return array|mixed + */ + private function get_submissions_by_filter( $request ) { + $args = $request->get_attributes()['args']; + + $filters = ( new Collection( $request->get_query_params() ) ) + ->filter(function ( $value, $key ) use ( $args ) { + return isset( $args[ $key ]['additionalProperties']['context'] ) && + 'filter' === $args[ $key ]['additionalProperties']['context']; + }) + ->map( function ( $value ) use ( $request ) { + return [ 'value' => $value ]; + } ) + ->all(); + + return Query::get_instance()->get_submissions( + [ + 'page' => $request->get_param( 'page' ), + 'per_page' => $request->get_param( 'per_page' ), + 'filters' => $filters, + 'order' => [ + 'order' => $request->get_param( 'order' ), + 'by' => $request->get_param( 'order_by' ), + ], + 'with_meta' => true, + ] + )['data']; + } +} diff --git a/modules/forms/submissions/data/endpoints/forms-index.php b/modules/forms/submissions/data/endpoints/forms-index.php new file mode 100644 index 00000000..596c4380 --- /dev/null +++ b/modules/forms/submissions/data/endpoints/forms-index.php @@ -0,0 +1,35 @@ +register_route( + '', + \WP_REST_Server::READABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::READABLE, $request, true ); + }, + [ + 'context' => [ + 'description' => 'Scope under which the request is made, determines fields present in response. (only "options" available for now)', + 'type' => 'string', + 'enum' => [ + 'options', + ], + 'default' => 'options', + 'required' => false, + ], + ] + ); + } +} diff --git a/modules/forms/submissions/data/endpoints/index.php b/modules/forms/submissions/data/endpoints/index.php new file mode 100644 index 00000000..7bffae96 --- /dev/null +++ b/modules/forms/submissions/data/endpoints/index.php @@ -0,0 +1,146 @@ +register_route( + '', + \WP_REST_Server::READABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::READABLE, $request, true ); + }, + $this->controller->get_collection_params() + ); + + $this->register_route( + '(?P[\d]+)/', + \WP_REST_Server::READABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::READABLE, $request ); + }, + [ + 'id' => [ + 'description' => 'Unique identifier for the object.', + 'type' => 'string', + 'required' => true, + ], + ] + ); + + $this->register_route( + '(?P[\d]+)/', + \WP_REST_Server::DELETABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::DELETABLE, $request ); + }, + [ + 'id' => [ + 'description' => 'Unique identifier for the object.', + 'type' => 'string', + 'required' => true, + ], + 'force' => [ + 'description' => 'Delete the object permanently.', + 'type' => 'boolean', + 'required' => false, + ], + ] + ); + + $this->register_route( + '', + \WP_REST_Server::DELETABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::DELETABLE, $request, true ); + }, + [ + 'ids' => [ + 'description' => 'Unique identifiers for the objects.', + 'type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'validate_callback' => function ( $param ) { + return ! empty( $param ); + }, + 'required' => true, + ], + 'force' => [ + 'description' => 'Delete the object permanently.', + 'type' => 'boolean', + 'required' => false, + ], + ] + ); + + $this->register_route( + '(?P[\d]+)/', + \WP_REST_Server::EDITABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::EDITABLE, $request ); + }, + [ + 'id' => [ + 'description' => 'Unique identifier for the object.', + 'type' => 'string', + 'required' => true, + ], + 'is_read' => [ + 'description' => 'mark whether the submission was read or not', + 'type' => 'boolean', + 'required' => false, + ], + 'values' => [ + 'description' => 'Form field values, receive an array, the key should be the form field id and the value should be the value.', + 'type' => 'object', + 'required' => false, + 'sanitize_callback' => function ( $values ) { + $result = []; + + foreach ( $values as $key => $value ) { + $result[ $key ] = sanitize_text_field( $value ); + } + + return $result; + }, + ], + ] + ); + + $this->register_route( + '', + \WP_REST_Server::EDITABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::EDITABLE, $request, true ); + }, + [ + 'ids' => [ + 'description' => 'Unique identifiers for the objects.', + 'type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'validate_callback' => function ( $param ) { + return ! empty( $param ); + }, + 'required' => true, + ], + 'is_read' => [ + 'description' => 'mark whether the submission was read or not', + 'type' => 'boolean', + 'required' => false, + ], + ] + ); + } +} diff --git a/modules/forms/submissions/data/endpoints/referer.php b/modules/forms/submissions/data/endpoints/referer.php new file mode 100644 index 00000000..bd1fbfa2 --- /dev/null +++ b/modules/forms/submissions/data/endpoints/referer.php @@ -0,0 +1,70 @@ +register_route( + '', + \WP_REST_Server::READABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::READABLE, $request, true ); + }, + [ + 'context' => [ + 'description' => 'Scope under which the request is made, determines fields present in response. (only "options" available for now)', + 'type' => 'string', + 'enum' => [ + 'options', + ], + 'default' => 'options', + 'required' => false, + ], + 'search' => [ + 'description' => 'Limit results to those matching a string.', + 'type' => 'string', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + 'value' => [ + 'description' => 'Limit results specific referer.', + 'type' => 'string', + 'required' => false, + 'additionalProperties' => [ + 'context' => 'filter', + ], + ], + ] + ); + } + + public function get_items( $request ) { + $referrers = Query::get_instance()->get_referrers( + $request->get_param( 'search' ), + $request->get_param( 'value' ) + ); + + // For now return only as "options" + return [ + 'data' => $referrers->map(function ( $referer ) { + return [ + 'label' => $referer['referer_title'], + 'value' => $referer['referer'], + ]; + })->values(), + 'meta' => [], + ]; + } +} diff --git a/modules/forms/submissions/data/endpoints/restore.php b/modules/forms/submissions/data/endpoints/restore.php new file mode 100644 index 00000000..5c2ec273 --- /dev/null +++ b/modules/forms/submissions/data/endpoints/restore.php @@ -0,0 +1,136 @@ +restore( + [ $request->get_param( 'id' ) ] + ); + } + + /** + * Restore multiple trashed submissions. + * + * @param \WP_REST_Request $request + * + * @return \WP_Error|\WP_REST_Response + */ + public function update_items( $request ) { + return $this->restore( + $request->get_param( 'ids' ) + ); + } + + protected function register() { + $this->register_route( + '/(?P[\d]+)/', + \WP_REST_Server::EDITABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::EDITABLE, $request ); + }, + [ + 'id' => [ + 'description' => 'Unique identifier for the object.', + 'type' => 'string', + 'required' => true, + ], + ] + ); + + $this->register_route( + '', + \WP_REST_Server::EDITABLE, + function ( $request ) { + return $this->base_callback( \WP_REST_Server::EDITABLE, $request, true ); + }, + [ + 'ids' => [ + 'description' => 'Unique identifiers for the objects.', + 'type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'validate_callback' => function ( $param ) { + return ! empty( $param ); + }, + 'required' => true, + ], + ] + ); + } + + /** + * Restore on or more submissions. + * + * @param array $ids + * + * @return Query_Failed_Response|\WP_Error|\WP_REST_Response + */ + private function restore( array $ids ) { + $affected = 0; + $failed = 0; + + foreach ( $ids as $id ) { + $affected_rows = $this->query->restore( $id ); + + if ( false === $affected_rows ) { + $failed++; + } else { + $affected += $affected_rows; + } + } + + if ( count( $ids ) === $failed ) { + return new Query_Failed_Response( + $this->query->get_last_error() + ); + } + + if ( 1 === count( $ids ) && 0 === $affected ) { + return new \WP_Error( + 'rest_not_found', + __( 'Submission not found or not in trash.', 'elementor-pro' ), + [ 'status' => 404 ] + ); + } + + return new \WP_REST_Response( [ + 'data' => [], + 'meta' => [ + 'affected' => $affected, + 'failed' => $failed, + ], + ], 200 ); + } + + public function __construct( $controller ) { + $this->query = Query::get_instance(); + + parent::__construct( $controller ); + } +} diff --git a/modules/forms/submissions/data/forms-controller.php b/modules/forms/submissions/data/forms-controller.php new file mode 100644 index 00000000..f3710562 --- /dev/null +++ b/modules/forms/submissions/data/forms-controller.php @@ -0,0 +1,44 @@ +all(); + + // For now return only as "options" + return [ + 'data' => $forms->map(function ( Form_Snapshot $form ) { + return [ + 'label' => $form->get_label(), + 'value' => $form->get_key(), + ]; + })->values(), + 'meta' => [], + ]; + } + + public function register_endpoints() { + // + } + + protected function register_internal_endpoints() { + // Register as internal to remove the default endpoint generated by the base controller. + $this->register_endpoint( Endpoints\Forms_Index::class ); + } + + public function get_permission_callback( $request ) { + return current_user_can( 'manage_options' ); + } +} diff --git a/modules/forms/submissions/data/responses/query-failed-response.php b/modules/forms/submissions/data/responses/query-failed-response.php new file mode 100644 index 00000000..11134758 --- /dev/null +++ b/modules/forms/submissions/data/responses/query-failed-response.php @@ -0,0 +1,28 @@ +log_error( $query_error_message ); + + parent::__construct( + 'rest_internal_error', + $message, + [ 'status' => 500 ] + ); + } + + private function log_error( $query_error_message ) { + Plugin::elementor()->logger->error( $query_error_message ); + } +} diff --git a/modules/forms/submissions/database/entities/form-snapshot.php b/modules/forms/submissions/database/entities/form-snapshot.php new file mode 100644 index 00000000..f6ef3e44 --- /dev/null +++ b/modules/forms/submissions/database/entities/form-snapshot.php @@ -0,0 +1,92 @@ +post_id, $this->id ); + } + + /** + * @return string + */ + public function get_label() { + return "{$this->name} ($this->id)"; + } + + /** + * Implement for the JsonSerializable method, will trigger when trying to json_encode this object. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'fields' => $this->fields, + ]; + } + + + /** + * Form constructor. + * + * @param $post_id + * @param $data + */ + public function __construct( $post_id, $data ) { + $this->post_id = (int) $post_id; + $this->id = $data['id']; + $this->name = $data['name']; + $this->fields = $data['fields']; + } +} diff --git a/modules/forms/submissions/database/migration.php b/modules/forms/submissions/database/migration.php new file mode 100644 index 00000000..5514d041 --- /dev/null +++ b/modules/forms/submissions/database/migration.php @@ -0,0 +1,50 @@ + Migrations\Initial::class, + // It jumps from version 1 to 4 because some users already migrated the DB when the migrations system worked with the Elementor Pro version + // when the int value of the version "3.2.0" was 3. + 4 => Migrations\Referer_Extra::class, + 5 => Migrations\Fix_Indexes::class, + ]; + + /** + * Checks if there is a need to run migrations. + */ + public static function install() { + $installed_version = intval( get_option( self::OPTION_DB_VERSION ) ); + + // Up to date. Nothing to do. + if ( static::CURRENT_DB_VERSION <= $installed_version ) { + return; + } + + global $wpdb; + + ( new Collection( static::$migrations ) ) + ->filter( function ( $_, $version ) use ( $installed_version ) { + // Filter all the migrations that already done. + return $version > $installed_version; + } ) + ->map( function ( $migration_class_name, $version ) use ( $wpdb ) { + /** @var Migrations\Base_Migration $migration */ + $migration = new $migration_class_name( $wpdb ); + $migration->run(); + + // In case some migration failed it updates version every migration. + update_option( static::OPTION_DB_VERSION, $version ); + } ); + + update_option( static::OPTION_DB_VERSION, self::CURRENT_DB_VERSION ); + } +} diff --git a/modules/forms/submissions/database/migrations/base-migration.php b/modules/forms/submissions/database/migrations/base-migration.php new file mode 100644 index 00000000..dc218a19 --- /dev/null +++ b/modules/forms/submissions/database/migrations/base-migration.php @@ -0,0 +1,47 @@ +wpdb = $wpdb; + $this->query = Query::get_instance(); + } + + /** + * Run migration. + * + * @return void + */ + abstract public function run(); +} diff --git a/modules/forms/submissions/database/migrations/fix-indexes.php b/modules/forms/submissions/database/migrations/fix-indexes.php new file mode 100644 index 00000000..c627b825 --- /dev/null +++ b/modules/forms/submissions/database/migrations/fix-indexes.php @@ -0,0 +1,101 @@ +get_indexes(); + + foreach ( $indexes as $table => $table_indexes ) { + $existing_indexes = $this->get_existed_indexes_of( $table ); + + // Protect from database errors (for example: table do not exists somehow). + if ( null === $existing_indexes ) { + continue; + } + + $indexes_query = $table_indexes->except( $existing_indexes )->implode( ',' ); + + $this->wpdb->query( "ALTER TABLE `{$table}` {$indexes_query};" ); // phpcs:ignore + } + } + + /** + * Get the user exited indexes + * + * @param $table_name + * + * @return array|null + */ + private function get_existed_indexes_of( $table_name ) { + $result = $this->wpdb->get_results( "SHOW INDEX FROM {$table_name};", ARRAY_A ); // phpcs:ignore + + if ( false === $result ) { + return null; + } + + return ( new Collection( $result ) ) + ->map( function ( $row ) { + if ( ! isset( $row['Key_name'] ) ) { + return null; + } + + return $row['Key_name']; + } ) + ->filter() + ->values(); + } + + /** + * Get all the database indexes. + * + * @return Collection[] + */ + private function get_indexes() { + $max_index_length = static::MAX_INDEX_LENGTH; + + return [ + $this->query->get_table_submissions() => new Collection( [ + 'main_meta_id_index' => 'ADD INDEX `main_meta_id_index` (`main_meta_id`)', + 'hash_id_unique_index' => "ADD UNIQUE INDEX `hash_id_unique_index` (`hash_id` ({$max_index_length}))", + 'hash_id_index' => "ADD INDEX `hash_id_index` (`hash_id` ({$max_index_length}))", + 'type_index' => "ADD INDEX `type_index` (`type` ({$max_index_length}))", + 'post_id_index' => 'ADD INDEX `post_id_index` (`post_id`)', + 'element_id_index' => "ADD INDEX `element_id_index` (`element_id` ({$max_index_length}))", + 'campaign_id_index' => 'ADD INDEX `campaign_id_index` (`campaign_id`)', + 'user_id_index' => 'ADD INDEX `user_id_index` (`user_id`)', + 'user_ip_index' => 'ADD INDEX `user_ip_index` (`user_ip`)', + 'status_index' => 'ADD INDEX `status_index` (`status`)', + 'is_read_index' => 'ADD INDEX `is_read_index` (`is_read`)', + 'created_at_gmt_index' => 'ADD INDEX `created_at_gmt_index` (`created_at_gmt`)', + 'updated_at_gmt_index' => 'ADD INDEX `updated_at_gmt_index` (`updated_at_gmt`)', + 'created_at_index' => 'ADD INDEX `created_at_index` (`created_at`)', + 'updated_at_index' => 'ADD INDEX `updated_at_index` (`updated_at`)', + 'referer_index' => "ADD INDEX `referer_index` (`referer` ({$max_index_length}))", + 'referer_title_index' => "ADD INDEX `referer_title_index` (`referer_title` ({$max_index_length}))", + ] ), + $this->query->get_table_submissions_values() => new Collection( [ + 'submission_id_index' => 'ADD INDEX `submission_id_index` (`submission_id`)', + 'key_index' => "ADD INDEX `key_index` (`key` ({$max_index_length}))", + ] ), + $this->query->get_table_form_actions_log() => new Collection( [ + 'submission_id_index' => 'ADD INDEX `submission_id_index` (`submission_id`)', + 'action_name_index' => "ADD INDEX `action_name_index` (`action_name` ({$max_index_length}))", + 'status_index' => 'ADD INDEX `status_index` (`status`)', + 'created_at_gmt_index' => 'ADD INDEX `created_at_gmt_index` (`created_at_gmt`)', + 'updated_at_gmt_index' => 'ADD INDEX `updated_at_gmt_index` (`updated_at_gmt`)', + 'created_at_index' => 'ADD INDEX `created_at_index` (`created_at`)', + 'updated_at_index' => 'ADD INDEX `updated_at_index` (`updated_at`)', + ] ), + ]; + } +} diff --git a/modules/forms/submissions/database/migrations/initial.php b/modules/forms/submissions/database/migrations/initial.php new file mode 100644 index 00000000..0d5d14e1 --- /dev/null +++ b/modules/forms/submissions/database/migrations/initial.php @@ -0,0 +1,98 @@ +create_tables(); + $this->add_indexes(); + } + + private function create_tables() { + $charset_collate = $this->wpdb->get_charset_collate(); + + $e_submission_table = "CREATE TABLE `{$this->query->get_table_submissions()}` ( + id bigint(20) unsigned auto_increment primary key, + type varchar(60) null, + hash_id varchar(60) not null, + main_meta_id bigint(20) unsigned not null comment 'Id of main field. to represent the main meta field', + post_id bigint(20) unsigned not null, + referer varchar(500) not null, + element_id varchar(20) not null, + form_name varchar(60) not null, + campaign_id bigint(20) unsigned not null, + user_id bigint(20) unsigned null, + user_ip varchar(46) not null, + user_agent text not null, + actions_count INT DEFAULT 0, + actions_succeeded_count INT DEFAULT 0, + status varchar(20) not null, + is_read tinyint(1) default 0 not null, + meta text null, + created_at_gmt datetime not null, + updated_at_gmt datetime not null, + created_at datetime not null, + updated_at datetime not null + ) {$charset_collate};"; + + $e_submission_values_table = "CREATE TABLE `{$this->query->get_table_submissions_values()}` ( + id bigint(20) unsigned auto_increment primary key, + submission_id bigint(20) unsigned not null default 0, + `key` varchar(60) null, + value longtext null + ) {$charset_collate};"; + + $e_submission_actions_log_table = "CREATE TABLE `{$this->query->get_table_form_actions_log()}` ( + id bigint(20) unsigned auto_increment primary key, + submission_id bigint(20) unsigned not null, + action_name varchar(60) not null, + action_label varchar(60) null, + status varchar(20) not null, + log text null, + created_at_gmt datetime not null, + updated_at_gmt datetime not null, + created_at datetime not null, + updated_at datetime not null + ) {$charset_collate};"; + + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + dbDelta( $e_submission_table . $e_submission_values_table . $e_submission_actions_log_table ); + } + + private function add_indexes() { + // phpcs:disable + $this->wpdb->query( "ALTER TABLE `{$this->query->get_table_submissions()}` + ADD INDEX `main_meta_id_index` (`main_meta_id`), + ADD UNIQUE INDEX `hash_id_unique_index` (`hash_id`), + ADD INDEX `hash_id_index` (`hash_id`), + ADD INDEX `type_index` (`type`), + ADD INDEX `post_id_index` (`post_id`), + ADD INDEX `element_id_index` (`element_id`), + ADD INDEX `campaign_id_index` (`campaign_id`), + ADD INDEX `user_id_index` (`user_id`), + ADD INDEX `user_ip_index` (`user_ip`), + ADD INDEX `status_index` (`status`), + ADD INDEX `is_read_index` (`is_read`), + ADD INDEX `created_at_gmt_index` (`created_at_gmt`), + ADD INDEX `updated_at_gmt_index` (`updated_at_gmt`), + ADD INDEX `created_at_index` (`created_at`), + ADD INDEX `updated_at_index` (`updated_at`) + " ); + + $this->wpdb->query( "ALTER TABLE `{$this->query->get_table_submissions_values()}` + ADD INDEX `submission_id_index` (`submission_id`), + ADD INDEX `key_index` (`key`) + " ); + + $this->wpdb->query( "ALTER TABLE `{$this->query->get_table_form_actions_log()}` + ADD INDEX `submission_id_index` (`submission_id`), + ADD INDEX `action_name_index` (`action_name`), + ADD INDEX `status_index` (`status`), + ADD INDEX `created_at_gmt_index` (`created_at_gmt`), + ADD INDEX `updated_at_gmt_index` (`updated_at_gmt`), + ADD INDEX `created_at_index` (`created_at`), + ADD INDEX `updated_at_index` (`updated_at`) + " ); + // phpcs:enable + } +} diff --git a/modules/forms/submissions/database/migrations/referer-extra.php b/modules/forms/submissions/database/migrations/referer-extra.php new file mode 100644 index 00000000..8370dab6 --- /dev/null +++ b/modules/forms/submissions/database/migrations/referer-extra.php @@ -0,0 +1,21 @@ +wpdb->query(" + ALTER TABLE `{$this->query->get_table_submissions()}` + ADD COLUMN `referer_title` varchar(300) null AFTER `referer`; + "); + + $this->wpdb->query(" + ALTER TABLE `{$this->query->get_table_submissions()}` + ADD INDEX `referer_index` (`referer`({$max_index_length})), + ADD INDEX `referer_title_index` (`referer_title`({$max_index_length})); + "); + // phpcs:enable + } +} diff --git a/modules/forms/submissions/database/query.php b/modules/forms/submissions/database/query.php new file mode 100644 index 00000000..aec66f00 --- /dev/null +++ b/modules/forms/submissions/database/query.php @@ -0,0 +1,904 @@ + 1, + 'per_page' => 10, + 'filters' => [], + 'order' => [], + 'with_meta' => false, + 'with_form_fields' => false, + ] ); + + $page = $args['page']; + $per_page = $args['per_page']; + $filters = $args['filters']; + $order = $args['order']; + $with_meta = $args['with_meta']; + $with_form_fields = $args['with_form_fields']; + + $result = [ + 'data' => [], + 'meta' => [], + ]; + + $where_sql = $this->apply_filter( $filters ); + $order_sql = ''; + + $total = (int) $this->wpdb->get_var("SELECT COUNT(*) FROM `{$this->get_table_submissions()}` t_submissions {$where_sql}" );// phpcs:ignore + + $last_page = 0 < $total && 0 < $per_page ? (int) ceil( $total / $per_page ) : 1; + + if ( $page > $last_page ) { + $page = $last_page; + } + + $offset = (int) ceil( ( $page - 1 ) * $per_page ); + + $result['meta']['pagination'] = [ + 'current_page' => $page, + 'per_page' => $per_page, + 'total' => $total, + 'last_page' => $last_page, + ]; + + $this->handle_order( $order, $order_sql ); + + $per_page = (int) $per_page; + + $q = "SELECT t_submissions.* FROM `{$this->get_table_submissions()}` t_submissions {$where_sql} {$order_sql} LIMIT {$per_page} OFFSET {$offset}"; + + $submissions = $this->wpdb->get_results( $q );// phpcs:ignore + + $data = new Collection( [] ); + + foreach ( $submissions as $current_submission ) { + $data[] = $this->get_submission_body( $current_submission, $with_form_fields ); + } + + $submissions_meta = $this + ->get_submissions_meta( $data, ! $with_meta ) + ->group_by( 'submission_id' ); + + $result['data'] = $data + ->map( function ( $submission ) use ( $submissions_meta ) { + $current_submission_meta = $submissions_meta->get( $submission['id'], [] ); + + foreach ( $current_submission_meta as $meta ) { + $extract_meta = $this->extract( $meta, [ 'id', 'key', 'value' ], [ 'id:int' ] ); + + if ( $meta->id === $submission['main_meta_id'] ) { + $submission['main'] = $extract_meta; + } + + $submission['values'][] = $extract_meta; + } + + return $submission; + } ) + ->all(); + + return $result; + } + + /** + * Get count by status. + * + * @param $filter + * + * @return Collection + */ + public function count_submissions_by_status( $filter = [] ) { + // Should not filter by status. + unset( $filter['status'] ); + + $where_sql = $this->apply_filter( $filter ); + + $trash_status = '"' . static::STATUS_TRASH . '"'; + + $sql = " + SELECT + SUM(IF(`status` != {$trash_status}, 1, 0)) AS `all`, + SUM(IF(`status` = {$trash_status}, 1, 0)) AS `trash`, + SUM(IF(is_read = 1 AND `status` != {$trash_status}, 1, 0)) AS `read`, + SUM(IF(is_read = 0 AND `status` != {$trash_status}, 1, 0)) AS `unread` + FROM {$this->get_table_submissions()} AS `t_submissions` {$where_sql}; + "; + + $sql_result = $this->wpdb->get_row( $sql, ARRAY_A ); // phpcs:ignore + + $result = new Collection( [ + 'all' => 0, + 'trash' => 0, + 'read' => 0, + 'unread' => 0, + ] ); + + if ( ! $sql_result ) { + return $result; + } + + return $result->map( function ( $count, $key ) use ( $sql_result ) { + if ( ! isset( $sql_result[ $key ] ) ) { + return $count; + } + + return intval( $sql_result[ $key ] ); + } ); + } + + public function get_submissions_by_email( $email, $include_submission_values = false ) { + $user = get_user_by( 'email', $email ); + $user_filter = ''; + + if ( $user ) { + $user_filter = $this->wpdb->prepare( 't_submissions.user_id = %s OR', $user->ID ); + } + + $query = " + SELECT DISTINCT(t_submissions.id), t_submissions.* + FROM `{$this->get_table_submissions()}` t_submissions + INNER JOIN {$this->get_table_submissions_values()} t_submissions_meta + ON t_submissions.id = t_submissions_meta.submission_id + WHERE + {$user_filter} + t_submissions_meta.value = %s + ; + "; + + $data = $this->wpdb->get_results( + $this->wpdb->prepare( $query, $email ) // phpcs:ignore + ); + + if ( ! $data ) { + return new Collection( [] ); + } + + $data = new Collection( $data ); + + if ( $include_submission_values ) { + $submissions_meta = $this->get_submissions_meta( $data ) + ->group_by( 'submission_id' ); + + $data->map( function ( $submission ) use ( $submissions_meta ) { + $submission->values = $submissions_meta->get( $submission->id, [] ); + + return $submission; + } ); + } + + return $data; + } + + /** + * @param int $delete_timestamp + * + * @return array + */ + public function get_trashed_submission_ids_to_delete( $delete_timestamp ) { + $date = gmdate( 'Y-m-d H:i:s', $delete_timestamp ); + + $sql = " + SELECT s.id FROM `{$this->get_table_submissions()}` s + WHERE s.status = %s AND s.updated_at_gmt < %s; + "; + + return $this->wpdb->get_col( + $this->wpdb->prepare( $sql, static::STATUS_TRASH, $date ) // phpcs:ignore + ); + } + + public function get_submission( $id ) { + $result = [ + 'data' => [], + 'meta' => [], + ]; + + $q = "SELECT * FROM `{$this->get_table_submissions()}` WHERE id=%d"; + $submission = $this->wpdb->get_row( $this->wpdb->prepare( $q, [ $id ] ) );// phpcs:ignore + + if ( ! $submission ) { + return null; + } + + $result['data'] = $this->get_submission_body( $submission, true ); + + $current_submission_meta = $this->get_submissions_meta( $submission, false )->all(); + + foreach ( $current_submission_meta as $meta ) { + $extract_meta = $this->extract( $meta, [ 'id', 'key', 'value' ], [ 'id:int' ] ); + + if ( $meta->id === $result['data']['main_meta_id'] ) { + $result['data']['main'] = $extract_meta; + } + + $result['data']['values'][] = $extract_meta; + } + + $result['data']['form_actions_log'] = ( new Collection( $this->get_submissions_actions_log( $id ) ) ) + ->map( function ( $value ) { + return $this->extract( + $value, + [ 'id', 'action_name', 'action_label', 'status', 'log', 'created_at', 'updated_at' ], + [ 'id:int', 'name', 'label' ] + ); + } ) + ->all(); + + return $result; + } + + public function get_referrers( $search = '', $value = '' ) { + $where = ''; + + if ( $search ) { + $search = '%' . $this->wpdb->esc_like( $search ) . '%'; + + $where = $this->wpdb->prepare( ' AND s.referer_title LIKE %s', $search ); + } + + if ( $value ) { + $where = $this->wpdb->prepare( ' AND s.referer = %s', $value ); // phpcs:ignore + } + + $where = 'WHERE 1=1' . $where; + + $query = " + SELECT DISTINCT (s.referer), s.referer_title + FROM {$this->get_table_submissions()} s + {$where}; + "; + + $result = $this->wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore + + if ( ! $result ) { + return new Collection( [] ); + } + + return new Collection( $result ); + } + + /** + * @param $submissions + * @param false $only_main + * + * @return Collection + */ + public function get_submissions_meta( $submissions, $only_main = false ) { + if ( ! ( $submissions instanceof Collection ) ) { + $submissions = new Collection( + is_array( $submissions ) ? $submissions : [ $submissions ] + ); + } + + if ( $submissions->is_empty() ) { + return new Collection( [] ); + } + + if ( $only_main ) { + $column = 'id'; + $ids = $submissions->pluck( 'main_meta_id' ); + } else { + $column = 'submission_id'; + $ids = $submissions->pluck( 'id' ); + } + + $placeholders = $ids->map( function () { + return '%d'; + } )->implode( ',' ); + + $q = "SELECT * FROM `{$this->get_table_submissions_values()}` WHERE `{$column}` IN ({$placeholders})"; + + $result = $this->wpdb->get_results( $this->wpdb->prepare( $q, $ids->all() ) ); // phpcs:ignore + + if ( ! $result ) { + return new Collection( [] ); + } + + return new Collection( $result ); + } + + /** + * @param $post_id + * @param $element_id + * + * @return Collection + */ + public function get_submissions_value_keys( $post_id, $element_id ) { + $sql = " + SELECT DISTINCT(wesv.`key`) + FROM {$this->get_table_submissions_values()} wesv + INNER JOIN {$this->get_table_submissions()} wes + ON wes.id = wesv.submission_id + WHERE wes.post_id = %s AND wes.element_id = %s; + "; + + $result = $this->wpdb->get_col( $this->wpdb->prepare( $sql, $post_id, $element_id ) ); // phpcs:ignore + + $form = Form_Snapshot_Repository::instance()->find( $post_id, $element_id ); + if ( $form ) { + $ordered_keys = array_map( function( $field ) { + return $field['id']; + }, $form->fields ); + + $result = array_merge( array_intersect( $ordered_keys, $result ), array_diff( $result, $ordered_keys ) ); + } + + if ( ! $result ) { + return new Collection( [] ); + } + + return new Collection( $result ); + } + + /** + * @param $submission_id + * + * @return array|null + */ + public function get_submissions_actions_log( $submission_id ) { + $query = "SELECT * FROM `{$this->get_table_form_actions_log()}` WHERE `submission_id` = %d;"; + + return $this->wpdb->get_results( + $this->wpdb->prepare( $query, (int) $submission_id ), // phpcs:ignore + ARRAY_A + ); + } + + /** + * Add submission. + * + * @param array $submission_data + * @param array $fields_data + * + * @return int id or 0 + */ + public function add_submission( array $submission_data, array $fields_data ) { + global $wpdb; + + $result = 0; + + $submission_data = $this->get_new_submission_initial_data( $submission_data ); + + try { + $wpdb->query( 'START TRANSACTION' ); + + $submission_success = $wpdb->insert( $this->get_table_submissions(), $submission_data ); + + if ( ! $submission_success ) { + throw new Exception( $wpdb->last_error ); + } + + $submission_id = $wpdb->insert_id; + + // Meta's keys/values. + $main_meta_id = 0; + $first_submissions_meta_id = 0; + foreach ( $fields_data as $field ) { + $wpdb->insert( $this->get_table_submissions_values(), [ + 'submission_id' => $submission_id, + 'key' => $field['id'], + 'value' => $field['value'], + ] ); + + if ( ! $first_submissions_meta_id ) { + $first_submissions_meta_id = $wpdb->insert_id; + } + + if ( 0 === $main_meta_id && 'email' === $field['type'] ) { + $main_meta_id = $wpdb->insert_id; + } + } + + // If `$main_meta_id` not determined. + if ( ! $main_meta_id ) { + $main_meta_id = $first_submissions_meta_id; + } + + // Update main_meta_id. + $wpdb->update( $this->get_table_submissions(), + [ + 'main_meta_id' => $main_meta_id, + ], + [ + 'id' => $submission_id, + ] + ); + + $wpdb->query( 'COMMIT' ); + + $result = $submission_id; + } catch ( Exception $e ) { + $wpdb->query( 'ROLLBACK' ); + + Plugin::elementor()->logger->get_logger()->error( 'Save submission failed, db error: ' . $e->getMessage() ); + } + + return $result; + } + + /** + * @param $submission_id + * @param array $data + * @param array $values + * + * @return bool|int affected rows + */ + public function update_submission( $submission_id, array $data, $values = [] ) { + if ( $values ) { + foreach ( $values as $key => $value ) { + $this->wpdb->update( + $this->get_table_submissions_values(), + [ 'value' => $value ], + [ + 'submission_id' => $submission_id, + 'key' => $key, + ] + ); + } + } + + $data['updated_at_gmt'] = current_time( 'mysql', true ); + $data['updated_at'] = get_date_from_gmt( $data['updated_at_gmt'] ); + + return $this->wpdb->update( + $this->get_table_submissions(), + $data, + [ 'id' => $submission_id ] + ); + } + + /** + * Move single submission to trash + * + * @param $id + * + * @return bool|int number of affected rows or false if failed + */ + public function move_to_trash_submission( $id ) { + return $this->update_submission( + $id, + [ 'status' => static::STATUS_TRASH ] + ); + } + + /** + * Delete a single submission. + * + * @param $id + * + * @return bool|int number of affected rows or false if failed + */ + public function delete_submission( $id ) { + $this->wpdb->delete( + $this->get_table_submissions_values(), + [ 'submission_id' => $id ] + ); + + $this->wpdb->delete( + $this->get_table_form_actions_log(), + [ 'submission_id' => $id ] + ); + + return $this->wpdb->delete( + $this->get_table_submissions(), + [ 'id' => $id ] + ); + } + + /** + * Restore a single submission. + * + * @param $id + * + * @return bool|int number of affected rows or false if failed + */ + public function restore( $id ) { + return $this->wpdb->update( + $this->get_table_submissions(), + [ 'status' => self::STATUS_NEW ], + [ 'id' => $id ] + ); + } + + /** + * @param $submission_id + * @param Action_Base $action Should be class based on ActionBase (do not type hint to support third party plugins) + * @param $status + * @param null $log_message + * + * @return bool|int + */ + public function add_action_log( $submission_id, $action, $status, $log_message = null ) { + $current_datetime_gmt = current_time( 'mysql', true ); + $current_datetime = get_date_from_gmt( $current_datetime_gmt ); + + return $this->wpdb->insert( + $this->get_table_form_actions_log(), + [ + 'submission_id' => $submission_id, + 'action_name' => $action->get_name(), + 'action_label' => $action->get_label(), + 'status' => $status, + 'log' => $log_message, + 'created_at_gmt' => $current_datetime_gmt, + 'updated_at_gmt' => $current_datetime_gmt, + 'created_at' => $current_datetime, + 'updated_at' => $current_datetime, + ] + ); + } + + public function get_last_error() { + $this->wpdb->last_error; + } + + public function get_table_submissions() { + return $this->table_submissions; + } + + public function get_table_submissions_values() { + return $this->table_submissions_values; + } + + public function get_table_form_actions_log() { + return $this->table_submissions_actions_log; + } + + /** + * Extract data from `$target` by selected `$keys`. + * `$as` used to convert extracted data with different keys. + * `$as` support converting to types. using ':' after the key name. + * + * Example: `$target = [ 'someId' => '5' ];` + * `$keys = [ 'someId' ]` + * `$as = [ 'id:int' ]` + * Output will be `[ 'id' => 5 ];` + * + * @param array|\stdClass $target + * @param array $keys + * @param array $as + * + * @return array + */ + private function extract( $target, $keys, $as = [] ) { + $result = []; + + $as_types = []; + $as_count = 0; + + if ( is_object( $target ) ) { + $target = (array) $target; + } + + foreach ( $as as $key => $as_item ) { + $exploded = explode( ':', $as_item ); + + if ( count( $exploded ) > 1 ) { + $as_types [] = $exploded[1]; + $as[ $key ] = $exploded[0]; + } + } + + foreach ( $keys as $key ) { + if ( isset( $target[ $key ] ) ) { + if ( isset( $as[ $as_count ] ) ) { + $value = $target[ $key ]; + if ( isset( $as_types[ $as_count ] ) ) { + settype( $value, $as_types[ $as_count ] ); + } + $result[ $as[ $as_count ] ] = $value; + } else { + $result[ $key ] = $target[ $key ]; + } + } + ++$as_count; + } + + return $result; + } + + private function handle_and_for_where_query( &$target_where_query ) { + if ( $target_where_query ) { + $target_where_query .= ' AND '; + } + } + + private function filter_after_and_before( $filters, &$target_where_query ) { + // Filters 'after' & 'before' known in advance, and could handled systematically. + if ( isset( $filters['after'] ) || isset( $filters['before'] ) ) { + $this->handle_and_for_where_query( $target_where_query ); + + // TODO: This logic applies only for 'date' format not 'date-time' format. + $after = '0000-01-01 00:00:00'; + $before = '9999-12-31 23:59:59'; + + if ( isset( $filters['after'] ) ) { + $after = $filters['after']['value'] . ' 00:00:00'; + } + + if ( isset( $filters['before'] ) ) { + $before = $filters['before']['value'] . ' 23:59:59'; + } + + $after = get_gmt_from_date( $after ); + $before = get_gmt_from_date( $before ); + + $target_where_query .= $this->wpdb->prepare( 'created_at_gmt BETWEEN %s and %s', [ $after, $before ] ); + } + } + + private function filter_status( $filters, &$target_where_query ) { + if ( isset( $filters['status'] ) ) { + $this->handle_and_for_where_query( $target_where_query ); + + switch ( $filters['status']['value'] ) { + case 'all': + $target_where_query .= 'status != \'' . self::STATUS_TRASH . '\''; + break; + case 'unread': + $target_where_query .= 'status = \'' . self::STATUS_NEW . '\' AND is_read = 0'; + break; + case 'read': + $target_where_query .= 'status = \'' . self::STATUS_NEW . '\' AND is_read > 0'; + break; + case 'trash': + $target_where_query .= 'status = \'' . self::STATUS_TRASH . '\''; + break; + } + } + } + + private function filter_ids( $filters, &$target_where_query ) { + if ( ! isset( $filters['ids'] ) || empty( $filters['ids'] ) ) { + return; + } + + $this->handle_and_for_where_query( $target_where_query ); + + $ids_collection = new Collection( $filters['ids']['value'] ); + + $placeholder = $ids_collection->map( function () { + return '%d'; + } )->implode( ', ' ); + + $target_where_query .= $this->wpdb->prepare( "`id` IN ({$placeholder})", $ids_collection->all() ); // phpcs:ignore + } + + private function filter_search( $filters, &$target_where_query ) { + if ( isset( $filters['search'] ) ) { + $this->handle_and_for_where_query( $target_where_query ); + + $like = '%' . $this->wpdb->esc_like( $filters['search']['value'] ) . '%'; + $meta_table_name = $this->get_table_submissions_values(); + + $search = $this->wpdb->prepare( 'LIKE %s OR t_submissions.id LIKE %s', [ $like, $like ] ); + + $target_where_query .= "( + ( + SELECT GROUP_CONCAT({$meta_table_name}.value) + FROM `{$meta_table_name}` + WHERE {$meta_table_name}.submission_id = t_submissions.id + GROUP BY {$meta_table_name}.submission_id + ) {$search} + )"; + } + } + + /** + * Filter bu element_id and post_id + * + * @param $filters + * @param $target_where_query + */ + private function filter_by_form( $filters, &$target_where_query ) { + if ( ! isset( $filters['form']['value'] ) ) { + return; + } + + $this->handle_and_for_where_query( $target_where_query ); + + list( $post_id, $form_id ) = explode( '_', $filters['form']['value'] ); + + $target_where_query .= $this->wpdb->prepare( + 'post_id = %d AND element_id = %s', + $post_id, + $form_id + ); + } + + /** + * @param $filters + * @param $target_where_query + */ + private function filter_by_referer( $filters, &$target_where_query ) { + if ( ! isset( $filters['referer']['value'] ) ) { + return; + } + + $this->handle_and_for_where_query( $target_where_query ); + + $target_where_query .= $this->wpdb->prepare( + 'referer = %s', + $filters['referer']['value'] + ); + } + + private function handle_order( $order, &$target_order_query ) { + if ( ! empty( $order ) ) { + $order['by'] = esc_sql( $order['by'] ); + $order['order'] = strtoupper( $order['order'] ); + + if ( ! in_array( $order['order'], [ 'ASC', 'DESC' ], true ) ) { + $order['order'] = 'ASC'; + } + + $target_order_query = 'ORDER BY ' . $order['by'] . ' ' . $order['order']; + } + } + + /** + * @param \stdClass $submission + * @param bool $with_form_fields + * + * @return array + */ + private function get_submission_body( $submission, $with_form_fields = false ) { + $id = (int) $submission->id; + + $result = [ + 'id' => $id, + ]; + + $result['post'] = $this->extract( $submission, [ 'post_id' ], [ 'id:int' ] ); + $result['form'] = $this->extract( $submission, [ 'form_name', 'element_id' ], [ 'name' ] ); + + $edit_post_id = $submission->post_id; + + // TODO: Should be removed if there is an ability to edit "global widgets" + $meta = json_decode( $submission->meta ?? '', true ); + + if ( isset( $meta['edit_post_id'] ) ) { + $edit_post_id = $meta['edit_post_id']; + } + + $document = Plugin::elementor()->documents->get( $edit_post_id ); + + if ( $document ) { + $result['post']['edit_url'] = $document->get_edit_url(); + } + + if ( $with_form_fields ) { + $form = Form_Snapshot_Repository::instance() + ->find( $submission->post_id, $submission->element_id ); + + if ( $form ) { + $result['form']['fields'] = $form->fields; + } + } + + $user = get_user_by( 'id', $submission->user_id ); + + $result['actions_count'] = (int) $submission->actions_count; + $result['actions_succeeded_count'] = (int) $submission->actions_succeeded_count; + $result['referer'] = $submission->referer; + $result['referer_title'] = $submission->referer_title; + $result['element_id'] = $submission->element_id; + $result['main_meta_id'] = $submission->main_meta_id; + $result['user_id'] = $submission->user_id; + $result['user_agent'] = $submission->user_agent; + $result['user_ip'] = $submission->user_ip; + $result['user_name'] = $user ? $user->display_name : null; + + $result['created_at_gmt'] = $submission->created_at_gmt; + $result['updated_at_gmt'] = $submission->updated_at_gmt; + + // Return the the dates according to WP current selected timezone. + $result['created_at'] = get_date_from_gmt( $submission->created_at_gmt ); + $result['updated_at'] = get_date_from_gmt( $submission->updated_at_gmt ); + + $result['status'] = $submission->status; + $result['is_read'] = (bool) $submission->is_read; + + return $result; + } + + private function get_new_submission_initial_data( array $submission_data ) { + $current_datetime_gmt = current_time( 'mysql', true ); + $current_datetime = get_date_from_gmt( $current_datetime_gmt ); + + $submission_data['hash_id'] = wp_generate_uuid4(); + + $submission_data = array_merge( [ + 'created_at_gmt' => $current_datetime_gmt, + 'updated_at_gmt' => $current_datetime_gmt, + 'created_at' => $current_datetime, + 'updated_at' => $current_datetime, + 'type' => self::TYPE_SUBMISSION, + 'status' => self::STATUS_NEW, + ], $submission_data ); + + return $submission_data; + } + + private function apply_filter( array $filter ) { + $where_sql = ''; + + $this->filter_after_and_before( $filter, $where_sql ); + $this->filter_status( $filter, $where_sql ); + $this->filter_search( $filter, $where_sql ); + $this->filter_by_form( $filter, $where_sql ); + $this->filter_ids( $filter, $where_sql ); + $this->filter_by_referer( $filter, $where_sql ); + + if ( ! $where_sql ) { + return ''; + } + + return 'WHERE ' . $where_sql; + } + + public function __construct() { + global $wpdb; + + $this->wpdb = $wpdb; + + $this->table_submissions = $wpdb->prefix . self::E_SUBMISSIONS; + $this->table_submissions_values = $wpdb->prefix . self::E_SUBMISSIONS_VALUES; + $this->table_submissions_actions_log = $wpdb->prefix . self::E_SUBMISSIONS_ACTIONS_LOG; + } +} diff --git a/modules/forms/submissions/database/repositories/form-snapshot-repository.php b/modules/forms/submissions/database/repositories/form-snapshot-repository.php new file mode 100644 index 00000000..5a0a93a2 --- /dev/null +++ b/modules/forms/submissions/database/repositories/form-snapshot-repository.php @@ -0,0 +1,168 @@ +cache->get( $key, false ) ) { + return $this->cache->get( $key, false ); + } + + return $this->save_in_cache( + $this->get_post_forms( $post_id ) + )->get( $key ); + } + + /** + * Get all the forms. + * + * @return Collection + */ + public function all() { + global $wpdb; + + $result = $wpdb->get_results( + $wpdb->prepare( + "SELECT pm.meta_value, pm.post_id FROM {$wpdb->postmeta} pm WHERE pm.meta_key = %s", + static::POST_META_KEY + ) + ); + + if ( ! $result ) { + return new Collection( [] ); + } + + foreach ( $result as $post_forms ) { + $this->save_in_cache( + $this->parse_meta( $post_forms->meta_value, $post_forms->post_id ) + ); + } + + return $this->cache; + } + + /** + * @param $post_id + * @param $form_id + * @param $data + * + * @return Form_Snapshot + */ + public function create_or_update( $post_id, $form_id, $data ) { + $forms = $this->get_post_forms( $post_id ) + ->filter( function ( Form_Snapshot $form ) use ( $form_id ) { + return $form->id !== $form_id; + } ); + + $form = new Form_Snapshot( $post_id, $data + [ 'id' => $form_id ] ); + $forms[] = $form; + + update_post_meta( + $post_id, + self::POST_META_KEY, + // Use `wp_slash` in order to avoid the unslashing during the `update_post_meta` + wp_slash( wp_json_encode( $forms->values() ) ) + ); + + $this->save_in_cache( $forms ); + + return $form; + } + + public function clear_cache() { + $this->cache = new Collection( [] ); + } + + /** + * @param $post_id + * + * @return Collection + */ + private function get_post_forms( $post_id ) { + $meta_value = get_post_meta( $post_id, self::POST_META_KEY, true ); + + if ( ! $meta_value ) { + return new Collection( [] ); + } + + return $this->parse_meta( $meta_value, $post_id ); + } + + /** + * Receive a meta value and transform it to an array of Form objects. + * + * @param $meta_value + * @param $post_id + * + * @return Collection + */ + private function parse_meta( $meta_value, $post_id ) { + return ( new Collection( json_decode( $meta_value, true ) ) ) + ->map( function ( $item ) use ( $post_id ) { + return new Form_Snapshot( $post_id, $item ); + } ); + } + + /** + * @param $forms + * + * @return Collection + */ + private function save_in_cache( Collection $forms ) { + /** @var Form_Snapshot $form */ + foreach ( $forms as $form ) { + $this->cache[ $form->get_key() ] = $form; + } + + return $this->cache; + } + + /** + * Forms_Repository constructor. + */ + public function __construct() { + $this->cache = new Collection( [] ); + } +} diff --git a/modules/forms/submissions/export/csv-export.php b/modules/forms/submissions/export/csv-export.php new file mode 100644 index 00000000..bb281c52 --- /dev/null +++ b/modules/forms/submissions/export/csv-export.php @@ -0,0 +1,186 @@ +submissions = $submissions; + + $first_submission = $this->submissions->first(); + + $this->values_keys = new Collection( [] ); + $this->post_id = $first_submission['post']['id']; + $this->element_id = $first_submission['element_id']; + + $this->form = Form_Snapshot_Repository::instance()->find( + $this->post_id, + $this->element_id + ); + } + + /** + * @return array + */ + public function prepare_for_json_response() { + $this->values_keys = Query::get_instance()->get_submissions_value_keys( + $this->post_id, + $this->element_id + ); + + $headers = $this->get_headers(); + $rows = $this->get_rows(); + + return [ + 'id' => $this->element_id, + 'content' => array_merge( $headers, $rows ), + 'mimetype' => 'text/csv;charset=UTF-8', + 'extension' => 'csv', + 'form_label' => $this->form ? $this->form->get_label() : "({$this->element_id})", + ]; + } + + /** + * @return array + */ + private function get_headers() { + $base_headers = [ + '1_form_name' => esc_html__( 'Form Name (ID)', 'elementor-pro' ), + '2_id' => esc_html__( 'Submission ID', 'elementor-pro' ), + '3_created_at' => esc_html__( 'Created At', 'elementor-pro' ), + '4_user_id' => esc_html__( 'User ID', 'elementor-pro' ), + '5_user_agent' => esc_html__( 'User Agent', 'elementor-pro' ), + '6_user_ip' => esc_html__( 'User IP', 'elementor-pro' ), + '7_referrer' => esc_html__( 'Referrer', 'elementor-pro' ), + ]; + + $labels_dictionary = $this->get_form_labels_dictionary(); + + $headers = $this->values_keys + ->map_with_keys( function ( $key ) use ( $labels_dictionary ) { + return [ + // JSON_UNESCAPED_UNICODE - for supporting non english chars. + $key => wp_json_encode( isset( $labels_dictionary[ $key ] ) ? $labels_dictionary[ $key ] : $key, JSON_UNESCAPED_UNICODE ), + ]; + } ) + ->merge( $base_headers ) + ->all(); + + return [ implode( ',', $headers ) ]; + } + + /** + * @return array + */ + private function get_rows() { + return $this->submissions->map( function ( $submission ) { + $base_values = [ + '1_form_name' => wp_json_encode( + $this->form ? $this->form->get_label() : "({$this->element_id})" + ), + '2_id' => wp_json_encode( $submission['id'] ), + '3_created_at' => wp_json_encode( $submission['created_at'] ), + '4_user_id' => wp_json_encode( $submission['user_id'] ), + // JSON_UNESCAPED_SLASHES - Should not escape the user agent e.g: 'Mozilla/5.0 ...' + '5_user_agent' => wp_json_encode( $submission['user_agent'], JSON_UNESCAPED_SLASHES ), + '6_user_ip' => wp_json_encode( $submission['user_ip'] ), + // JSON_UNESCAPED_SLASHES - should not escape the url slashes e.g: 'https://local.test/' + '7_referrer' => wp_json_encode( $submission['referer'], JSON_UNESCAPED_SLASHES ), + ]; + + $values_dictionary = $this->get_values_dictionary( $submission['values'] ); + + $row = $this->values_keys + ->map_with_keys( function ( $key ) use ( $values_dictionary ) { + return [ + // JSON_UNESCAPED_UNICODE - for supporting non english chars. + $key => wp_json_encode( isset( $values_dictionary[ $key ] ) ? $values_dictionary[ $key ] : '', JSON_UNESCAPED_UNICODE ), + ]; + } ) + ->merge( $base_values ) + ->all(); + + return implode( ',', $row ); + } )->all(); + } + + /** + * Create a dictionary from the field id and label. + * + * @return array + */ + private function get_form_labels_dictionary() { + if ( ! $this->form ) { + return []; + } + + $dictionary = []; + + foreach ( $this->form->fields as $field ) { + $dictionary[ $field['id'] ] = $field['label']; + } + + return $dictionary; + } + + /** + * Create a dictionary from the value record key and value. + * + * @param array $values + * + * @return array + */ + private function get_values_dictionary( $values ) { + if ( ! $values ) { + return []; + } + + $dictionary = []; + + foreach ( $values as $value ) { + $dictionary[ $value['key'] ] = $value['value']; + } + + return $dictionary; + } +} diff --git a/modules/forms/submissions/personal-data.php b/modules/forms/submissions/personal-data.php new file mode 100644 index 00000000..aacad23e --- /dev/null +++ b/modules/forms/submissions/personal-data.php @@ -0,0 +1,179 @@ +get_submissions_by_email( $email, true ) + ->map(function ( $submission ) { + $submission_data = ( new Collection( $submission->values ) ) + ->map( function ( $value ) { + return [ + 'name' => $value->key, + 'value' => $value->value, + ]; + } ) + ->merge([ + [ + 'name' => esc_html__( 'User IP', 'elementor-pro' ), + 'value' => $submission->user_ip, + ], + [ + 'name' => esc_html__( 'Referer', 'elementor-pro' ), + 'value' => $submission->referer, + ], + [ + 'name' => esc_html__( 'User Agent', 'elementor-pro' ), + 'value' => $submission->user_agent, + ], + [ + 'name' => esc_html__( 'Created At', 'elementor-pro' ), + 'value' => $submission->created_at, + ], + [ + 'name' => esc_html__( 'Created At GMT', 'elementor-pro' ), + 'value' => $submission->created_at_gmt, + ], + [ + 'name' => esc_html__( 'Updated At', 'elementor-pro' ), + 'value' => $submission->updated_at, + ], + [ + 'name' => esc_html__( 'Updated At GMT', 'elementor-pro' ), + 'value' => $submission->updated_at_gmt, + ], + ]) + ->all(); + + return [ + 'group_id' => $this->get_key(), + 'group_label' => $this->get_title(), + 'item_id' => "{$this->get_key()}-{$submission->id}", + 'data' => $submission_data, + ]; + }) + ->all(); + + return [ + 'data' => $data, + 'done' => true, + ]; + } + + /** + * Erase all the submissions related to specific email. + * + * WordPress send always an email even if the user choose to erase by username. + * + * @param $email + * + * @return array + */ + private function erase_data( $email ) { + $query = Query::get_instance(); + + $submissions = $query->get_submissions_by_email( $email, true ); + + $affected = 0; + $failed = 0; + + foreach ( $submissions as $submission ) { + $affected_rows = $query->delete_submission( $submission->id ); + + if ( false === $affected_rows ) { + $failed++; + } else { + $affected += $affected_rows; + } + } + + return [ + 'items_removed' => count( $submissions ) === $affected, + 'items_retained' => $failed > 0, + 'messages' => [], + 'done' => true, + ]; + } + + /** + * Add exporter to the list of exporters + * + * @param $exporters + * + * @return mixed + */ + private function add_exporter( $exporters ) { + $exporters[ $this->get_key() ] = [ + 'exporter_friendly_name' => $this->get_title(), + 'callback' => function ( $email ) { + return $this->export_data( $email ); + }, + ]; + + return $exporters; + } + + /** + * Add eraser to the list of erasers. + * + * @param $erasers + * + * @return array[] + */ + private function add_eraser( $erasers ) { + return $erasers + [ + $this->get_key() => [ + 'eraser_friendly_name' => $this->get_title(), + 'callback' => function ( $email ) { + return $this->erase_data( $email ); + }, + ], + ]; + } + + /** + * Personal_Data constructor. + */ + public function __construct() { + add_filter( 'wp_privacy_personal_data_exporters', function ( $exporters ) { + return $this->add_exporter( $exporters ); + } ); + + add_filter( 'wp_privacy_personal_data_erasers', function ( $exporters ) { + return $this->add_eraser( $exporters ); + } ); + } +} diff --git a/modules/forms/widgets/form.php b/modules/forms/widgets/form.php new file mode 100644 index 00000000..57046001 --- /dev/null +++ b/modules/forms/widgets/form.php @@ -0,0 +1,2795 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-form' ]; + } + + protected function register_controls() { + $repeater = new Repeater(); + + $field_types = [ + 'text' => esc_html__( 'Text', 'elementor-pro' ), + 'email' => esc_html__( 'Email', 'elementor-pro' ), + 'textarea' => esc_html__( 'Textarea', 'elementor-pro' ), + 'url' => esc_html__( 'URL', 'elementor-pro' ), + 'tel' => esc_html__( 'Tel', 'elementor-pro' ), + 'radio' => esc_html__( 'Radio', 'elementor-pro' ), + 'select' => esc_html__( 'Select', 'elementor-pro' ), + 'checkbox' => esc_html__( 'Checkbox', 'elementor-pro' ), + 'acceptance' => esc_html__( 'Acceptance', 'elementor-pro' ), + 'number' => esc_html__( 'Number', 'elementor-pro' ), + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'time' => esc_html__( 'Time', 'elementor-pro' ), + 'upload' => esc_html__( 'File Upload', 'elementor-pro' ), + 'password' => esc_html__( 'Password', 'elementor-pro' ), + 'html' => esc_html__( 'HTML', 'elementor-pro' ), + 'hidden' => esc_html__( 'Hidden', 'elementor-pro' ), + ]; + + /** + * Forms field types. + * + * Filters the list of field types displayed in the form `field_type` control. + * + * This hook allows developers to alter the list of displayed field types. For + * example, removing the 'upload' field type from the list of fields types will + * prevent uploading files using Elementor forms. + * + * @since 1.0.0 + * + * @param array $field_types Field types. + */ + $field_types = apply_filters( 'elementor_pro/forms/field_types', $field_types ); + + $repeater->start_controls_tabs( 'form_fields_tabs' ); + + $repeater->start_controls_tab( 'form_fields_content_tab', [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'field_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $field_types, + 'default' => 'text', + ] + ); + + $repeater->add_control( + 'field_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'placeholder', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => 'in', + 'value' => [ + 'tel', + 'text', + 'email', + 'textarea', + 'number', + 'url', + 'password', + ], + ], + ], + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'required', + [ + 'label' => esc_html__( 'Required', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'true', + 'default' => '', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => '!in', + 'value' => [ + 'checkbox', + 'recaptcha', + 'recaptcha_v3', + 'hidden', + 'html', + 'step', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'field_options', + [ + 'label' => esc_html__( 'Options', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => '', + 'description' => esc_html__( 'Enter each option in a separate line. To differentiate between label and value, separate them with a pipe char ("|"). For example: First Name|f_name', 'elementor-pro' ), + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => 'in', + 'value' => [ + 'select', + 'checkbox', + 'radio', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'allow_multiple', + [ + 'label' => esc_html__( 'Multiple Selection', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'true', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'select', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'select_size', + [ + 'label' => esc_html__( 'Rows', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 2, + 'step' => 1, + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'select', + ], + [ + 'name' => 'allow_multiple', + 'value' => 'true', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'inline_list', + [ + 'label' => esc_html__( 'Inline List', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'elementor-subgroup-inline', + 'default' => '', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => 'in', + 'value' => [ + 'checkbox', + 'radio', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'field_html', + [ + 'label' => esc_html__( 'HTML', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'html', + ], + ], + ], + ] + ); + + $repeater->add_responsive_control( + 'width', + [ + 'label' => esc_html__( 'Column Width', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + '100' => '100%', + '80' => '80%', + '75' => '75%', + '70' => '70%', + '66' => '66%', + '60' => '60%', + '50' => '50%', + '40' => '40%', + '33' => '33%', + '30' => '30%', + '25' => '25%', + '20' => '20%', + ], + 'default' => '100', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => '!in', + 'value' => [ + 'hidden', + 'recaptcha', + 'recaptcha_v3', + 'step', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'rows', + [ + 'label' => esc_html__( 'Rows', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 4, + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'textarea', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'recaptcha_size', [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'normal', + 'options' => [ + 'normal' => esc_html__( 'Normal', 'elementor-pro' ), + 'compact' => esc_html__( 'Compact', 'elementor-pro' ), + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'recaptcha', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'recaptcha_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'light', + 'options' => [ + 'light' => esc_html__( 'Light', 'elementor-pro' ), + 'dark' => esc_html__( 'Dark', 'elementor-pro' ), + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'recaptcha', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'recaptcha_badge', [ + 'label' => esc_html__( 'Badge', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'bottomright', + 'options' => [ + 'bottomright' => esc_html__( 'Bottom Right', 'elementor-pro' ), + 'bottomleft' => esc_html__( 'Bottom Left', 'elementor-pro' ), + 'inline' => esc_html__( 'Inline', 'elementor-pro' ), + ], + 'description' => esc_html__( 'To view the validation badge, switch to preview mode', 'elementor-pro' ), + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'value' => 'recaptcha_v3', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'css_classes', + [ + 'label' => esc_html__( 'CSS Classes', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => '', + 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor-pro' ), + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( + 'form_fields_advanced_tab', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + 'condition' => [ + 'field_type!' => 'html', + ], + ] + ); + + $repeater->add_control( + 'field_value', + [ + 'label' => esc_html__( 'Default Value', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'field_type', + 'operator' => 'in', + 'value' => [ + 'text', + 'email', + 'textarea', + 'url', + 'tel', + 'radio', + 'select', + 'number', + 'date', + 'time', + 'hidden', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'custom_id', + [ + 'label' => esc_html__( 'ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => sprintf( + esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor-pro' ), + '', + '' + ), + 'render_type' => 'none', + 'required' => true, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $shortcode_template = '{{ view.container.settings.get( \'custom_id\' ) }}'; + $repeater->add_control( + 'shortcode', + [ + 'label' => esc_html__( 'Shortcode', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'classes' => 'forms-field-shortcode', + 'raw' => '', + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $this->start_controls_section( + 'section_form_fields', + [ + 'label' => esc_html__( 'Form Fields', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'form_name', + [ + 'label' => esc_html__( 'Form Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'New Form', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'form_fields', + [ + 'type' => Fields_Repeater::CONTROL_TYPE, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'custom_id' => 'name', + 'field_type' => 'text', + 'field_label' => esc_html__( 'Name', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Name', 'elementor-pro' ), + 'width' => '100', + 'dynamic' => [ + 'active' => true, + ], + ], + [ + 'custom_id' => 'email', + 'field_type' => 'email', + 'required' => 'true', + 'field_label' => esc_html__( 'Email', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Email', 'elementor-pro' ), + 'width' => '100', + ], + [ + 'custom_id' => 'message', + 'field_type' => 'textarea', + 'field_label' => esc_html__( 'Message', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Message', 'elementor-pro' ), + 'width' => '100', + ], + ], + 'title_field' => '{{{ field_label }}}', + ] + ); + + $this->add_control( + 'input_size', + [ + 'label' => esc_html__( 'Input Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'default' => 'sm', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'show_labels', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'true', + 'default' => 'true', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'mark_required', + [ + 'label' => esc_html__( 'Required Mark', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => '', + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_control( + 'label_position', + [ + 'label' => esc_html__( 'Label Position', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'options' => [ + 'above' => esc_html__( 'Above', 'elementor-pro' ), + 'inline' => esc_html__( 'Inline', 'elementor-pro' ), + ], + 'default' => 'above', + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_buttons', + [ + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'sm', + 'options' => self::get_button_sizes(), + ] + ); + + $this->add_responsive_control( + 'button_width', + [ + 'label' => esc_html__( 'Column Width', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + '100' => '100%', + '80' => '80%', + '75' => '75%', + '70' => '70%', + '66' => '66%', + '60' => '60%', + '50' => '50%', + '40' => '40%', + '33' => '33%', + '30' => '30%', + '25' => '25%', + '20' => '20%', + ], + 'default' => '100', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'heading_steps_buttons', + [ + 'label' => esc_html__( 'Step Buttons', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'step_next_label', + [ + 'label' => esc_html__( 'Next', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'frontend_available' => true, + 'render_type' => 'none', + 'default' => esc_html__( 'Next', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Next', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'step_previous_label', + [ + 'label' => esc_html__( 'Previous', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'frontend_available' => true, + 'render_type' => 'none', + 'default' => esc_html__( 'Previous', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Previous', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_submit_button', + [ + 'label' => esc_html__( 'Submit Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Submit', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Send', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Send', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'selected_button_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $this->add_control( + 'button_icon_align', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => is_rtl() ? 'row-reverse' : 'row', + 'options' => [ + 'row' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$start}", + ], + 'row-reverse' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$end}", + ], + ], + 'selectors_dictionary' => [ + 'left' => is_rtl() ? 'row-reverse' : 'row', + 'right' => is_rtl() ? 'row' : 'row-reverse', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button-content-wrapper' => 'flex-direction: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + 'selected_button_icon[value]!' => '', + ], + ] + ); + + $this->add_control( + 'button_icon_indent', + [ + 'label' => esc_html__( 'Icon Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'button_text!' => '', + 'selected_button_icon[value]!' => '', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button span' => 'gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_css_id', + [ + 'label' => esc_html__( 'Button ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor-pro' ), + 'description' => sprintf( + esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor-pro' ), + '', + '' + ), + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_integration', + [ + 'label' => esc_html__( 'Actions After Submit', 'elementor-pro' ), + ] + ); + + $this->maybe_add_send_app_promotion_control(); + + $actions = Module::instance()->actions_registrar->get(); + + $actions_options = []; + + foreach ( $actions as $action ) { + $actions_options[ $action->get_name() ] = $action->get_label(); + } + + $default_submit_actions = [ 'email' ]; + + /** + * Default submit actions. + * + * Filters the list of submit actions pre deffined by Elementor forms. + * + * By default, only one submit action is set by Elementor forms, an 'email' + * action. This hook allows developers to alter those submit action. + * + * @param array $default_submit_actions A list of default submit actions. + */ + $default_submit_actions = apply_filters( 'elementor_pro/forms/default_submit_actions', $default_submit_actions ); + + $this->add_control( + 'submit_actions', + [ + 'label' => esc_html__( 'Add Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => $actions_options, + 'render_type' => 'none', + 'label_block' => true, + 'default' => $default_submit_actions, + 'description' => esc_html__( 'Add actions that will be performed after a visitor submits the form (e.g. send an email notification). Choosing an action will add its setting below.', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + foreach ( $actions as $action ) { + $action->register_settings_section( $this ); + } + + // Steps settings. + $this->start_controls_section( + 'section_steps_settings', + [ + 'label' => esc_html__( 'Steps Settings', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'step_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'frontend_available' => true, + 'render_type' => 'none', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + 'icon' => esc_html__( 'Icon', 'elementor-pro' ), + 'number' => esc_html__( 'Number', 'elementor-pro' ), + 'progress_bar' => esc_html__( 'Progress Bar', 'elementor-pro' ), + 'number_text' => esc_html__( 'Number & Text', 'elementor-pro' ), + 'icon_text' => esc_html__( 'Icon & Text', 'elementor-pro' ), + ], + 'default' => 'number_text', + ] + ); + + $this->add_control( + 'step_icon_shape', + [ + 'label' => esc_html__( 'Shape', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'frontend_available' => true, + 'render_type' => 'none', + 'options' => [ + 'circle' => esc_html__( 'Circle', 'elementor-pro' ), + 'square' => esc_html__( 'Square', 'elementor-pro' ), + 'rounded' => esc_html__( 'Rounded', 'elementor-pro' ), + 'none' => 'None', + ], + 'default' => 'circle', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'step_type', + 'operator' => '!in', + 'value' => [ + 'progress_bar', + 'text', + ], + ], + ], + ], + ] + ); + + $repeater->add_control( + 'display_percentage', + [ + 'label' => esc_html__( 'Display Percentage', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'frontend_available' => true, + 'render_type' => 'none', + 'return_value' => 'true', + 'default' => '', + 'condition' => [ + 'step_type' => 'progress_bar', + ], + ] + ); + + // End of steps settings. + $this->end_controls_section(); + + $this->start_controls_section( + 'section_form_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'form_id', + [ + 'label' => esc_html__( 'Form ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'placeholder' => 'new_form_id', + 'description' => sprintf( + esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor-pro' ), + '', + '' + ), + 'separator' => 'after', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'form_validation', + [ + 'label' => esc_html__( 'Form Validation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Browser Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => '', + ] + ); + + $this->add_control( + 'custom_messages', + [ + 'label' => esc_html__( 'Custom Messages', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'separator' => 'before', + 'render_type' => 'none', + ] + ); + + $default_messages = Ajax_Handler::get_default_messages(); + + $this->add_control( + 'success_message', + [ + 'label' => esc_html__( 'Success Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_messages[ Ajax_Handler::SUCCESS ], + 'placeholder' => $default_messages[ Ajax_Handler::SUCCESS ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'error_message', + [ + 'label' => esc_html__( 'Form Error', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_messages[ Ajax_Handler::ERROR ], + 'placeholder' => $default_messages[ Ajax_Handler::ERROR ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'server_message', + [ + 'label' => esc_html__( 'Server Error', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_messages[ Ajax_Handler::SERVER_ERROR ], + 'placeholder' => $default_messages[ Ajax_Handler::SERVER_ERROR ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'invalid_message', + [ + 'label' => esc_html__( 'Invalid Form', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_messages[ Ajax_Handler::INVALID_FORM ], + 'placeholder' => $default_messages[ Ajax_Handler::INVALID_FORM ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'required_field_message', + [ + 'label' => esc_html__( 'Required Field', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $default_messages[ Ajax_Handler::FIELD_REQUIRED ], + 'placeholder' => $default_messages[ Ajax_Handler::FIELD_REQUIRED ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + 'form_validation' => 'custom', + ], + 'render_type' => 'none', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_form_style', + [ + 'label' => esc_html__( 'Form', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group' => 'padding-right: calc( {{SIZE}}{{UNIT}}/2 ); padding-left: calc( {{SIZE}}{{UNIT}}/2 );', + '{{WRAPPER}} .elementor-form-fields-wrapper' => 'margin-left: calc( -{{SIZE}}{{UNIT}}/2 ); margin-right: calc( -{{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group' => 'margin-bottom: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-field-group.recaptcha_v3-bottomleft, {{WRAPPER}} .elementor-field-group.recaptcha_v3-bottomright' => 'margin-bottom: 0;', + '{{WRAPPER}} .elementor-form-fields-wrapper' => 'margin-bottom: -{{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'heading_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'label_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 0, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + 'body.rtl {{WRAPPER}} .elementor-labels-inline .elementor-field-group > label' => 'padding-left: {{SIZE}}{{UNIT}};', + // for the label position = inline option + 'body:not(.rtl) {{WRAPPER}} .elementor-labels-inline .elementor-field-group > label' => 'padding-right: {{SIZE}}{{UNIT}};', + // for the label position = inline option + 'body {{WRAPPER}} .elementor-labels-above .elementor-field-group > label' => 'padding-bottom: {{SIZE}}{{UNIT}};', + // for the label position = above option + ], + ] + ); + + $this->add_control( + 'label_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group > label, {{WRAPPER}} .elementor-field-subgroup label' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_control( + 'mark_required_color', + [ + 'label' => esc_html__( 'Mark Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-mark-required .elementor-field-label:after' => 'color: {{COLOR}};', + ], + 'condition' => [ + 'mark_required' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'label_typography', + 'selector' => '{{WRAPPER}} .elementor-field-group > label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'heading_html', + [ + 'label' => esc_html__( 'HTML Field', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'html_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 0, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-type-html' => 'padding-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'html_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-type-html' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'html_typography', + 'selector' => '{{WRAPPER}} .elementor-field-type-html', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_field_style', + [ + 'label' => esc_html__( 'Field', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'field_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'field_typography', + 'selector' => '{{WRAPPER}} .elementor-field-group .elementor-field, {{WRAPPER}} .elementor-field-subgroup label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'field_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'background-color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'field_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper::before' => 'color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'field_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'placeholder' => '1', + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'field_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_style', + [ + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'button_align', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'stretch' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-h-align-stretch', + ], + ], + 'default' => 'stretch', + 'prefix_class' => 'elementor%s-button-align-', + ] + ); + + $this->add_responsive_control( + 'button_content_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-text-align-{$start}", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-text-align-{$end}", + ], + 'space-between' => [ + 'title' => esc_html__( 'Space between', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-button span' => 'justify-content: {{VALUE}};', + ], + 'condition' => [ 'button_align' => 'stretch' ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-button', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), [ + 'name' => 'button_border', + 'selector' => '{{WRAPPER}} .elementor-button', + 'exclude' => [ + 'color', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_next_submit_button', + [ + 'label' => esc_html__( 'Next & Submit Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"] svg *' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'heading_previous_button', + [ + 'label' => esc_html__( 'Previous Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'previous_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'previous_button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'previous_button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_border_border!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_next_submit_button_hover', + [ + 'label' => esc_html__( 'Next & Submit Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'button_background_hover_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next:hover' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next:hover' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]:hover' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]:hover svg *' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-next:hover' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-button[type="submit"]:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'heading_previous_button_hover', + [ + 'label' => esc_html__( 'Previous Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'previous_button_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'previous_button_text_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'previous_button_border_color_hover', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .e-form__buttons__wrapper__button-previous' => 'transition-duration: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .e-form__buttons__wrapper__button-next' => 'transition-duration: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-button[type="submit"] svg *' => 'transition-duration: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-button[type="submit"]' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_hover_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'button_text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_messages_style', + [ + 'label' => esc_html__( 'Messages', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'message_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-message', + ] + ); + + $this->add_control( + 'success_message_color', + [ + 'label' => esc_html__( 'Success Message Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-message.elementor-message-success' => 'color: {{COLOR}};', + ], + ] + ); + + $this->add_control( + 'error_message_color', + [ + 'label' => esc_html__( 'Error Message Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-message.elementor-message-danger' => 'color: {{COLOR}};', + ], + ] + ); + + $this->add_control( + 'inline_message_color', + [ + 'label' => esc_html__( 'Inline Message Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-message.elementor-help-inline' => 'color: {{COLOR}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_steps_style', + [ + 'label' => esc_html__( 'Steps', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'steps_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .e-form__indicators__indicator, {{WRAPPER}} .e-form__indicators__indicator__label', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'step_type', + 'operator' => '!in', + 'value' => [ + 'icon', + 'progress_bar', + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'steps_gap', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicators-spacing: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'steps_icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 15, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'step_type', + 'operator' => 'in', + 'value' => [ + 'icon', + 'icon_text', + ], + ], + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-icon-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'steps_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'size' => 30, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-padding: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'step_type', + 'operator' => '!in', + 'value' => [ + 'text', + 'progress_bar', + ], + ], + ], + ], + ] + ); + + $this->start_controls_tabs( 'steps_state', [ + 'condition' => [ + 'step_type!' => 'progress_bar', + ], + ] ); + + $this->start_controls_tab( + 'tab_steps_state_inactive', + [ + 'label' => esc_html__( 'Inactive', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'step_inactive_primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-inactive-primary-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'step_inactive_secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-inactive-secondary-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_steps_state_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'step_active_primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-active-primary-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'step_active_secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-active-secondary-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_steps_state_completed', + [ + 'label' => esc_html__( 'Completed', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'step_completed_primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-completed-primary-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'step_completed_secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'condition' => [ + 'step_icon_shape!' => 'none', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-completed-secondary-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'step_divider_width', + [ + 'label' => esc_html__( 'Divider Width', 'elementor-pro' ), + 'separator' => 'before', + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'step_type!' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-divider-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'step_divider_gap', + [ + 'label' => esc_html__( 'Divider Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'step_type!' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-divider-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'step_progress_bar_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'condition' => [ + 'step_type' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-progress-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'step_progress_bar_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'step_type' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-progress-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'step_progress_bar_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'step_type' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-progress-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'step_progress_bar_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 0, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'step_type' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-progress-border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'step_progress_bar_percentage_heading', + [ + 'label' => esc_html__( 'Percentage', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'step_type' => 'progress_bar', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'step_progress_bar_percentage__typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .e-form__indicators__indicator__progress__meter', + 'condition' => [ + 'step_type' => 'progress_bar', + ], + ] + ); + + $this->add_control( + 'step_progress_bar_percentage_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'step_type' => 'progress_bar', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-form-steps-indicator-progress-meter-color: {{VALUE}};', + ], + ] + ); + + // End of steps style. + $this->end_controls_section(); + + } + + private function render_icon_with_fallback( $settings ) { + $migrated = isset( $settings['__fa4_migrated']['selected_button_icon'] ); + $is_new = empty( $settings['button_icon'] ) && Icons_Manager::is_migration_allowed(); + + if ( $is_new || $migrated ) { + Icons_Manager::render_icon( $settings['selected_button_icon'], [ 'aria-hidden' => 'true' ] ); + } else { + ?>get_settings_for_display(); + + if ( ! Plugin::elementor()->editor->is_edit_mode() ) { + /** + * Elementor form pre render. + * + * Fires before the form is rendered in the frontend. This hook allows + * developers to add functionality before the form is rendered. + * + * @since 2.4.0 + * + * @param array $instance Current form settings. + * @param Form $this An instance of the form. + */ + do_action( 'elementor-pro/forms/pre_render', $instance, $this ); + } + + $this->add_render_attribute( + [ + 'wrapper' => [ + 'class' => [ + 'elementor-form-fields-wrapper', + 'elementor-labels-' . $instance['label_position'], + ], + ], + 'submit-group' => [ + 'class' => [ + 'elementor-field-group', + 'elementor-column', + 'elementor-field-type-submit', + ], + ], + 'button' => [ + 'class' => 'elementor-button', + 'type' => 'submit', + ], + 'button-content-wrapper' => [ + 'class' => 'elementor-button-content-wrapper', + ], + 'button-icon' => [ + 'class' => 'elementor-button-icon', + ], + 'button-text' => [ + 'class' => 'elementor-button-text', + ], + ] + ); + + if ( empty( $instance['button_width'] ) ) { + $instance['button_width'] = '100'; + } + + $this->add_render_attribute( 'submit-group', 'class', 'elementor-col-' . $instance['button_width'] . ' e-form__buttons' ); + + if ( ! empty( $instance['button_width_tablet'] ) ) { + $this->add_render_attribute( 'submit-group', 'class', 'elementor-md-' . $instance['button_width_tablet'] ); + } + + if ( ! empty( $instance['button_width_mobile'] ) ) { + $this->add_render_attribute( 'submit-group', 'class', 'elementor-sm-' . $instance['button_width_mobile'] ); + } + + if ( ! empty( $instance['button_size'] ) ) { + $this->add_render_attribute( 'button', 'class', 'elementor-size-' . $instance['button_size'] ); + } + + if ( ! empty( $instance['button_type'] ) ) { + $this->add_render_attribute( 'button', 'class', 'elementor-button-' . $instance['button_type'] ); + } + + if ( $instance['button_hover_animation'] ) { + $this->add_render_attribute( 'button', 'class', 'elementor-animation-' . $instance['button_hover_animation'] ); + } + + if ( ! empty( $instance['form_id'] ) ) { + $this->add_render_attribute( 'form', 'id', $instance['form_id'] ); + } + + if ( ! empty( $instance['form_name'] ) ) { + $this->add_render_attribute( 'form', 'name', $instance['form_name'] ); + $this->add_render_attribute( 'form', 'aria-label', $instance['form_name'] ); + } + + if ( 'custom' === $instance['form_validation'] ) { + $this->add_render_attribute( 'form', 'novalidate' ); + } + + if ( ! empty( $instance['button_css_id'] ) ) { + $this->add_render_attribute( 'button', 'id', $instance['button_css_id'] ); + } + + $referer_title = trim( wp_title( '', false ) ); + + if ( ! $referer_title && is_home() ) { + $referer_title = get_option( 'blogname' ); + } + + ?> +
      print_render_attribute_string( 'form' ); ?>> + + + + + + + + +
      print_render_attribute_string( 'wrapper' ); ?>> + $item ) : + $item['input_size'] = $instance['input_size']; + $this->form_fields_render_attributes( $item_index, $instance, $item ); + + $field_type = $item['field_type']; + + /** + * Render form field. + * + * Filters the field rendered by Elementor forms. + * + * @since 1.0.0 + * + * @param array $item The field value. + * @param int $item_index The field index. + * @param Form $this An instance of the form. + */ + $item = apply_filters( 'elementor_pro/forms/render/item', $item, $item_index, $this ); + + /** + * Render form field. + * + * Filters the field rendered by Elementor forms. + * + * The dynamic portion of the hook name, `$field_type`, refers to the field type. + * + * @since 1.0.0 + * + * @param array $item The field value. + * @param int $item_index The field index. + * @param Form $this An instance of the form. + */ + $item = apply_filters( "elementor_pro/forms/render/item/{$field_type}", $item, $item_index, $this ); + + $print_label = ! in_array( $item['field_type'], [ 'hidden', 'html', 'step' ], true ); + ?> +
      print_render_attribute_string( 'field-group' . $item_index ); ?>> + + + make_textarea_field( $item, $item_index ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + break; + + case 'select': + // PHPCS - the method make_select_field is safe. + echo $this->make_select_field( $item, $item_index ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + break; + + case 'radio': + case 'checkbox': + // PHPCS - the method make_radio_checkbox_field is safe. + echo $this->make_radio_checkbox_field( $item, $item_index, $item['field_type'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + break; + case 'text': + case 'email': + case 'url': + case 'password': + case 'hidden': + case 'search': + $this->add_render_attribute( 'input' . $item_index, 'class', 'elementor-field-textual' ); + ?> + print_render_attribute_string( 'input' . $item_index ); ?>> + +
      + +
      print_render_attribute_string( 'submit-group' ); ?>> + +
      +
      +
      + + <# + view.addRenderAttribute( 'form', 'class', 'elementor-form' ); + + if ( '' !== settings.form_id ) { + view.addRenderAttribute( 'form', 'id', settings.form_id ); + } + + if ( '' !== settings.form_name ) { + view.addRenderAttribute( 'form', 'name', settings.form_name ); + } + + if ( 'custom' === settings.form_validation ) { + view.addRenderAttribute( 'form', 'novalidate' ); + } + #> +
      +
      + <# + for ( var i in settings.form_fields ) { + var item = settings.form_fields[ i ]; + item = elementor.hooks.applyFilters( 'elementor_pro/forms/content_template/item', item, i, settings ); + + item.field_type = _.escape( item.field_type ); + item.field_value = _.escape( item.field_value ); + + var options = item.field_options ? item.field_options.split( '\n' ) : [], + itemClasses = _.escape( item.css_classes ), + labelVisibility = '', + placeholder = '', + required = '', + inputField = '', + multiple = '', + fieldGroupClasses = 'elementor-field-group elementor-column elementor-field-type-' + item.field_type, + printLabel = settings.show_labels && ! [ 'hidden', 'html', 'step' ].includes( item.field_type ); + + fieldGroupClasses += ' elementor-col-' + ( ( '' !== item.width ) ? item.width : '100' ); + + if ( item.width_tablet ) { + fieldGroupClasses += ' elementor-md-' + item.width_tablet; + } + + if ( item.width_mobile ) { + fieldGroupClasses += ' elementor-sm-' + item.width_mobile; + } + + if ( item.required ) { + required = 'required'; + fieldGroupClasses += ' elementor-field-required'; + + if ( settings.mark_required ) { + fieldGroupClasses += ' elementor-mark-required'; + } + } + + if ( item.placeholder ) { + placeholder = 'placeholder="' + _.escape( item.placeholder ) + '"'; + } + + if ( item.allow_multiple ) { + multiple = ' multiple'; + fieldGroupClasses += ' elementor-field-type-' + item.field_type + '-multiple'; + } + + switch ( item.field_type ) { + case 'step': + inputField = `
      `; + break; + case 'html': + inputField = item.field_html; + break; + + case 'textarea': + inputField = ''; + break; + + case 'select': + if ( options ) { + var size = ''; + if ( item.allow_multiple && item.select_size ) { + size = ' size="' + item.select_size + '"'; + } + inputField = '
      '; + inputField += '
      '; + } + break; + + case 'radio': + case 'checkbox': + if ( options ) { + var multiple = ''; + + if ( 'checkbox' === item.field_type && options.length > 1 ) { + multiple = '[]'; + } + + inputField = '
      '; + + for ( var x in options ) { + var option_value = options[ x ]; + var option_label = options[ x ]; + var option_id = 'form_field_' + item.field_type + i + x; + if ( options[x].indexOf( '|' ) > -1 ) { + var label_value = options[x].split( '|' ); + option_label = label_value[0]; + option_value = label_value[1]; + } + + view.addRenderAttribute( option_id, { + value: option_value, + type: item.field_type, + id: 'form_field_' + i + '-' + x, + name: 'form_field_' + i + multiple + } ); + + if ( option_value === item.field_value ) { + view.addRenderAttribute( option_id, 'checked', 'checked' ); + } + + inputField += ' '; + inputField += ''; + + } + + inputField += '
      '; + } + break; + + case 'text': + case 'email': + case 'url': + case 'password': + case 'number': + case 'search': + itemClasses = 'elementor-field-textual ' + itemClasses; + inputField = ''; + break; + default: + item.placeholder = _.escape( item.placeholder ); + inputField = elementor.hooks.applyFilters( 'elementor_pro/forms/content_template/field/' + item.field_type, '', item, i, settings ); + } + + if ( inputField ) { + #> +
      + + <# if ( printLabel && item.field_label ) { #> + + <# } #> + + {{{ inputField }}} +
      + <# + } + } + + view.addRenderAttribute( + 'submit-group', + { + 'class': [ + 'elementor-field-group', + 'elementor-column', + 'elementor-field-type-submit', + 'e-form__buttons', + 'elementor-col-' + ( ( '' !== settings.button_width ) ? settings.button_width : '100' ) + ] + } + ); + + if ( settings.button_width_tablet ) { + view.addRenderAttribute( 'submit-group', 'class', 'elementor-md-' + settings.button_width_tablet ); + } + + if ( settings.button_width_mobile ) { + view.addRenderAttribute( 'submit-group', 'class', 'elementor-sm-' + settings.button_width_mobile ); + } + + view.addRenderAttribute( 'button', 'type', 'submit' ); + view.addRenderAttribute( 'button', 'class', 'elementor-button' ); + + if ( '' !== settings.button_css_id ) { + view.addRenderAttribute( 'button', 'id', settings.button_css_id ); + } + + if ( '' !== settings.button_size ) { + view.addRenderAttribute( 'button', 'class', 'elementor-size-' + settings.button_size ); + } + + if ( '' !== settings.button_type ) { + view.addRenderAttribute( 'button', 'class', 'elementor-button-' + settings.button_type ); + } + + if ( '' !== settings.button_hover_animation ) { + view.addRenderAttribute( 'button', 'class', 'elementor-animation-' + settings.button_hover_animation ); + } + + view.addRenderAttribute( 'button-content-wrapper', 'class', 'elementor-button-content-wrapper' ); + view.addRenderAttribute( 'button-icon', 'class', 'elementor-button-icon' ); + view.addRenderAttribute( 'button-text', 'class', 'elementor-button-text' ); + + const iconHTML = elementor.helpers.renderIcon( view, settings.selected_button_icon, { 'aria-hidden': true }, 'i' , 'object' ); + const migrated = elementor.helpers.isIconMigrated( settings, 'selected_button_icon' ); + #> +
      + +
      +
      +
      + Let Send do the work', 'elementor-pro' ), [ 'br' => [] ] ); + + $this->add_control( + 'send_app_promo', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Hints::get_notice_template( [ + 'display' => ! Hints::is_dismissed( $notice_id ), + 'type' => 'info', + 'content' => $notice_content, + 'icon' => true, + 'dismissible' => $notice_id, + 'button_text' => __( 'Start for free', 'elementor-pro' ), + 'button_event' => $notice_id, + 'button_data' => [ + 'action_url' => Hints::get_plugin_action_url( 'send-app' ), + ], + ], true ), + ] + ); + } +} diff --git a/modules/forms/widgets/login.php b/modules/forms/widgets/login.php new file mode 100644 index 00000000..916b542f --- /dev/null +++ b/modules/forms/widgets/login.php @@ -0,0 +1,1116 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-login', 'widget-form' ]; + } + + protected function register_controls() { + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + $widget_container_selector = $optimized_markup ? '' : ' .elementor-widget-container'; + + $this->start_controls_section( + 'section_fields_content', + [ + 'label' => esc_html__( 'Form Fields', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_labels', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'input_size', + [ + 'label' => esc_html__( 'Input Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'default' => 'sm', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_content', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Log In', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'default' => 'sm', + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'stretch' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'prefix_class' => 'elementor%s-button-align-', + 'default' => '', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_login_content', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'redirect_after_login', + [ + 'label' => esc_html__( 'Redirect After Login', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'redirect_url', + [ + 'type' => Controls_Manager::URL, + 'show_label' => false, + 'options' => false, + 'description' => esc_html__( 'Note: Because of security reasons, you can ONLY use your current domain here.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'redirect_after_login' => 'yes', + ], + ] + ); + + $this->add_control( + 'redirect_after_logout', + [ + 'label' => esc_html__( 'Redirect After Logout', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'redirect_logout_url', + [ + 'type' => Controls_Manager::URL, + 'show_label' => false, + 'options' => false, + 'description' => esc_html__( 'Note: Because of security reasons, you can ONLY use your current domain here.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'redirect_after_logout' => 'yes', + ], + ] + ); + + $this->add_control( + 'show_lost_password', + [ + 'label' => esc_html__( 'Lost your password?', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + if ( get_option( 'users_can_register' ) ) { + $this->add_control( + 'show_register', + [ + 'label' => esc_html__( 'Register', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + } + + $this->add_control( + 'show_remember_me', + [ + 'label' => esc_html__( 'Remember Me', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_logged_in_message', + [ + 'label' => esc_html__( 'Logged in Message', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'custom_labels', + [ + 'label' => esc_html__( 'Custom Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'user_label', + [ + 'label' => esc_html__( 'Username Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Username or Email Address', 'elementor-pro' ), + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'show_labels', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'custom_labels', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $this->add_control( + 'user_placeholder', + [ + 'label' => esc_html__( 'Username Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Username or Email Address', 'elementor-pro' ), + 'condition' => [ + 'custom_labels' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'password_label', + [ + 'label' => esc_html__( 'Password Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Password', 'elementor-pro' ), + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'show_labels', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'custom_labels', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $this->add_control( + 'password_placeholder', + [ + 'label' => esc_html__( 'Password Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Password', 'elementor-pro' ), + 'condition' => [ + 'custom_labels' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Form', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group' => 'margin-bottom: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-form-fields-wrapper' => 'margin-bottom: -{{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'links_color', + [ + 'label' => esc_html__( 'Links Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group > a' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_control( + 'links_hover_color', + [ + 'label' => esc_html__( 'Links Hover Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group > a:hover' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_labels', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_labels!' => '', + ], + ] + ); + + $this->add_control( + 'label_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 0, + ], + 'range' => [ + 'px' => [ + 'max' => 60, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'selectors' => [ + 'body {{WRAPPER}} .elementor-field-group > label' => 'padding-bottom: {{SIZE}}{{UNIT}};', + // for the label position = above option + ], + ] + ); + + $this->add_control( + 'label_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-form-fields-wrapper label' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'label_typography', + 'selector' => '{{WRAPPER}} .elementor-form-fields-wrapper label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_field_style', + [ + 'label' => esc_html__( 'Fields', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'field_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'field_typography', + 'selector' => '{{WRAPPER}} .elementor-field-group .elementor-field, {{WRAPPER}} .elementor-field-subgroup label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'field_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'background-color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'field_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-color: {{VALUE}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper::before' => 'color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'field_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'placeholder' => '1', + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'field_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-field-group .elementor-field:not(.elementor-select-wrapper)' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .elementor-field-group .elementor-select-wrapper select' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-button', + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-button', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), [ + 'name' => 'button_border', + 'selector' => '{{WRAPPER}} .elementor-button', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background_hover', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-button:hover', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-button:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->add_control( + 'button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'transition-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_message', + [ + 'label' => esc_html__( 'Logged in Message', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_logged_in_message' => 'yes', + ], + ] + ); + + $this->add_control( + 'message_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + "{{WRAPPER}}{$widget_container_selector} .elementor-login__logged-in-message" => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'show_logged_in_message' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'message_typography', + 'selector' => "{{WRAPPER}}{$widget_container_selector} .elementor-login__logged-in-message", + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'condition' => [ + 'show_logged_in_message' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + } + + private function form_fields_render_attributes() { + $settings = $this->get_settings_for_display(); + + if ( ! empty( $settings['button_size'] ) ) { + $this->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['button_size'] ); + } + + if ( $settings['button_hover_animation'] ) { + $this->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['button_hover_animation'] ); + } + + $this->add_render_attribute( + [ + 'wrapper' => [ + 'class' => [ + 'elementor-form-fields-wrapper', + ], + ], + 'field-group' => [ + 'class' => [ + 'elementor-field-type-text', + 'elementor-field-group', + 'elementor-column', + 'elementor-col-100', + ], + ], + 'submit-group' => [ + 'class' => [ + 'elementor-field-group', + 'elementor-column', + 'elementor-field-type-submit', + 'elementor-col-100', + ], + ], + 'button' => [ + 'class' => [ + 'elementor-button', + ], + 'name' => 'wp-submit', + ], + 'user_label' => [ + 'for' => 'user-' . $this->get_id(), + 'class' => 'elementor-field-label', + ], + 'user_input' => [ + 'size' => '1', + 'type' => 'text', + 'name' => 'log', + 'id' => 'user-' . $this->get_id(), + 'placeholder' => $settings['user_placeholder'], + 'class' => [ + 'elementor-field', + 'elementor-field-textual', + 'elementor-size-' . $settings['input_size'], + ], + ], + 'password_label' => [ + 'for' => 'password-' . $this->get_id(), + 'class' => 'elementor-field-label', + ], + 'password_input' => [ + 'size' => '1', + 'type' => 'password', + 'name' => 'pwd', + 'id' => 'password-' . $this->get_id(), + 'placeholder' => $settings['password_placeholder'], + 'class' => [ + 'elementor-field', + 'elementor-field-textual', + 'elementor-size-' . $settings['input_size'], + ], + ], + ] + ); + + if ( ! $settings['show_labels'] ) { + $this->add_render_attribute( 'user_label', 'class', 'elementor-screen-only' ); + $this->add_render_attribute( 'password_label', 'class', 'elementor-screen-only' ); + } + + $this->add_render_attribute( 'field-group', 'class', 'elementor-field-required' ) + ->add_render_attribute( 'input', 'required', true ); + + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $current_url = remove_query_arg( 'fake_arg' ); + $logout_redirect = $current_url; + + if ( 'yes' === $settings['redirect_after_login'] && ! empty( $settings['redirect_url']['url'] ) ) { + $redirect_url = $settings['redirect_url']['url']; + } else { + $redirect_url = $current_url; + } + + if ( 'yes' === $settings['redirect_after_logout'] && ! empty( $settings['redirect_logout_url']['url'] ) ) { + $logout_redirect = $settings['redirect_logout_url']['url']; + } + + if ( is_user_logged_in() && ! Plugin::elementor()->editor->is_edit_mode() ) { + if ( 'yes' === $settings['show_logged_in_message'] ) { + $current_user = wp_get_current_user(); + + // PHPCS - `sprintf` is safe. + echo ''; + } + + return; + } + + $this->form_fields_render_attributes(); + ?> + + + + get_css_assets_url( 'widget-gallery', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + + wp_register_style( + 'e-transitions', + $this->get_css_assets_url( 'transitions', 'assets/css/conditionals/', true ), + [], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/gallery/widgets/gallery.php b/modules/gallery/widgets/gallery.php new file mode 100644 index 00000000..0854af5d --- /dev/null +++ b/modules/gallery/widgets/gallery.php @@ -0,0 +1,1669 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + $this->start_controls_section( 'settings', [ 'label' => esc_html__( 'Settings', 'elementor-pro' ) ] ); + + $this->add_control( + 'gallery_type', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'default' => 'single', + 'options' => [ + 'single' => esc_html__( 'Single', 'elementor-pro' ), + 'multiple' => esc_html__( 'Multiple', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'gallery', + [ + 'type' => Controls_Manager::GALLERY, + 'condition' => [ + 'gallery_type' => 'single', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'gallery_title', + [ + 'type' => Controls_Manager::TEXT, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'default' => esc_html__( 'New Gallery', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'multiple_gallery', + [ + 'type' => Controls_Manager::GALLERY, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'galleries', + [ + 'type' => Controls_Manager::REPEATER, + 'label' => esc_html__( 'Galleries', 'elementor-pro' ), + 'fields' => $repeater->get_controls(), + 'title_field' => '{{{ gallery_title }}}', + 'default' => [ + [ + 'gallery_title' => esc_html__( 'New Gallery', 'elementor-pro' ), + ], + ], + 'condition' => [ + 'gallery_type' => 'multiple', + ], + ] + ); + + $this->add_control( + 'order_by', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + 'random' => esc_html__( 'Random', 'elementor-pro' ), + ], + 'default' => '', + ] + ); + + $this->add_control( + 'lazyload', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Lazy Load', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'gallery_layout', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'default' => 'grid', + 'options' => [ + 'grid' => esc_html__( 'Grid', 'elementor-pro' ), + 'justified' => esc_html__( 'Justified', 'elementor-pro' ), + 'masonry' => esc_html__( 'Masonry', 'elementor-pro' ), + ], + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 4, + 'tablet_default' => 2, + 'mobile_default' => 1, + 'min' => 1, + 'max' => 24, + 'condition' => [ + 'gallery_layout!' => 'justified', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $active_breakpoints = Plugin::elementor()->breakpoints->get_active_breakpoints(); + $ideal_row_height_device_args = []; + $gap_device_args = []; + + // Add default values for all active breakpoints. + foreach ( $active_breakpoints as $breakpoint_name => $breakpoint_instance ) { + if ( 'widescreen' !== $breakpoint_name ) { + $ideal_row_height_device_args[ $breakpoint_name ] = [ + 'default' => [ + 'size' => 150, + ], + ]; + + $gap_device_args[ $breakpoint_name ] = [ + 'default' => [ + 'size' => 10, + ], + ]; + } + } + + $this->add_responsive_control( + 'ideal_row_height', + [ + 'label' => esc_html__( 'Row Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 50, + 'max' => 500, + ], + ], + 'default' => [ + 'size' => 200, + ], + 'device_args' => $ideal_row_height_device_args, + 'condition' => [ + 'gallery_layout' => 'justified', + ], + 'required' => true, + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'gap', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 10, + ], + 'device_args' => $gap_device_args, + 'required' => true, + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'link_to', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'file', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'file' => esc_html__( 'Media File', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom URL', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'condition' => [ + 'link_to' => 'custom', + ], + 'frontend_available' => true, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'open_lightbox', + [ + 'label' => esc_html__( 'Lightbox', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'description' => sprintf( + /* translators: 1: Link open tag, 2: Link close tag. */ + esc_html__( 'Manage your site’s lightbox settings in the %1$sLightbox panel%2$s.', 'elementor-pro' ), + '', + '' + ), + 'default' => 'default', + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'yes' => esc_html__( 'Yes', 'elementor-pro' ), + 'no' => esc_html__( 'No', 'elementor-pro' ), + ], + 'condition' => [ + 'link_to' => 'file', + ], + 'assets' => [ + 'styles' => [ + [ + 'name' => 'e-swiper', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'link_to', + 'operator' => '===', + 'value' => 'file', + ], + [ + 'name' => 'open_lightbox', + 'operator' => '!==', + 'value' => 'no', + ], + ], + ], + ], + ], + 'scripts' => [ + [ + 'name' => 'swiper', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'link_to', + 'operator' => '===', + 'value' => 'file', + ], + [ + 'name' => 'open_lightbox', + 'operator' => '!==', + 'value' => 'no', + ], + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'aspect_ratio', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Aspect Ratio', 'elementor-pro' ), + 'default' => '3:2', + 'options' => [ + '1:1' => '1:1', + '3:2' => '3:2', + '4:3' => '4:3', + '9:16' => '9:16', + '16:9' => '16:9', + '21:9' => '21:9', + ], + 'condition' => [ + 'gallery_layout' => 'grid', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'thumbnail_image', + 'default' => 'medium', + ] + ); + + $this->end_controls_section(); // settings + + $this->start_controls_section( + 'section_filter_bar_content', + [ + 'label' => esc_html__( 'Filter Bar', 'elementor-pro' ), + 'condition' => [ + 'gallery_type' => 'multiple', + ], + ] + ); + + $this->add_control( + 'show_all_galleries', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( '"All" Filter', 'elementor-pro' ), + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'show_all_galleries_label', + [ + 'type' => Controls_Manager::TEXT, + 'label' => esc_html__( '"All" Filter Label', 'elementor-pro' ), + 'default' => esc_html__( 'All', 'elementor-pro' ), + 'condition' => [ + 'show_all_galleries' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'pointer', + [ + 'label' => esc_html__( 'Pointer', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'underline', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'underline' => esc_html__( 'Underline', 'elementor-pro' ), + 'overline' => esc_html__( 'Overline', 'elementor-pro' ), + 'double-line' => esc_html__( 'Double Line', 'elementor-pro' ), + 'framed' => esc_html__( 'Framed', 'elementor-pro' ), + 'background' => esc_html__( 'Background', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + ], + 'style_transfer' => true, + ] + ); + + $this->add_control( + 'animation_line', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'slide' => 'Slide', + 'grow' => 'Grow', + 'drop-in' => 'Drop In', + 'drop-out' => 'Drop Out', + 'none' => 'None', + ], + 'condition' => [ + 'pointer' => [ 'underline', 'overline', 'double-line' ], + ], + ] + ); + + $this->add_control( + 'animation_framed', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'draw' => 'Draw', + 'corners' => 'Corners', + 'none' => 'None', + ], + 'condition' => [ + 'pointer' => 'framed', + ], + ] + ); + + $this->add_control( + 'animation_background', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'sweep-left' => 'Sweep Left', + 'sweep-right' => 'Sweep Right', + 'sweep-up' => 'Sweep Up', + 'sweep-down' => 'Sweep Down', + 'shutter-in-vertical' => 'Shutter In Vertical', + 'shutter-out-vertical' => 'Shutter Out Vertical', + 'shutter-in-horizontal' => 'Shutter In Horizontal', + 'shutter-out-horizontal' => 'Shutter Out Horizontal', + 'none' => 'None', + ], + 'condition' => [ + 'pointer' => 'background', + ], + ] + ); + + $this->add_control( + 'animation_text', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'grow', + 'options' => [ + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'sink' => 'Sink', + 'float' => 'Float', + 'skew' => 'Skew', + 'rotate' => 'Rotate', + 'none' => 'None', + ], + 'condition' => [ + 'pointer' => 'text', + ], + ] + ); + + $this->end_controls_section(); // settings + + $this->start_controls_section( 'overlay', [ 'label' => esc_html__( 'Overlay', 'elementor-pro' ) ] ); + + $this->add_control( + 'overlay_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'overlay_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'caption' => esc_html__( 'Caption', 'elementor-pro' ), + 'alt' => esc_html__( 'Alt', 'elementor-pro' ), + 'description' => esc_html__( 'Description', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'overlay_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'caption' => esc_html__( 'Caption', 'elementor-pro' ), + 'alt' => esc_html__( 'Alt', 'elementor-pro' ), + 'description' => esc_html__( 'Description', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); // overlay + + $this->start_controls_section( + 'image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'image_tabs' ); + + $this->start_controls_tab( + 'image_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'image_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--image-border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'image_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'em' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--image-border-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--image-border-radius: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'image_css_filters', + 'selector' => '{{WRAPPER}} .e-gallery-image', + ] + ); + + $this->end_controls_tab(); // overlay_background normal + + $this->start_controls_tab( + 'image_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'image_border_color_hover', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-gallery-item:hover' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'image_border_radius_hover', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-gallery-item:hover' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'image_css_filters_hover', + 'selector' => '{{WRAPPER}} .e-gallery-item:hover .e-gallery-image', + ] + ); + + $this->end_controls_tab(); // overlay_background normal + + $this->end_controls_tabs();// overlay_background tabs + + $this->add_control( + 'image_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => 'None', + 'grow' => 'Zoom In', + 'shrink-contained' => 'Zoom Out', + 'move-contained-left' => 'Move Left', + 'move-contained-right' => 'Move Right', + 'move-contained-top' => 'Move Up', + 'move-contained-bottom' => 'Move Down', + ], + 'separator' => 'before', + 'default' => '', + 'frontend_available' => true, + 'render_type' => 'ui', + ] + ); + + $this->add_control( + 'image_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 800, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--image-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->end_controls_section(); // overlay_background + + $this->start_controls_section( + 'overlay_style', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'overlay_background' => 'yes', + ], + ] + ); + + $this->start_controls_tabs( 'overlay_background_tabs' ); + + $this->start_controls_tab( + 'overlay_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'overlay_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-gallery-item__overlay', + 'fields_options' => [ + 'background' => [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + ], + ], + ] + ); + + $this->end_controls_tab(); // overlay_background normal + + $this->start_controls_tab( + 'overlay_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'overlay_background_hover', + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}} .e-gallery-item:hover .elementor-gallery-item__overlay, {{WRAPPER}} .e-gallery-item:focus .elementor-gallery-item__overlay', + 'exclude' => [ 'image' ], + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'default' => 'rgba(0,0,0,0.5)', + ], + ], + ] + ); + + $this->end_controls_tab(); // overlay_background normal + + $this->end_controls_tabs();// overlay_background tabs + + $this->add_control( + 'image_blend_mode', + [ + 'label' => esc_html__( 'Blend Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'multiply' => 'Multiply', + 'screen' => 'Screen', + 'overlay' => 'Overlay', + 'darken' => 'Darken', + 'lighten' => 'Lighten', + 'color-dodge' => 'Color Dodge', + 'color-burn' => 'Color Burn', + 'hue' => 'Hue', + 'saturation' => 'Saturation', + 'color' => 'Color', + 'exclusion' => 'Exclusion', + 'luminosity' => 'Luminosity', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--overlay-mix-blend-mode: {{VALUE}}', + ], + 'separator' => 'before', + 'render_type' => 'ui', + ] + ); + + $this->add_control( + 'background_overlay_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => [ + [ + 'label' => esc_html__( 'None', 'elementor-pro' ), + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + ], + ], + [ + 'label' => esc_html__( 'Entrance', 'elementor-pro' ), + 'options' => [ + 'enter-from-right' => 'Slide In Right', + 'enter-from-left' => 'Slide In Left', + 'enter-from-top' => 'Slide In Up', + 'enter-from-bottom' => 'Slide In Down', + 'enter-zoom-in' => 'Zoom In', + 'enter-zoom-out' => 'Zoom Out', + 'fade-in' => 'Fade In', + ], + ], + [ + 'label' => esc_html__( 'Exit', 'elementor-pro' ), + 'options' => [ + 'exit-to-right' => 'Slide Out Right', + 'exit-to-left' => 'Slide Out Left', + 'exit-to-top' => 'Slide Out Up', + 'exit-to-bottom' => 'Slide Out Down', + 'exit-zoom-in' => 'Zoom In', + 'exit-zoom-out' => 'Zoom Out', + 'fade-out' => 'Fade Out', + ], + ], + ], + 'separator' => 'before', + 'default' => '', + 'frontend_available' => true, + 'render_type' => 'ui', + ] + ); + + $this->add_control( + 'background_overlay_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 800, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--overlay-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->end_controls_section(); // overlay_background + + $this->start_controls_section( + 'overlay_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + //TODO: add conditions for this section + ] + ); + + $this->add_control( + 'content_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}}' => '--content-text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'content_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--content-justify-content: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'content_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--content-padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'overlay_title!' => '', + ], + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--title-text-color: {{VALUE}}', + ], + 'condition' => [ + 'overlay_title!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-gallery-item__title', + 'condition' => [ + 'overlay_title!' => '', + ], + ] + ); + + $this->add_control( + 'title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--description-margin-top: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'overlay_title!' => '', + ], + ] + ); + + $this->add_control( + 'heading_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'overlay_description!' => '', + ], + ] + ); + + $this->add_control( + 'description_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--description-text-color: {{VALUE}}', + ], + 'condition' => [ + 'overlay_description!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-gallery-item__description', + 'condition' => [ + 'overlay_description!' => '', + ], + ] + ); + + $this->add_control( + 'content_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => [ + [ + 'label' => esc_html__( 'None', 'elementor-pro' ), + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + ], + ], + [ + 'label' => esc_html__( 'Entrance', 'elementor-pro' ), + 'options' => [ + 'enter-from-right' => 'Slide In Right', + 'enter-from-left' => 'Slide In Left', + 'enter-from-top' => 'Slide In Up', + 'enter-from-bottom' => 'Slide In Down', + 'enter-zoom-in' => 'Zoom In', + 'enter-zoom-out' => 'Zoom Out', + 'fade-in' => 'Fade In', + ], + ], + [ + 'label' => esc_html__( 'Reaction', 'elementor-pro' ), + 'options' => [ + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'move-right' => 'Move Right', + 'move-left' => 'Move Left', + 'move-up' => 'Move Up', + 'move-down' => 'Move Down', + ], + ], + [ + 'label' => esc_html__( 'Exit', 'elementor-pro' ), + 'options' => [ + 'exit-to-right' => 'Slide Out Right', + 'exit-to-left' => 'Slide Out Left', + 'exit-to-top' => 'Slide Out Up', + 'exit-to-bottom' => 'Slide Out Down', + 'exit-zoom-in' => 'Zoom In', + 'exit-zoom-out' => 'Zoom Out', + 'fade-out' => 'Fade Out', + ], + ], + ], + 'default' => 'fade-in', + 'separator' => 'before', + 'render_type' => 'ui', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'content_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 800, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--content-transition-duration: {{SIZE}}ms; --content-transition-delay: {{SIZE}}ms;', + ], + 'condition' => [ + 'content_hover_animation!' => '', + ], + ] + ); + + $this->add_control( + 'content_sequenced_animation', + [ + 'label' => esc_html__( 'Sequenced Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'content_hover_animation!' => '', + ], + 'frontend_available' => true, + 'render_type' => 'ui', + ] + ); + + $this->end_controls_section(); // overlay_content + + $this->start_controls_section( + 'filter_bar_style', + [ + 'label' => esc_html__( 'Filter Bar', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'gallery_type' => 'multiple', + ], + ] + ); + + $this->add_control( + 'align_filter_bar_items', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-gallery--filter-align-', + 'selectors_dictionary' => [ + 'left' => 'flex-start', + 'right' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--titles-container-justify-content: {{VALUE}}', + ], + ] + ); + + $this->start_controls_tabs( 'filter_bar_colors' ); + + $this->start_controls_tab( 'filter_bar_colors_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'galleries_title_color_normal', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-title-color-normal: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'galleries_titles_typography', + 'selector' => '{{WRAPPER}} .elementor-gallery-title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->end_controls_tab();// filter_bar_colors_normal + + $this->start_controls_tab( 'filter_bar_colors_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'galleries_title_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-title-color-hover: {{VALUE}}', + ], + 'condition' => [ + 'pointer!' => 'background', + ], + ] + ); + + /* + When the pointer style = background, users could need a different text color. + The control handles the title color in hover state, only when the pointer style is background. + */ + $this->add_control( + 'galleries_title_color_hover_pointer_bg', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#fff', + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-title-color-hover: {{VALUE}}', + ], + 'condition' => [ + 'pointer' => 'background', + ], + ] + ); + + $this->add_control( + 'galleries_pointer_color_hover', + [ + 'label' => esc_html__( 'Pointer Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-pointer-bg-color-hover: {{VALUE}}', + ], + 'condition' => [ + 'pointer!' => [ 'none', 'text' ], + ], + ] + ); + + $this->end_controls_tab();// filter_bar_colors_hover + + $this->start_controls_tab( 'filter_bar_colors_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'galleries_title_color_active', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--gallery-title-color-active: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'galleries_pointer_color_active', + [ + 'label' => esc_html__( 'Pointer Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-pointer-bg-color-active: {{VALUE}}', + ], + 'condition' => [ + 'pointer!' => [ 'none', 'text' ], + ], + + ] + ); + + $this->end_controls_tab();// filter_bar_colors_active + + $this->end_controls_tabs(); // filter_bar_colors + + $this->add_control( + 'pointer_width', + [ + 'label' => esc_html__( 'Pointer Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'devices' => [ Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP, Breakpoints_Manager::BREAKPOINT_KEY_TABLET ], + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 30, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--galleries-pointer-border-width: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + 'condition' => [ + 'pointer' => [ 'underline', 'overline', 'double-line', 'framed' ], + ], + ] + ); + + $this->add_control( + 'galleries_titles_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-gallery-title' => '--space-between: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'galleries_titles_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-gallery__titles-container' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); // filter_bar_style + } + + protected function render_static() { + $settings = $this->get_settings_for_display(); + + $is_multiple = 'multiple' === $settings['gallery_type'] && ! empty( $settings['galleries'] ); + + $is_single = 'single' === $settings['gallery_type'] && ! empty( $settings['gallery'] ); + + $gap = $settings['gap']['size'] . $settings['gap']['unit']; + $ratio_percentage = '75'; + $columns = 4; + + if ( $settings['columns'] ) { + $columns = $settings['columns']; + } + + if ( $settings['aspect_ratio'] ) { + $ratio_array = explode( ':', $settings['aspect_ratio'] ); + + $ratio_percentage = ( $ratio_array[1] / $ratio_array[0] ) * 100; + } + + $this->add_render_attribute( + 'gallery_container', + [ + 'style' => "--columns: {$columns}; --aspect-ratio: {$ratio_percentage}%; --hgap: {$gap}; --vgap: {$gap};", + 'class' => 'e-gallery-grid', + ] + ); + + $galleries = []; + + if ( $is_multiple ) { + foreach ( array_values( $settings['galleries'] ) as $multi_gallery ) { + if ( ! $multi_gallery['multiple_gallery'] ) { + continue; + } + + $galleries[] = $multi_gallery['multiple_gallery']; + } + } elseif ( $is_single ) { + $galleries[0] = $settings['gallery']; + } + + foreach ( $galleries as $gallery ) { + foreach ( $gallery as $item ) { + $image_src = 'custom' !== $settings['thumbnail_image_size'] + ? wp_get_attachment_image_src( $item['id'], $settings['thumbnail_image_size'] )[0] + : Group_Control_Image_Size::get_attachment_image_src( $item['id'], 'thumbnail_image', $settings ); + + $this->add_render_attribute( 'gallery_item_image_' . $item['id'], [ + 'style' => "background-image: url('{$image_src}');", + ] ); + } + } + + $this->render(); + } + + /** + * + */ + protected function render() { + $settings = $this->get_settings_for_display(); + + $is_multiple = 'multiple' === $settings['gallery_type'] && ! empty( $settings['galleries'] ); + + $is_single = 'single' === $settings['gallery_type'] && ! empty( $settings['gallery'] ); + + $has_description = ! empty( $settings['overlay_description'] ); + + $has_title = ! empty( $settings['overlay_title'] ); + + $has_animation = ! empty( $settings['image_hover_animation'] ) || ! empty( $settings['content_hover_animation'] ) || ! empty( $settings['background_overlay_hover_animation'] ); + + $gallery_item_tag = ! empty( $settings['link_to'] ) ? 'a' : 'div'; + + $galleries = []; + + if ( $is_multiple ) { + $this->add_render_attribute( + 'titles-container', + [ + 'class' => 'elementor-gallery__titles-container', + 'aria-label' => esc_attr__( 'Gallery filter', 'elementor-pro' ), + ] + ); + + if ( $settings['pointer'] ) { + $this->add_render_attribute( 'titles-container', 'class', 'e--pointer-' . $settings['pointer'] ); + + foreach ( $settings as $key => $value ) { + if ( 0 === strpos( $key, 'animation' ) && $value ) { + $this->add_render_attribute( 'titles-container', 'class', 'e--animation-' . $value ); + break; + } + } + } ?> +
      print_render_attribute_string( 'titles-container' ); ?>> + + + + + + + $gallery ) : + if ( ! $gallery['multiple_gallery'] ) { + continue; + } + + $galleries[ $index ] = $gallery['multiple_gallery']; + ?> + + print_unescaped_setting( 'gallery_title', 'galleries', $index ); ?> + + +
      + editor->is_edit_mode() ) { ?> + + add_render_attribute( 'gallery_container', 'class', 'elementor-gallery__container' ); + + if ( $has_title || $has_description ) { + $this->add_render_attribute( 'gallery_item_content', 'class', 'elementor-gallery-item__content' ); + + if ( $has_title ) { + $this->add_render_attribute( 'gallery_item_title', 'class', 'elementor-gallery-item__title' ); + } + + if ( $has_description ) { + $this->add_render_attribute( 'gallery_item_description', 'class', 'elementor-gallery-item__description' ); + } + } + + $this->add_render_attribute( 'gallery_item_background_overlay', [ 'class' => 'elementor-gallery-item__overlay' ] ); + + $gallery_items = []; + $thumbnail_size = $settings['thumbnail_image_size']; + foreach ( $galleries as $gallery_index => $gallery ) { + foreach ( $gallery as $index => $item ) { + if ( in_array( $item['id'], array_keys( $gallery_items ), true ) ) { + $gallery_items[ $item['id'] ][] = $gallery_index; + } else { + $gallery_items[ $item['id'] ] = [ $gallery_index ]; + } + } + } + + if ( 'random' === $settings['order_by'] ) { + $shuffled_items = []; + $keys = array_keys( $gallery_items ); + shuffle( $keys ); + foreach ( $keys as $key ) { + $shuffled_items[ $key ] = $gallery_items[ $key ]; + } + $gallery_items = $shuffled_items; + } + + if ( ! empty( $galleries ) ) { ?> +
      print_render_attribute_string( 'gallery_container' ); ?>> + $tags ) : + $unique_index = $id; //$gallery_index . '_' . $index; + $image_src = wp_get_attachment_image_src( $id, $thumbnail_size ); + if ( ! $image_src ) { + continue; + } + $attachment = get_post( $id ); + + $image_data = $this->get_image_data( $attachment, $id, $image_src, $settings ); + + $this->add_render_attribute( 'gallery_item_' . $unique_index, [ + 'class' => [ + 'e-gallery-item', + 'elementor-gallery-item', + ], + ] ); + + if ( $has_animation ) { + $this->add_render_attribute( 'gallery_item_' . $unique_index, [ 'class' => 'elementor-animated-content' ] ); + } + + if ( $is_multiple ) { + $this->add_render_attribute( 'gallery_item_' . $unique_index, [ 'data-e-gallery-tags' => implode( ',', $tags ) ] ); + } + + if ( $has_title && 'div' === $gallery_item_tag ) { + $this->add_render_attribute( 'gallery_item_' . $unique_index, [ 'tabindex' => '0' ] ); + } + + if ( 'a' === $gallery_item_tag ) { + if ( 'file' === $settings['link_to'] ) { + $href = $image_data['media']; + + $this->add_render_attribute( 'gallery_item_' . $unique_index, [ + 'href' => esc_url( $href ), + ] ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + $this->add_render_attribute( 'gallery_item_' . $unique_index, 'class', 'elementor-clickable' ); + } + + $this->add_lightbox_data_attributes( 'gallery_item_' . $unique_index, $id, $settings['open_lightbox'], $this->get_id() ); + } elseif ( 'custom' === $settings['link_to'] ) { + $this->add_link_attributes( 'gallery_item_' . $unique_index, $settings['url'] ); + } + } + + $this->add_render_attribute( 'gallery_item_image_' . $unique_index, + [ + 'class' => [ + 'e-gallery-image', + 'elementor-gallery-item__image', + ], + 'data-thumbnail' => $image_data['src'], + 'data-width' => $image_data['width'], + 'data-height' => $image_data['height'], + 'aria-label' => $image_data['alt'], + 'role' => 'img', + ] + );?> + < print_render_attribute_string( 'gallery_item_' . $unique_index ); ?>> +
      print_render_attribute_string( 'gallery_item_image_' . $unique_index ); ?> >
      + +
      print_render_attribute_string( 'gallery_item_background_overlay' ); ?>>
      + + +
      print_render_attribute_string( 'gallery_item_content' ); ?>> + +
      print_render_attribute_string( 'gallery_item_title' ); ?>> + + +
      + +
      print_render_attribute_string( 'gallery_item_description' ); ?>> + + +
      + +
      + + > + +
      + get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), + 'media' => wp_get_attachment_image_src( $image_id, 'full' )['0'], + 'src' => $image_src['0'], + 'width' => $image_src['1'], + 'height' => $image_src['2'], + 'caption' => $attachment->post_excerpt, + 'description' => $attachment->post_content, + 'title' => $attachment->post_title, + ]; + + if ( 'custom' !== $settings['thumbnail_image_size'] ) { + return $image_data; + } + + $image_data['src'] = Group_Control_Image_Size::get_attachment_image_src( $image_id, 'thumbnail_image', $settings ); + $image_data['width'] = $settings['thumbnail_image_custom_dimension']['width']; + $image_data['height'] = $settings['thumbnail_image_custom_dimension']['height']; + + return $image_data; + } +} diff --git a/modules/global-widget/data/controller.php b/modules/global-widget/data/controller.php new file mode 100644 index 00000000..af57b3eb --- /dev/null +++ b/modules/global-widget/data/controller.php @@ -0,0 +1,61 @@ +get_param( 'ids' ); + + if ( ! empty( $ids ) ) { + // TODO: This logic should be handled at REST API. + $ids = explode( ',', $ids ); + + foreach ( $ids as $template_id ) { + if ( ! $this->is_allowed_to_read_template( $template_id ) ) { + continue; + } + + $template_data = Plugin::elementor()->templates_manager->get_template_data( [ + 'source' => 'local', + 'template_id' => $template_id, + 'check_permissions' => false, + ] ); + + if ( ! empty( $template_data ) ) { + $result[ $template_id ] = $template_data['content'][0]; + } + } + } + + return $result; + } + + public function get_permission_callback( $request ) { + return current_user_can( 'edit_posts' ); + } + + private function is_allowed_to_read_template( $template_id ): bool { + return $this->user_can_edit_template( $template_id ) || $this->is_published_and_unprotected( $template_id ); + } + + private function is_published_and_unprotected( int $template_id ): bool { + $post_status = get_post_status( $template_id ); + + return 'publish' === $post_status && ! post_password_required( $template_id ); + } + + private function user_can_edit_template( int $template_id ): bool { + return current_user_can( 'edit_post', $template_id ); + } +} diff --git a/modules/global-widget/documents/widget.php b/modules/global-widget/documents/widget.php new file mode 100644 index 00000000..00be15c0 --- /dev/null +++ b/modules/global-widget/documents/widget.php @@ -0,0 +1,65 @@ + static::get_type(), + ] ); + } + + public function is_editable_by_current_user() { + return User::is_current_user_can_edit( $this->get_main_id() ); + } + + public function import( array $data ) { + parent::import( $data ); + + $this->update_main_meta( Module::WIDGET_TYPE_META_KEY, $data['content'][0]['widgetType'] ); + } + + public function save( $data ) { + // Since the method of 'modules/usage::before_document_save' will remove from global if new_status is the same as old. + $data['settings'] = [ 'post_status' => Document::STATUS_PUBLISH ]; + + return parent::save( $data ); + } +} diff --git a/modules/global-widget/import-export-customization/export.php b/modules/global-widget/import-export-customization/export.php new file mode 100644 index 00000000..f4437713 --- /dev/null +++ b/modules/global-widget/import-export-customization/export.php @@ -0,0 +1,75 @@ +export_global_widgets(); + + if ( empty( $global_widgets_data['files'] ) ) { + return $export_data; + } + + $export_data['files'] = array_merge( $export_data['files'], $global_widgets_data['files'] ); + + if ( ! empty( $global_widgets_data['manifest'] ) ) { + $export_data['manifest'][0]['templates'] = ( $export_data['manifest'][0]['templates'] ?? [] ) + $global_widgets_data['manifest']; + } + + return $export_data; + } + + private function export_global_widgets() { + $query_args = [ + 'post_type' => Source_Local::CPT, + 'post_status' => 'publish', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => Module::TEMPLATE_TYPE, + ], + ], + ]; + + $global_widgets_query = new \WP_Query( $query_args ); + + $manifest_data = []; + $files = []; + + foreach ( $global_widgets_query->posts as $widget_post ) { + $widget_id = $widget_post->ID; + + $widget_document = Plugin::elementor()->documents->get( $widget_id ); + + if ( ! $widget_document ) { + continue; + } + + $manifest_data[ $widget_id ] = $widget_document->get_export_summary(); + + $files[] = [ + 'path' => 'templates/' . $widget_id, + 'data' => $widget_document->get_export_data(), + ]; + } + + return [ + 'files' => $files, + 'manifest' => $manifest_data, + ]; + } +} diff --git a/modules/global-widget/import-export-customization/import.php b/modules/global-widget/import-export-customization/import.php new file mode 100644 index 00000000..634f0bcf --- /dev/null +++ b/modules/global-widget/import-export-customization/import.php @@ -0,0 +1,107 @@ +import_global_widgets( $data ); + + if ( ! empty( $global_widgets_result ) ) { + $result['templates']['succeed'] = array_merge( $result['templates']['succeed'], $global_widgets_result['succeed'] ); + $result['templates']['failed'] = array_merge( $result['templates']['failed'], $global_widgets_result['failed'] ); + + foreach ( $global_widgets_result['succeed_summary'] as $doc_type => $count ) { + $result['templates']['succeed_summary'][ $doc_type ] = ( $result['templates']['succeed_summary'][ $doc_type ] ?? 0 ) + $count; + } + } + + return $result; + } + + private function import_global_widgets( $data ) { + $path = $data['extracted_directory_path'] . 'templates/'; + $templates = $data['manifest']['templates']; + + $result = [ + 'succeed' => [], + 'failed' => [], + 'succeed_summary' => [], + ]; + + foreach ( $templates as $id => $template_settings ) { + if ( Module::TEMPLATE_TYPE !== $template_settings['doc_type'] ) { + continue; + } + + try { + $template_data = ImportExportCustomizationUtils::read_json_file( $path . $id ); + $imported_id = $this->import_global_widget( $id, $template_settings, $template_data, $data ); + + $result['succeed'][ $id ] = $imported_id; + $result['succeed_summary'][ $template_settings['doc_type'] ] = ( $result['succeed_summary'][ $template_settings['doc_type'] ] ?? 0 ) + 1; + } catch ( \Exception $error ) { + $result['failed'][ $id ] = $error->getMessage(); + } + } + + return $result; + } + + private function import_global_widget( $id, array $template_settings, array $template_data, array $import_data ) { + $new_document = Plugin::elementor()->documents->create( + Module::TEMPLATE_TYPE, + [ + 'post_title' => $template_settings['title'], + 'post_type' => Source_Local::CPT, + 'post_status' => 'publish', + ] + ); + + if ( is_wp_error( $new_document ) ) { + throw new \Exception( esc_html( $new_document->get_error_message() ) ); + } + + $template_data['import_settings'] = $template_settings; + $template_data['id'] = $id; + + if ( isset( $import_data['session_id'] ) ) { + $new_attachment_callback = function( $attachment_id ) use ( $import_data ) { + $this->set_session_post_meta( $attachment_id, $import_data['session_id'] ); + }; + + add_filter( 'elementor/template_library/import_images/new_attachment', $new_attachment_callback ); + } + + $new_document->import( $template_data ); + + if ( isset( $new_attachment_callback ) ) { + remove_filter( 'elementor/template_library/import_images/new_attachment', $new_attachment_callback ); + } + + $document_id = $new_document->get_main_id(); + + if ( isset( $import_data['session_id'] ) ) { + $this->set_session_post_meta( $document_id, $import_data['session_id'] ); + } + + return $document_id; + } + + private function set_session_post_meta( $post_id, $session_id ) { + update_post_meta( $post_id, '_elementor_import_session_id', $session_id ); + } +} diff --git a/modules/global-widget/module.php b/modules/global-widget/module.php new file mode 100644 index 00000000..e94539a8 --- /dev/null +++ b/modules/global-widget/module.php @@ -0,0 +1,279 @@ + 'Global_Widget', + ]; + + const LICENSE_FEATURE_NAME = 'global-widget'; + + public function __construct() { + parent::__construct(); + + $this->add_component( 'import_export_import', new ImportExportCustomization\Import() ); + $this->add_component( 'import_export_export', new ImportExportCustomization\Export() ); + + $this->add_hooks(); + + Plugin::elementor()->data_manager->register_controller_instance( new Data\Controller() ); + } + + public function get_widgets() { + return API::filter_active_features( static::WIDGET_NAME_CLASS_NAME_MAP ); + } + + public function get_name() { + return 'global-widget'; + } + + public function add_templates_localize_data( $settings ) { + $elementor = Plugin::elementor(); + + $templates_manager = $elementor->templates_manager; + + $widgets_types = $elementor->widgets_manager->get_widget_types(); + + $widget_templates = array_filter( $templates_manager->get_source( 'local' )->get_items( [ 'type' => self::TEMPLATE_TYPE ] ), function( $template ) use ( $widgets_types ) { + if ( empty( $template['widgetType'] ) || empty( $widgets_types[ $template['widgetType'] ] ) ) { + return false; + } + + // Open the stack in order to include the widget controls in initial editor config + $widgets_types[ $template['widgetType'] ]->get_stack( false ); + + return true; + } ); + + $widget_templates_content = []; + + foreach ( $widget_templates as $widget_template ) { + $widget_templates_content[ $widget_template['template_id'] ] = [ + 'elType' => 'widget', + 'title' => $widget_template['title'], + 'widgetType' => $widget_template['widgetType'], + ]; + } + + $settings = array_replace_recursive( $settings, [ + 'widget_templates' => $widget_templates_content, + 'should_show_promotion' => ! API::is_licence_has_feature( static::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ), + ] ); + + return $settings; + } + + public function set_template_widget_type_meta( $post_id, $template_data ) { + if ( self::TEMPLATE_TYPE === $template_data['type'] ) { + update_post_meta( $post_id, self::WIDGET_TYPE_META_KEY, $template_data['content'][0]['widgetType'] ); + } + } + + public function on_template_update( $template_id, $template_data ) { + if ( self::TEMPLATE_TYPE !== $template_data['type'] ) { + return; + } + + $this->delete_included_posts_css( $template_id ); + } + + public function filter_template_data( $data ) { + if ( self::TEMPLATE_TYPE === $data['type'] ) { + $data['widgetType'] = get_post_meta( $data['template_id'], self::WIDGET_TYPE_META_KEY, true ); + } + + return $data; + } + + public function get_element_child_type( Element_Base $default_child_type, array $element_data ) { + if ( isset( $element_data['templateID'] ) ) { + $template_post = get_post( $element_data['templateID'] ); + + if ( ! $template_post || 'trash' === $template_post->post_status ) { + return false; + } + } + + return $default_child_type; + } + + public function is_post_type_support_elementor( $is_supported, $post_id, $post_type ) { + if ( ! $is_supported || Source_Local::CPT !== $post_type ) { + return $is_supported; + } + + $is_widget_template = $this->is_widget_template( $post_id ); + + // FIX ME: Change `get_current_screen()` condition to better way. + if ( $is_widget_template && function_exists( 'get_current_screen' ) ) { + $screen = get_current_screen(); + + if ( ! empty( $screen->id ) && in_array( $screen->id, [ 'elementor_library', 'edit-elementor_library' ] ) ) { + $is_supported = false; + } + } + + return $is_supported; + } + + public function is_template_supports_export( $default_value, $template_id ) { + return $default_value && ! $this->is_widget_template( $template_id ); + } + + /** + * Remove user edit capabilities. + * + * Filters the user capabilities to disable editing in admin. + * + * @param array $allcaps An array of all the user's capabilities. + * @param array $caps Actual capabilities for meta capability. + * @param array $args Optional parameters passed to has_cap(), typically object ID. + * + * @return array + * @deprecated 3.1.0 Use `Plugin::elementor()->documents->remove_user_edit_cap()` instead. + */ + public function remove_user_edit_cap( $allcaps, $caps, $args ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', 'Plugin::elementor()->documents->remove_user_edit_cap()' ); + + return Plugin::elementor()->documents->remove_user_edit_cap( $allcaps, $caps, $args ); + } + + public function is_widget_template( $template_id ) { + $template_type = Source_Local::get_template_type( $template_id ); + + return self::TEMPLATE_TYPE === $template_type; + } + + public function set_global_widget_included_posts_list( $post_id, $editor_data ) { + $global_widget_ids = []; + + Plugin::elementor()->db->iterate_data( $editor_data, function( $element_data ) use ( &$global_widget_ids ) { + if ( isset( $element_data['templateID'] ) ) { + $global_widget_ids[] = $element_data['templateID']; + } + } ); + + foreach ( $global_widget_ids as $widget_id ) { + $included_posts = get_post_meta( $widget_id, self::INCLUDED_POSTS_LIST_META_KEY, true ); + + if ( ! is_array( $included_posts ) ) { + $included_posts = []; + } + + $included_posts[ $post_id ] = true; + + update_post_meta( $widget_id, self::INCLUDED_POSTS_LIST_META_KEY, $included_posts ); + } + } + + private function delete_included_posts_css( $template_id ) { + $including_post_ids = (array) get_post_meta( $template_id, self::INCLUDED_POSTS_LIST_META_KEY, true ); + + if ( empty( $including_post_ids ) ) { + return; + } + + foreach ( array_keys( $including_post_ids ) as $post_id ) { + delete_post_meta( $post_id, '_elementor_css' ); + } + } + + /** + * @param Documents_Manager $documents_manager + */ + public function register_documents( $documents_manager ) { + $documents_manager->register_document_type( self::TEMPLATE_TYPE, Documents\Widget::get_class_full_name() ); + } + + public function on_elementor_editor_init() { + if ( ! API::is_licence_has_feature( static::LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $promotion_data = [ + 'title' => esc_html__( 'Meet Our Global Widget', 'elementor-pro' ), + 'messages' => [ + esc_html__( 'Create Global Widgets. Modify the content, style and setting of any widget and reuse it across your website to accelerate your workflow and stay consistent.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-global-widget/', + ]; + + $promotion_data = Filtered_Promotions_Manager::get_filtered_promotion_data( $promotion_data, 'elementor-pro/advanced-global-widget-pro-widget/promotion', 'link' ); + $promotion = Tiers::get_promotion_template( $promotion_data, true ); + + Plugin::elementor()->common->add_template( $promotion, 'text' ); + + return; + } + + Plugin::elementor()->common->add_template( __DIR__ . '/views/panel-template.php' ); + } + + /** + * Get document data. + * + * Used to manipulate data of global widgets. + * + * @param $data + * @param $document + * + * @return array + */ + private function get_document_data( $data, $document ) { + // If not a global widget template document or does not have elements. + if ( ! ( $document instanceof Widget ) && ! empty( $data['elements'] ) ) { + $data['elements'] = Plugin::elementor()->db->iterate_data( $data['elements'], function( $element ) { + if ( ! empty( $element['templateID'] ) ) { + $element['originalWidgetType'] = $element['widgetType']; + $element['widgetType'] = 'global'; + } + + return $element; + } ); + } + + return $data; + } + + + private function add_hooks() { + add_action( 'elementor/documents/register', [ $this, 'register_documents' ] ); + add_action( 'elementor/template-library/after_save_template', [ $this, 'set_template_widget_type_meta' ], 10, 2 ); + add_action( 'elementor/template-library/after_update_template', [ $this, 'on_template_update' ], 10, 2 ); + add_action( 'elementor/editor/init', [ $this, 'on_elementor_editor_init' ] ); + add_action( 'elementor/editor/after_save', [ $this, 'set_global_widget_included_posts_list' ], 10, 2 ); + + add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_templates_localize_data' ] ); + add_filter( 'elementor/template-library/get_template', [ $this, 'filter_template_data' ] ); + add_filter( 'elementor/element/get_child_type', [ $this, 'get_element_child_type' ], 10, 2 ); + add_filter( 'elementor/utils/is_post_support', [ $this, 'is_post_type_support_elementor' ], 10, 3 ); + + add_filter( 'elementor/template_library/is_template_supports_export', [ $this, 'is_template_supports_export' ], 10, 2 ); + add_filter( 'elementor/document/save/data', function ( $data, $document ) { + return $this->get_document_data( $data, $document ); + }, 10, 2 ); + add_filter( 'elementor/import-export-customization/export/templates_data', [ $this->get_component( 'import_export_export' ), 'add_global_widgets_to_export' ], 10, 3 ); + add_filter( 'elementor/import-export-customization/import/templates_result', [ $this->get_component( 'import_export_import' ), 'add_global_widgets_to_import' ], 10, 4 ); + } +} diff --git a/modules/global-widget/views/panel-template.php b/modules/global-widget/views/panel-template.php new file mode 100644 index 00000000..3305e6cd --- /dev/null +++ b/modules/global-widget/views/panel-template.php @@ -0,0 +1,33 @@ + + + + + diff --git a/modules/global-widget/widgets/global-widget.php b/modules/global-widget/widgets/global-widget.php new file mode 100644 index 00000000..8d504510 --- /dev/null +++ b/modules/global-widget/widgets/global-widget.php @@ -0,0 +1,255 @@ +templates_manager->get_template_data( [ + 'source' => 'local', + 'template_id' => $data['templateID'], + 'check_permissions' => false, + ] ); + + if ( is_wp_error( $template_data ) ) { + throw new \Exception( $template_data->get_error_message() ); + } + + if ( empty( $template_data['content'] ) ) { + throw new \Exception( 'Template content not found.' ); + } + + $this->set_template_data( $template_data ); + + $template_widget_type = $this->get_template_widget_type(); + $original_widget_type = Plugin::elementor()->widgets_manager->get_widget_types( + $template_widget_type + ); + + if ( ! $original_widget_type ) { + throw new \Exception( 'Original widget type not found.' ); + } + + // If it saved as draft it already have the recent settings. + if ( empty( $data['draft'] ) ) { + if ( empty( $data['originalWidgetType'] ) ) { + // If: `$data['originalWidgetType']` exists it means that the data was manipulated in saving process, from the backend. + // so `widgetType` is 'global' and have to be changed. + $data['widgetType'] = $template_widget_type; + } + + if ( ! $this->is_draft_or_autosave_process() ) { + // If its not 'draft saving process' then settings should be according the template. + // Since draft saving process, already have the recent settings to save. + $data['settings'] = $this->get_template_settings(); + } + } + + $this->original_widget_type = $original_widget_type; + $this->data = $data; + } + + parent::__construct( $data, $args ); + } + + public function show_in_panel() { + return false; + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_raw_data( $with_html_content = false ) { + $raw_data = parent::get_raw_data( $with_html_content ); + + // Save 'templateID' in all situations. + $raw_data['templateID'] = $this->get_data( 'templateID' ); + + if ( $this->is_draft_or_autosave_process() ) { + $raw_data['draft'] = true; + + // Keep the current snapshot, just mark it as a draft. + return $raw_data; + } + + if ( $this->is_saved_as_draft() ) { + // If: Item saved as draft + // Then: the the `$raw_data` hold recently saved draft template, with original widget type. + $raw_data['widgetType'] = $this->get_template_widget_type(); + + return $raw_data; + } + + if ( apply_filters( 'elementor/element/should_render_shortcode', false ) ) { + $raw_data['widgetType'] = $this->get_name(); + + return $raw_data; + } + + return $raw_data; + } + + public function render_content() { + $this->get_original_element_instance()->render_content(); + } + + public function get_unique_selector() { + return '.elementor-global-' . $this->get_data( 'templateID' ); + } + + public function get_name() { + return 'global'; + } + + public function get_title() { + return esc_html__( 'Global', 'elementor-pro' ); + } + + public function get_script_depends() { + if ( $this->is_type_instance() ) { + return []; + } + + return $this->get_original_element_instance()->get_script_depends(); + } + + public function get_style_depends() { + if ( $this->is_type_instance() ) { + return []; + } + + return $this->get_original_element_instance()->get_style_depends(); + } + + public function get_controls( $control_id = null ) { + if ( $this->is_type_instance() ) { + return []; + } + + return $this->get_original_element_instance()->get_controls(); + } + + public function get_original_element_instance() { + if ( ! $this->original_element_instance ) { + $this->init_original_element_instance(); + } + + return $this->original_element_instance; + } + + public function on_export() { + return $this->get_template_content(); + } + + public function render_plain_content() { + $this->get_original_element_instance()->render_plain_content(); + } + + protected function add_render_attributes() { + // Never called from editor, this method is used only for frontend/preview. + parent::add_render_attributes(); + + $skin_type = $this->get_settings( '_skin' ); + + $original_widget_type = $this->get_original_element_instance()->get_data( 'widgetType' ); + + $this->set_render_attribute( '_wrapper', 'data-widget_type', $original_widget_type . '.' . ( $skin_type ? $skin_type : 'default' ) ); + + $this->add_render_attribute( '_wrapper', [ + 'class' => [ + 'elementor-global-' . $this->get_data( 'templateID' ), + 'elementor-widget-' . $original_widget_type, + ], + ] ); + } + + private function init_original_element_instance() { + $widget_class = $this->original_widget_type->get_class_name(); + + $template_content = $this->get_template_or_draft_content(); + $template_content['id'] = $this->get_id(); + + $this->original_element_instance = new $widget_class( + $template_content, + $this->original_widget_type->get_default_args() + ); + } + + private function is_draft_or_autosave_process() { + /** + * `Plugin::elementor()->common` is not available for guest/logged out users. + */ + if ( ! Plugin::elementor()->common ) { + return false; + } + + $ajax = Plugin::elementor()->common->get_component( 'ajax' ); + $ajax_data = $ajax->get_current_action_data(); + + // Is draft or autosave? + return $ajax_data && 'save_builder' === $ajax_data['action'] && in_array( $ajax_data['data']['status'], [ + Document::STATUS_DRAFT, + Document::STATUS_AUTOSAVE, + ], true ); + } + + private function is_saved_as_draft() { + return $this->get_data( 'draft' ); + } + + private function set_template_data( $template_data ) { + $this->template_data = $template_data; + } + + private function get_template_widget_type() { + return $this->template_data['content'][0]['widgetType']; + } + + private function get_template_settings() { + return $this->template_data['content'][0]['settings']; + } + + private function get_template_content() { + return $this->template_data['content'][0]; + } + + private function get_template_or_draft_content() { + if ( $this->is_saved_as_draft() ) { + $draft_data = $this->data; + $draft_data['widgetType'] = $this->get_template_widget_type(); + + return $draft_data; + } + + return $this->get_template_content(); + } +} diff --git a/modules/hotspot/module.php b/modules/hotspot/module.php new file mode 100644 index 00000000..99f485fa --- /dev/null +++ b/modules/hotspot/module.php @@ -0,0 +1,53 @@ +get_css_assets_url( 'widget-hotspot', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/hotspot/widgets/hotspot.php b/modules/hotspot/widgets/hotspot.php new file mode 100644 index 00000000..eb1208b3 --- /dev/null +++ b/modules/hotspot/widgets/hotspot.php @@ -0,0 +1,1297 @@ +remove_control( 'caption_source' ); + $this->remove_control( 'caption' ); + $this->remove_control( 'link_to' ); + $this->remove_control( 'link' ); + $this->remove_control( 'open_lightbox' ); + + /** + * Section Hotspot + */ + $this->start_controls_section( + 'hotspot_section', + [ + 'label' => esc_html__( 'Hotspot', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $repeater->start_controls_tabs( 'hotspot_repeater' ); + + $repeater->start_controls_tab( + 'hotspot_content_tab', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'hotspot_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'label_block' => true, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'hotspot_link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'hotspot_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $repeater->add_control( + 'hotspot_icon_position', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$start}", + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$end}", + ], + ], + 'selectors_dictionary' => [ + 'start' => 'grid-column: 1;', + 'end' => 'grid-column: 2;', + ], + 'condition' => [ + 'hotspot_icon[value]!' => '', + 'hotspot_label[value]!' => '', + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .e-hotspot__icon' => '{{VALUE}}', + ], + 'default' => 'start', + ] + ); + + $repeater->add_control( + 'hotspot_icon_spacing', + [ + 'label' => esc_html__( 'Icon Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'default' => [ + 'size' => 5, + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .e-hotspot__button' => + 'grid-gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'hotspot_icon[value]!' => '', + 'hotspot_label[value]!' => '', + ], + ] + ); + + $repeater->add_control( + 'hotspot_custom_size', + [ + 'label' => esc_html__( 'Custom Hotspot Size', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'default' => 'no', + 'description' => esc_html__( 'Set custom Hotspot size that will only affect this specific hotspot.', 'elementor-pro' ), + ] + ); + + $repeater->add_control('hotspot_width', + [ + 'label' => esc_html__( 'Min Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => '--hotspot-min-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'hotspot_custom_size' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'hotspot_height', + [ + 'label' => esc_html__( 'Min Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => '--hotspot-min-height: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'hotspot_custom_size' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'hotspot_tooltip_content', + [ + 'render_type' => 'template', + 'label' => esc_html__( 'Tooltip Content', 'elementor-pro' ), + 'type' => Controls_Manager::WYSIWYG, + 'default' => esc_html__( 'Add Your Tooltip Text Here', 'elementor-pro' ), + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( + 'hotspot_position_tab', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'hotspot_horizontal', + [ + 'label' => esc_html__( 'Horizontal Orientation', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => is_rtl() ? 'right' : 'left', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'toggle' => false, + ] + ); + + $repeater->add_responsive_control( + 'hotspot_offset_x', + [ + 'label' => esc_html__( 'Offset', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ '%' ], + 'default' => [ + 'unit' => '%', + 'size' => 50, + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => + '{{hotspot_horizontal.VALUE}}: {{SIZE}}%; --hotspot-translate-x: {{SIZE}}%;', + ], + ] + ); + + $repeater->add_control( + 'hotspot_vertical', + [ + 'label' => esc_html__( 'Vertical Orientation', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'default' => 'top', + 'toggle' => false, + ] + ); + + $repeater->add_responsive_control( + 'hotspot_offset_y', + [ + 'label' => esc_html__( 'Offset', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ '%' ], + 'default' => [ + 'unit' => '%', + 'size' => 50, + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => + '{{hotspot_vertical.VALUE}}: {{SIZE}}%; --hotspot-translate-y: {{SIZE}}%;', + ], + ] + ); + + $repeater->add_control( + 'hotspot_tooltip_position', + [ + 'label' => esc_html__( 'Custom Tooltip Properties', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'default' => 'no', + 'description' => esc_html__( 'Set custom Tooltip opening that will only affect this specific hotspot.', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'hotspot_heading', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'hotspot_tooltip_position' => 'yes', + ], + ] + ); + + $repeater->add_responsive_control( + 'hotspot_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'right' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'bottom' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'left' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'top' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .e-hotspot--tooltip-position' => 'right: initial;bottom: initial;left: initial;top: initial;{{VALUE}}: calc(100% + 5px );', + ], + 'condition' => [ + 'hotspot_tooltip_position' => 'yes', + ], + 'render_type' => 'template', + ] + ); + + $repeater->add_responsive_control( + 'hotspot_tooltip_width', + [ + 'label' => esc_html__( 'Min Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 2000, + ], + 'em' => [ + 'max' => 200, + ], + 'rem' => [ + 'max' => 200, + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .e-hotspot__tooltip' => 'min-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'hotspot_tooltip_position' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'hotspot_tooltip_text_wrap', + [ + 'label' => esc_html__( 'Text Wrap', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => '--white-space: normal', + ], + 'condition' => [ + 'hotspot_tooltip_position' => 'yes', + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $this->add_control( + 'hotspot', + [ + 'label' => esc_html__( 'Hotspot', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'title_field' => '{{{ hotspot_label }}}', + 'default' => [ + [ + // Default #1 circle + ], + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'hotspot_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'e-hotspot--soft-beat' => esc_html__( 'Soft Beat', 'elementor-pro' ), + 'e-hotspot--expand' => esc_html__( 'Expand', 'elementor-pro' ), + 'e-hotspot--overlay' => esc_html__( 'Overlay', 'elementor-pro' ), + '' => esc_html__( 'None', 'elementor-pro' ), + ], + 'default' => 'e-hotspot--expand', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'hotspot_sequenced_animation', + [ + 'label' => esc_html__( 'Sequenced Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'default' => 'no', + 'frontend_available' => true, + 'render_type' => 'none', + ] + ); + + $this->add_control( + 'hotspot_sequenced_animation_duration', + [ + 'label' => esc_html__( 'Sequence Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 20000, + 'step' => 100, + ], + ], + 'condition' => [ + 'hotspot_sequenced_animation' => 'yes', + ], + 'frontend_available' => true, + 'render_type' => 'ui', + ] + ); + + $this->end_controls_section(); + + /** + * Tooltip Section + */ + $this->start_controls_section( + 'tooltip_section', + [ + 'label' => esc_html__( 'Tooltip', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'tooltip_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'top', + 'toggle' => false, + 'options' => [ + 'right' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'bottom' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'left' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'top' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-hotspot--tooltip-position' => 'right: initial;bottom: initial;left: initial;top: initial;{{VALUE}}: calc(100% + 5px );', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'tooltip_trigger', + [ + 'label' => esc_html__( 'Trigger', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'mouseenter' => esc_html__( 'Hover', 'elementor-pro' ), + 'click' => esc_html__( 'Click', 'elementor-pro' ), + 'none' => esc_html__( 'None', 'elementor-pro' ), + ], + 'default' => 'click', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'tooltip_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'e-hotspot--fade-in-out' => esc_html__( 'Fade In/Out', 'elementor-pro' ), + 'e-hotspot--fade-grow' => esc_html__( 'Fade Grow', 'elementor-pro' ), + 'e-hotspot--fade-direction' => esc_html__( 'Fade By Direction', 'elementor-pro' ), + 'e-hotspot--slide-direction' => esc_html__( 'Slide By Direction', 'elementor-pro' ), + ], + 'default' => 'e-hotspot--fade-in-out', + 'placeholder' => esc_html__( 'Enter your image caption', 'elementor-pro' ), + 'condition' => [ + 'tooltip_trigger!' => 'none', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'tooltip_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 10000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-transition-duration: {{SIZE}}ms;', + ], + 'condition' => [ + 'tooltip_trigger!' => 'none', + ], + ] + ); + + $this->end_controls_section(); + + /************* + * Style Tab + ************/ + /** + * Section Style Image + */ + + $this->remove_control( 'section_style_caption' ); + + $this->remove_control( 'caption_align' ); + + $this->remove_control( 'text_color' ); + + $this->remove_control( 'caption_background_color' ); + + $this->remove_control( 'caption_typography' ); + + $this->remove_control( 'caption_text_shadow' ); + + $this->remove_control( 'caption_space' ); + + $this->update_control( 'align', [ + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--background-align: {{VALUE}};', + ], + ] ); + + $this->update_control( + 'width', + [ + 'selectors' => [ + '{{WRAPPER}}' => '--container-width: {{SIZE}}{{UNIT}}; --image-width: 100%;', + ], + ] + ); + + $this->update_control( + 'space', + [ + 'selectors' => [ + '{{WRAPPER}}' => '--container-max-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->update_control( + 'height', + [ + 'selectors' => [ + '{{WRAPPER}}' => '--container-height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->remove_control( 'hover_animation' ); + + $this->update_control( + 'opacity', + [ + 'selectors' => [ + '{{WRAPPER}}' => '--opacity: {{SIZE}};', + ], + ] + ); + + $this->update_control( + 'opacity_hover', + [ + 'selectors' => [ + '{{WRAPPER}} .elementor-widget-container>img:hover' => '--opacity: {{SIZE}};', + ], + ] + ); + + /** + * Section Style Hotspot + */ + $this->start_controls_section( + 'section_style_hotspot', + [ + 'label' => esc_html__( 'Hotspot', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'style_hotspot_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + ] + ); + + $this->add_responsive_control( + 'style_hotspot_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 300, + ], + 'em' => [ + 'max' => 30, + ], + 'rem' => [ + 'max' => 30, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'style_typography', + 'selector' => '{{WRAPPER}} .e-hotspot__label', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_responsive_control( + 'style_hotspot_width', + [ + 'label' => esc_html__( 'Min Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-min-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'style_hotspot_height', + [ + 'label' => esc_html__( 'Min Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-min-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'style_hotspot_box_color', + [ + 'label' => esc_html__( 'Box Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-box-color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + ] + ); + + $this->add_responsive_control( + 'style_hotspot_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-padding: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'style_hotspot_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--hotspot-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'style_hotspot_box_shadow', + 'selector' => ' + {{WRAPPER}} .e-hotspot:not(.e-hotspot--circle) .e-hotspot__button, + {{WRAPPER}} .e-hotspot.e-hotspot--circle .e-hotspot__button .e-hotspot__outer-circle + ', + ] + ); + + $this->end_controls_section(); + + /** + * Section Style Tooltip + */ + $this->start_controls_section( + 'section_style_tooltip', + [ + 'label' => esc_html__( 'Tooltip', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'style_tooltip_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'style_tooltip_typography', + 'selector' => '{{WRAPPER}} .e-hotspot__tooltip', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + ] + ); + + $this->add_responsive_control( + 'style_tooltip_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-align: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'style_tooltip_heading', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'style_tooltip_width', + [ + 'label' => esc_html__( 'Min Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 2000, + ], + 'em' => [ + 'max' => 200, + ], + 'rem' => [ + 'max' => 200, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-min-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'style_tooltip_max_width', + [ + 'label' => esc_html__( 'Max Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 2000, + ], + 'em' => [ + 'max' => 200, + ], + 'rem' => [ + 'max' => 200, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-max-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'style_tooltip_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'style_tooltip_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-color: {{VALUE}}', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + ] + ); + + $this->add_control( + 'style_tooltip_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tooltip-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'style_tooltip_box_shadow', + 'selector' => '{{WRAPPER}} .e-hotspot__tooltip', + ] + ); + + $this->end_controls_section(); + } + + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['image']['url'] ) ) { + return; + } + + $is_tooltip_direction_animation = 'e-hotspot--slide-direction' === $settings['tooltip_animation'] || 'e-hotspot--fade-direction' === $settings['tooltip_animation']; + $show_tooltip = 'none' === $settings['tooltip_trigger']; + $sequenced_animation_class = 'yes' === $settings['hotspot_sequenced_animation'] ? 'e-hotspot--sequenced' : ''; + + // Main Image + Group_Control_Image_Size::print_attachment_image_html( $settings, 'image', 'image' ); + + // Hotspot + foreach ( $settings['hotspot'] as $key => $hotspot ) : + $is_circle = ! $hotspot['hotspot_label'] && ! $hotspot['hotspot_icon']['value']; + $is_only_icon = ! $hotspot['hotspot_label'] && $hotspot['hotspot_icon']['value']; + $hotspot_position_x = '%' === $hotspot['hotspot_offset_x']['unit'] ? 'e-hotspot--position-' . $hotspot['hotspot_horizontal'] : ''; + $hotspot_position_y = '%' === $hotspot['hotspot_offset_y']['unit'] ? 'e-hotspot--position-' . $hotspot['hotspot_vertical'] : ''; + $is_hotspot_link = ! empty( $hotspot['hotspot_link']['url'] ); + $hotspot_element_tag = $is_hotspot_link ? 'a' : 'div'; + + // hotspot attributes + $hotspot_repeater_setting_key = $this->get_repeater_setting_key( 'hotspot', 'hotspots', $key ); + $this->add_render_attribute( + $hotspot_repeater_setting_key, [ + 'class' => [ + 'e-hotspot', + 'elementor-repeater-item-' . $hotspot['_id'], + $sequenced_animation_class, + $hotspot_position_x, + $hotspot_position_y, + $is_hotspot_link ? 'e-hotspot--link' : '', + ( 'click' === $settings['tooltip_trigger'] && $is_hotspot_link ) ? 'e-hotspot--no-tooltip' : '', + ], + ] + ); + if ( $is_circle ) { + $this->add_render_attribute( $hotspot_repeater_setting_key, 'class', 'e-hotspot--circle' ); + } + if ( $is_only_icon ) { + $this->add_render_attribute( $hotspot_repeater_setting_key, 'class', 'e-hotspot--icon' ); + } + + if ( $is_hotspot_link ) { + $this->add_link_attributes( $hotspot_repeater_setting_key, $hotspot['hotspot_link'] ); + } + + // hotspot trigger attributes + $trigger_repeater_setting_key = $this->get_repeater_setting_key( 'trigger', 'hotspots', $key ); + $this->add_render_attribute( + $trigger_repeater_setting_key, [ + 'class' => [ + 'e-hotspot__button', + $settings['hotspot_animation'], + ], + ] + ); + + //direction mask attributes + $direction_mask_repeater_setting_key = $this->get_repeater_setting_key( 'e-hotspot__direction-mask', 'hotspots', $key ); + $this->add_render_attribute( + $direction_mask_repeater_setting_key, [ + 'class' => [ + 'e-hotspot__direction-mask', + ( $is_tooltip_direction_animation ) ? 'e-hotspot--tooltip-position' : '', + ], + ] + ); + + //tooltip attributes + $tooltip_custom_position = ( $is_tooltip_direction_animation && $hotspot['hotspot_tooltip_position'] && $hotspot['hotspot_position'] ) ? 'e-hotspot--override-tooltip-animation-from-' . $hotspot['hotspot_position'] : ''; + $tooltip_repeater_setting_key = $this->get_repeater_setting_key( 'tooltip', 'hotspots', $key ); + $this->add_render_attribute( + $tooltip_repeater_setting_key, [ + 'class' => [ + 'e-hotspot__tooltip', + ( $show_tooltip ) ? 'e-hotspot--show-tooltip' : '', + ( ! $is_tooltip_direction_animation ) ? 'e-hotspot--tooltip-position' : '', + ( ! $show_tooltip ) ? $settings['tooltip_animation'] : '', + $tooltip_custom_position, + ], + ] + ); ?> + + + < print_render_attribute_string( $hotspot_repeater_setting_key ); ?>> + + +
      print_render_attribute_string( $trigger_repeater_setting_key ); ?>> + +
      +
      + + +
      + + +
      + + +
      + + + + +
      print_render_attribute_string( $direction_mask_repeater_setting_key ); ?>> + +
      print_render_attribute_string( $tooltip_repeater_setting_key ); ?> > + +
      + +
      + + + + > + + + + + <# + const image = { + id: settings.image.id, + url: settings.image.url, + size: settings.image_size, + dimension: settings.image_custom_dimension, + model: view.getEditModel() + }; + + const imageUrl = elementor.imagesManager.getImageUrl( image ); + + if ( ! imageUrl ) { + return; + } + #> + + <# + const isTooltipDirectionAnimation = (settings.tooltip_animation==='e-hotspot--slide-direction' || settings.tooltip_animation==='e-hotspot--fade-direction' ) ? true : false; + const showTooltip = ( settings.tooltip_trigger === 'none' ); + + _.each( settings.hotspot, ( hotspot, index ) => { + const iconHTML = elementor.helpers.renderIcon( view, hotspot.hotspot_icon, {}, 'i' , 'object' ); + + const isCircle = !hotspot.hotspot_label && !hotspot.hotspot_icon.value; + const isOnlyIcon = !hotspot.hotspot_label && hotspot.hotspot_icon.value; + const hotspotPositionX = '%' === hotspot.hotspot_offset_x.unit ? 'e-hotspot--position-' + hotspot.hotspot_horizontal : ''; + const hotspotPositionY = '%' === hotspot.hotspot_offset_y.unit ? 'e-hotspot--position-' + hotspot.hotspot_vertical : ''; + const hotspotLink = hotspot.hotspot_link.url; + const hotspotElementTag = hotspotLink ? 'a': 'div'; + + // hotspot attributes + const hotspotRepeaterSettingKey = view.getRepeaterSettingKey( 'hotspot', 'hotspots', index ); + view.addRenderAttribute( hotspotRepeaterSettingKey, { + 'class' : [ + 'e-hotspot', + 'elementor-repeater-item-' + hotspot._id, + hotspotPositionX, + hotspotPositionY, + hotspotLink ? 'e-hotspot--link' : '',, + ] + }); + + if ( isCircle ) { + view.addRenderAttribute( hotspotRepeaterSettingKey, 'class', 'e-hotspot--circle' ); + } + + if ( isOnlyIcon ) { + view.addRenderAttribute( hotspotRepeaterSettingKey, 'class', 'e-hotspot--icon' ); + } + + // hotspot trigger attributes + const triggerRepeaterSettingKey = view.getRepeaterSettingKey( 'trigger', 'hotspots', index ); + view.addRenderAttribute(triggerRepeaterSettingKey, { + 'class' : [ + 'e-hotspot__button', + settings.hotspot_animation, + //'hotspot-trigger-' + hotspot.hotspot_icon_position + ] + }); + + //direction mask attributes + const directionMaskRepeaterSettingKey = view.getRepeaterSettingKey( 'e-hotspot__direction-mask', 'hotspots', index ); + view.addRenderAttribute(directionMaskRepeaterSettingKey, { + 'class' : [ + 'e-hotspot__direction-mask', + ( isTooltipDirectionAnimation ) ? 'e-hotspot--tooltip-position' : '' + ] + }); + + //tooltip attributes + const tooltipCustomPosition = ( isTooltipDirectionAnimation && hotspot.hotspot_tooltip_position && hotspot.hotspot_position ) ? 'e-hotspot--override-tooltip-animation-from-' + hotspot.hotspot_position : ''; + const tooltipRepeaterSettingKey = view.getRepeaterSettingKey('tooltip', 'hotspots', index); + view.addRenderAttribute( tooltipRepeaterSettingKey, { + 'class': [ + 'e-hotspot__tooltip', + ( showTooltip ) ? 'e-hotspot--show-tooltip' : '', + ( !isTooltipDirectionAnimation ) ? 'e-hotspot--tooltip-position' : '', + ( !showTooltip ) ? settings.tooltip_animation : '', + tooltipCustomPosition + ], + }); + + #> + <{{{ hotspotElementTag }}} {{{ view.getRenderAttributeString( hotspotRepeaterSettingKey ) }}}> + + +
      + <# if ( isCircle ) { #> +
      +
      + <# } else { #> + <# if (hotspot.hotspot_icon.value){ #> +
      {{{ iconHTML.value }}}
      + <# } #> + <# if ( hotspot.hotspot_label ){ #> +
      {{{ hotspot.hotspot_label }}}
      + <# } #> + <# } #> +
      + + + <# if( hotspot.hotspot_tooltip_content && ! ( 'click' === settings.tooltip_trigger && hotspotLink ) ){ #> + <# if( isTooltipDirectionAnimation ){ #> +
      + <# } #> +
      + {{{ hotspot.hotspot_tooltip_content }}} +
      + <# if( isTooltipDirectionAnimation ){ #> +
      + <# } #> + <# } #> + + + <# }); #> + add_actions(); + } + + public function admin_columns_headers( $defaults ) { + $defaults['shortcode'] = esc_html__( 'Shortcode', 'elementor-pro' ); + + return $defaults; + } + + public function admin_columns_content( $column_name, $post_id ) { + if ( 'shortcode' !== $column_name ) { + return; + } + + printf( + '', + sprintf( + /* translators: %s: Template ID. */ + esc_attr( 'elementor-templte-%s-shortcode' ), + $post_id // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ), + sprintf( + /* translators: %s: Template ID. */ + esc_html__( 'Elementor template shortcode for template %s', 'elementor-pro' ), + $post_id // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ), + sprintf( + /* translators: %s: Shortcode, %d: Template ID. */ + esc_attr( '[%s id="%d"]' ), + self::SHORTCODE, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $post_id // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ) + ); + } + + public function shortcode( $attributes = [] ) { + if ( empty( $attributes['id'] ) ) { + return ''; + } + + $include_css = false; + + if ( isset( $attributes['css'] ) && 'false' !== $attributes['css'] ) { + $include_css = (bool) $attributes['css']; + } + + return Plugin::elementor()->frontend->get_builder_content_for_display( $attributes['id'], $include_css ); + } + + private function add_actions() { + if ( is_admin() ) { + add_action( 'manage_' . Source_Local::CPT . '_posts_columns', [ $this, 'admin_columns_headers' ] ); + add_action( 'manage_' . Source_Local::CPT . '_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + } + + add_shortcode( self::SHORTCODE, [ $this, 'shortcode' ] ); + } +} diff --git a/modules/library/module.php b/modules/library/module.php new file mode 100644 index 00000000..ef6794e3 --- /dev/null +++ b/modules/library/module.php @@ -0,0 +1,149 @@ +add_filters(); + $this->add_actions(); + + new Shortcode(); + } + + public function get_name() { + return 'library'; + } + + public function register_wp_widgets() { + register_widget( 'ElementorPro\Modules\Library\WP_Widgets\Elementor_Library' ); + } + + public function add_to_results_for_library_widget_templates( $val, $post, $request ) { + $document = Plugin::elementor()->documents->get( $post->ID ); + if ( $document ) { + return true; + } + + return false; + } + + public function format_post_title_for_library_widget_templates( $post_title, $post_id, $request ) { + $document = Plugin::elementor()->documents->get( $post_id ); + return $post_title . ' (' . $document->get_post_type_title() . ')'; + } + + public function add_actions() { + add_action( 'widgets_init', [ $this, 'register_wp_widgets' ] ); + } + + /** + * @deprecated 2.6.0 No longer used by internal code. See Autocomplete documentation in Query-Control Module. + * @param array $results + * @param array $data + * + * @return array + */ + public function get_autocomplete_for_library_widget_templates( array $results, array $data ) { + $document_types = Plugin::elementor()->documents->get_document_types( [ + 'show_in_library' => true, + ] ); + + $query_params = [ + 's' => $data['q'], + 'post_type' => Source_Local::CPT, + 'posts_per_page' => -1, + 'orderby' => 'meta_value', + 'order' => 'ASC', + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => array_keys( $document_types ), + 'compare' => 'IN', + ], + ], + ]; + + $query = new \WP_Query( $query_params ); + + $results = []; + + foreach ( $query->posts as $post ) { + $document = Plugin::elementor()->documents->get( $post->ID ); + if ( $document ) { + $results[] = [ + 'id' => $post->ID, + 'text' => esc_html( $post->post_title ) . ' (' . $document->get_post_type_title() . ')', + ]; + } + } + + return $results; + } + + /** + * @deprecated 2.6.0 No longer used by internal code. See Autocomplete documentation in Query-Control Module. + * @param $results + * @param $request + * + * @return mixed + */ + public function get_value_title_for_library_widget_templates( $results, $request ) { + $ids = (array) $request['id']; + + $query = new \WP_Query( + [ + 'post_type' => Source_Local::CPT, + 'post__in' => $ids, + 'posts_per_page' => -1, + ] + ); + + foreach ( $query->posts as $post ) { + $document = Plugin::elementor()->documents->get( $post->ID ); + if ( $document ) { + $results[ $post->ID ] = esc_html( $post->post_title ) . ' (' . $document->get_post_type_title() . ')'; + } + } + + return $results; + } + + public function add_filters() { + add_filter( 'elementor/widgets/black_list', function( $black_list ) { + $black_list[] = 'ElementorPro\Modules\Library\WP_Widgets\Elementor_Library'; + + return $black_list; + } ); + } + + public static function get_templates() { + return Plugin::elementor()->templates_manager->get_source( 'local' )->get_items(); + } + + public static function empty_templates_message() { + return '
      +
      +
      ' . esc_html__( 'You Haven’t Saved Templates Yet.', 'elementor-pro' ) . '
      + +
      '; + } +} diff --git a/modules/library/widgets/template.php b/modules/library/widgets/template.php new file mode 100644 index 00000000..b2a92256 --- /dev/null +++ b/modules/library/widgets/template.php @@ -0,0 +1,108 @@ +start_controls_section( + 'section_template', + [ + 'label' => esc_html__( 'Template', 'elementor-pro' ), + ] + ); + + $document_types = Plugin::elementor()->documents->get_document_types( [ + 'show_in_library' => true, + ] ); + + $this->add_control( + 'template_id', + [ + 'label' => esc_html__( 'Choose Template', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => array_keys( $document_types ), + 'compare' => 'IN', + ], + ], + ], + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $template_id = $this->get_settings( 'template_id' ); + + if ( empty( $template_id ) ) { + return; + } + + if ( 'publish' !== get_post_status( $template_id ) ) { + return; + } + + ?> +
      + frontend->get_builder_content_for_display( $template_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> +
      + esc_html__( 'Embed your saved elements.', 'elementor-pro' ), + ] + ); + } + + /** + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + // PHPCS - Theme arg + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + if ( ! empty( $instance['title'] ) ) { + /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ + $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); + // PHPCS - Theme arg + echo $args['before_title'] . esc_html( $title ) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + if ( ! empty( $instance['template_id'] ) && 'publish' === get_post_status( $instance['template_id'] ) ) { + $this->sidebar_id = $args['id']; + + add_filter( 'elementor/frontend/builder_content_data', [ $this, 'filter_content_data' ] ); + + // PHPCS - the main content + echo Plugin::elementor()->frontend->get_builder_content_for_display( $instance['template_id'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + remove_filter( 'elementor/frontend/builder_content_data', [ $this, 'filter_content_data' ] ); + + unset( $this->sidebar_id ); + } + + // PHPCS - Theme arg + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + /** + * Avoid nesting a sidebar within a template that will appear in the sidebar itself + * + * @param array $data + * + * @return mixed + */ + public function filter_content_data( $data ) { + if ( ! empty( $data ) ) { + $data = Plugin::elementor()->db->iterate_data( $data, function( $element ) { + if ( 'widget' === $element['elType'] && 'sidebar' === $element['widgetType'] && $this->sidebar_id === $element['settings']['sidebar'] ) { + $element['settings']['sidebar'] = null; + } + + return $element; + } ); + } + + return $data; + } + + /** + * @param array $instance + * + * @return void + */ + public function form( $instance ) { + $default = [ + 'title' => '', + 'template_id' => '', + ]; + + $instance = array_merge( $default, $instance ); + + $templates = Module::get_templates(); + + if ( ! $templates ) { + // PHPCS - the method empty_templates_message is safe. + echo Module::empty_templates_message(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + return; + } + ?> +

      + + +

      + +

      + + + + + href="" + > + + + +

      + build_layout_render_attribute(); + ?> +
      widget->get_render_attribute_string( 'layout' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>> + + +
      + settings['cta_link'] = [ + [ + 'cta_link_text' => $this->settings['cta_section_button_text'] ?? '', + 'cta_link_type' => $this->settings['cta_link_type'] ?? null, + 'cta_link_url' => $this->settings['cta_link_url'] ?? null, + 'cta_link_mail' => $this->settings['cta_link_mail'] ?? null, + 'cta_link_mail_subject' => $this->settings['cta_link_mail_subject'] ?? null, + 'cta_link_mail_body' => $this->settings['cta_link_mail_body'] ?? null, + 'cta_link_number' => $this->settings['cta_link_number'] ?? null, + 'cta_link_location' => $this->settings['cta_link_location'] ?? null, + 'cta_link_username' => $this->settings['cta_link_username'] ?? null, + 'cta_link_file' => $this->settings['cta_link_file'] ?? null, + ], + ]; + parent::render_ctas(); + } + +} diff --git a/modules/link-in-bio/module.php b/modules/link-in-bio/module.php new file mode 100644 index 00000000..0d9e1686 --- /dev/null +++ b/modules/link-in-bio/module.php @@ -0,0 +1,30 @@ + esc_html__( 'Get Healthy', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Top 10 Recipes', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Meal Prep', 'elementor-pro' ), + ], + ]; + $config['style']['cta_section']['has_corners']['default'] = 'sharp'; + $config['style']['identity_section']['has_profile_image_shape'] = false; + $config['style']['identity_section']['profile_image_max'] = 200; + + return $config; + } + + public function get_name(): string { + return 'link-in-bio-var-2'; + } + + public function get_title(): string { + return esc_html__( 'Classic', 'elementor-pro' ); + } + + public function render(): void { + $render = new Icons_Below_Cta_Render( $this ); + $render->render(); + } + + protected function add_content_tab(): void { + $this->add_identity_section(); + + $this->add_bio_section(); + + $this->add_cta_controls(); + + $this->add_icons_controls(); + } + + protected function add_style_tab(): void { + $this->add_style_identity_controls(); + + $this->add_style_bio_controls(); + + $this->add_style_cta_section(); + + $this->add_style_icons_controls(); + + $this->add_style_background_controls(); + } + + protected function add_style_identity_controls(): void { + $this->start_controls_section( + 'identity_section_style', + [ + 'label' => esc_html__( 'Identity', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'identity_section_style_cover_heading', + [ + 'label' => esc_html__( 'Cover', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'none', + ] + ); + + $this->add_identity_image_cover_control( [] ); + + $this->add_control( + 'identity_section_style_profile_heading', + [ + 'label' => esc_html__( 'Profile', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_identity_image_profile_controls( [] ); + + $this->end_controls_section(); + } +} diff --git a/modules/link-in-bio/widgets/link-in-bio-var-3.php b/modules/link-in-bio/widgets/link-in-bio-var-3.php new file mode 100644 index 00000000..55c2608c --- /dev/null +++ b/modules/link-in-bio/widgets/link-in-bio-var-3.php @@ -0,0 +1,34 @@ + [ + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + ], + ]; + $config['content']['cta_section']['cta_repeater_defaults'] = [ + [ + 'cta_link_text' => esc_html__( 'Get Healthy', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Top 10 Recipes', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Meal Prep', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Healthful Resources', 'elementor-pro' ), + ], + ]; + + return $config; + } + + public function get_name(): string { + return 'link-in-bio-var-4'; + } + + public function get_title(): string { + return esc_html__( 'Links', 'elementor-pro' ); + } + + public function render(): void { + $render = new Icons_Below_Cta_Render( $this ); + $render->render(); + } + + protected function add_content_tab(): void { + $this->add_identity_section(); + + $this->add_bio_section(); + + $this->add_cta_controls(); + + $this->add_icons_controls(); + } + + protected function add_style_tab(): void { + $this->add_style_identity_controls(); + + $this->add_style_bio_controls(); + + $this->add_style_cta_section(); + + $this->add_style_icons_controls(); + + $this->add_style_background_controls(); + } +} diff --git a/modules/link-in-bio/widgets/link-in-bio-var-5.php b/modules/link-in-bio/widgets/link-in-bio-var-5.php new file mode 100644 index 00000000..b7ade380 --- /dev/null +++ b/modules/link-in-bio/widgets/link-in-bio-var-5.php @@ -0,0 +1,49 @@ + esc_html__( 'Get Healthy', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Top Recipes', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Meal Prep', 'elementor-pro' ), + ], + [ + 'cta_link_text' => esc_html__( 'Resources', 'elementor-pro' ), + ], + ]; + $config['style']['cta_section']['has_link_type'] = false; + $config['style']['cta_section']['has_corners'] = false; + $config['style']['cta_section']['has_padding'] = false; + $config['style']['cta_section']['has_border_control']['show_border_args']['condition'] = []; + $config['style']['cta_section']['has_border_control']['border_width_args']['condition'] = []; + $config['style']['cta_section']['has_border_control']['border_color_args']['condition'] = []; + + return $config; + } + + public function get_name(): string { + return 'link-in-bio-var-5'; + } + + public function get_title(): string { + return esc_html__( 'Services', 'elementor-pro' ); + } +} diff --git a/modules/link-in-bio/widgets/link-in-bio-var-6.php b/modules/link-in-bio/widgets/link-in-bio-var-6.php new file mode 100644 index 00000000..41594d9c --- /dev/null +++ b/modules/link-in-bio/widgets/link-in-bio-var-6.php @@ -0,0 +1,55 @@ + 0, + 'images_repeater_defaults' => [ + [], + [], + [], + [], + ], + ]; + $config['style']['cta_section'] = false; + $config['style']['image_links_section'] = [ + 'has_border_control' => [ + 'prefix' => 'image_links', + 'show_border_args' => [ + 'label' => esc_html__( 'Image Border', 'elementor-pro' ), + ], + 'border_width_args' => [ + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-image-links-border-width: {{SIZE}}{{UNIT}}', + ], + ], + 'border_color_args' => [ + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-image-links-border-color: {{VALUE}}', + ], + ], + ], + ]; + + return $config; + } + + public function get_name(): string { + return 'link-in-bio-var-6'; + } + + public function get_title(): string { + return esc_html__( 'Portfolio', 'elementor-pro' ); + } +} diff --git a/modules/link-in-bio/widgets/link-in-bio-var-7.php b/modules/link-in-bio/widgets/link-in-bio-var-7.php new file mode 100644 index 00000000..131e1c0b --- /dev/null +++ b/modules/link-in-bio/widgets/link-in-bio-var-7.php @@ -0,0 +1,594 @@ + Social_Network_Provider::TELEPHONE, + 'icon_text' => 'Call', + ], + [ + 'icon_platform' => Social_Network_Provider::EMAIL, + 'icon_text' => 'Email', + ], + [ + 'icon_platform' => Social_Network_Provider::WHATSAPP, + 'icon_text' => 'WhatsApp', + ], + [ + 'icon_platform' => Social_Network_Provider::INSTAGRAM, + 'icon_text' => 'Instagram', + ], + [ + 'icon_platform' => Social_Network_Provider::LINKEDIN, + 'icon_text' => 'LinkedIn', + ], + [ + 'icon_platform' => Social_Network_Provider::BEHANCE, + 'icon_text' => 'Behance', + ], + ]; + } + + public function get_description_position() { + return 'bottom'; + } + + public function get_name(): string { + return 'link-in-bio-var-7'; + } + + public function get_title(): string { + return esc_html__( 'Business Card', 'elementor-pro' ); + } + + public function render(): void { + $render_strategy = new Single_Button_Cta_Render( $this ); + + $render_strategy->render(); + } + + protected function register_controls(): void { + parent::register_controls(); + + $this->start_injection( + [ + 'type' => 'section', + 'at' => 'start', + 'of' => 'icons_section', + ] + ); + + $this->add_icons_per_row_control(); + + $this->end_injection(); + } + + protected function add_cta_controls() { + $this->start_controls_section( + 'cta_section', + [ + 'label' => esc_html__( 'CTA Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'cta_section_button_text', + [ + 'label' => esc_html__( 'Button Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Download Resume', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'cta_link_type', + [ + 'label' => esc_html__( 'Link Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'groups' => [ + + [ + 'label' => '', + 'options' => Social_Network_Provider::get_social_networks_text( + [ + Social_Network_Provider::FILE_DOWNLOAD, + Social_Network_Provider::URL, + ] + ), + ], + [ + 'label' => ' --', + 'options' => Social_Network_Provider::get_social_networks_text( + [ + Social_Network_Provider::EMAIL, + Social_Network_Provider::TELEPHONE, + Social_Network_Provider::MESSENGER, + Social_Network_Provider::WAZE, + Social_Network_Provider::WHATSAPP, + ] + ), + ], + ], + 'default' => Social_Network_Provider::FILE_DOWNLOAD, + ], + ); + + $this->add_control( + 'cta_section_alert', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Upload your card in .vcf format', 'elementor-pro' ), + 'condition' => [ + 'cta_link_type' => Social_Network_Provider::VCF, + ], + ] + ); + + $this->add_control( + 'cta_link_file', + [ + 'label' => esc_html__( 'Choose File', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'label_block' => true, + 'media_type' => [ 'application/pdf' ], + 'condition' => [ + 'cta_link_type' => Social_Network_Provider::FILE_DOWNLOAD, + ], + 'ai' => [ + 'active' => false, + ], + ], + ); + + $this->add_control( + 'cta_link_url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'autocomplete' => true, + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::URL, + ], + ], + 'placeholder' => esc_html__( 'Enter your link', 'elementor-pro' ), + 'default' => [ + 'is_external' => true, + ], + ], + ); + + $this->add_control( + 'cta_link_mail', + [ + 'label' => esc_html__( 'Email', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::EMAIL, + ], + ], + 'placeholder' => esc_html__( 'Enter your email', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'cta_link_mail_subject', + [ + 'label' => esc_html__( 'Subject', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::EMAIL, + ], + ], + 'placeholder' => esc_html__( 'Subject', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'cta_link_mail_body', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::EMAIL, + ], + ], + 'placeholder' => esc_html__( 'Message', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'cta_link_number', + [ + 'label' => esc_html__( 'Number', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::TELEPHONE, + Social_Network_Provider::WHATSAPP, + ], + ], + 'placeholder' => esc_html__( 'Enter your number', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'cta_link_location', + [ + 'label' => esc_html__( 'Location', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'is_external' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::WAZE, + ], + ], + 'placeholder' => esc_html__( 'Paste Waze link', 'elementor-pro' ), + ], + ); + + $this->add_control( + 'cta_link_username', + [ + 'label' => esc_html__( 'Username', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'cta_link_type' => [ + Social_Network_Provider::MESSENGER, + ], + ], + 'placeholder' => esc_html__( 'Enter your username', 'elementor-pro' ), + ], + ); + + $this->end_controls_section(); + } + + protected function add_style_identity_controls(): void { + $this->start_controls_section( + 'identity_section_style', + [ + 'label' => esc_html__( 'Identity', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'identity_section_style_cover_heading', + [ + 'label' => esc_html__( 'Cover', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'none', + ] + ); + + $this->add_identity_image_cover_control( [] ); + + $this->add_control( + 'identity_section_style_profile_heading', + [ + 'label' => esc_html__( 'Profile', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_identity_image_profile_controls( [] ); + + $this->add_control( + 'identity_section_style_divider_heading', + [ + 'label' => esc_html__( 'Shape Divider', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $shapes_options = [ + '' => esc_html__( 'None', 'elementor-pro' ), + ]; + + foreach ( Shapes::get_shapes() as $shape_name => $shape_props ) { + $shapes_options[ $shape_name ] = $shape_props['title']; + } + + $shape_divider_side = 'bottom'; + $shape_divider_base_control_key = "identity_section_style_cover_divider_$shape_divider_side"; + + $this->add_control( + $shape_divider_base_control_key, + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $shapes_options, + ] + ); + + $this->add_control( + $shape_divider_base_control_key . '_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + "$shape_divider_base_control_key!" => '', + ], + 'selectors' => [ + "{{WRAPPER}} .e-link-in-bio__identity-image .elementor-shape-$shape_divider_side .elementor-shape-fill" => 'fill: {{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + $shape_divider_base_control_key . '_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ '%', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 100, + 'max' => 300, + 'step' => 1, + ], + 'vw' => [ + 'min' => 100, + 'max' => 300, + 'step' => 1, + ], + ], + 'condition' => [ + "$shape_divider_base_control_key" => array_keys( Shapes::filter_shapes( 'height_only', Shapes::FILTER_EXCLUDE ) ), + ], + 'selectors' => [ + "{{WRAPPER}} .e-link-in-bio__identity-image .elementor-shape-$shape_divider_side svg" => 'width: calc({{SIZE}}{{UNIT}} + 1.3px)', + ], + ] + ); + + $this->add_responsive_control( + $shape_divider_base_control_key . '_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 500, + ], + 'em' => [ + 'max' => 50, + ], + 'rem' => [ + 'max' => 50, + ], + ], + 'condition' => [ + "$shape_divider_base_control_key!" => '', + ], + 'selectors' => [ + "{{WRAPPER}} .e-link-in-bio__identity-image .elementor-shape-$shape_divider_side svg" => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + $shape_divider_base_control_key . '_negative', + [ + 'label' => esc_html__( 'Invert', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + "$shape_divider_base_control_key" => array_keys( Shapes::filter_shapes( 'has_negative' ) ), + ], + ] + ); + + $this->end_controls_section(); + } + + protected function add_style_bio_controls(): void { + parent::add_style_bio_controls(); + + $this->start_injection( + [ + 'type' => 'control', + 'at' => 'before', + 'of' => 'bio_description_heading', + ] + ); + + $this->add_control( + 'bio_about_heading', + [ + 'label' => esc_html__( 'About Heading', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'bio_about_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-about-heading-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'bio_about_typography', + 'selector' => '{{WRAPPER}} .e-link-in-bio__about-heading', + ] + ); + + $this->end_injection(); + } + + public function add_style_icons_controls(): void { + parent::add_style_icons_controls(); + + $this->start_injection( + [ + 'type' => 'control', + 'at' => 'after', + 'of' => 'icons_color', + ] + ); + + $this->add_control( + 'icons_color_background', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-icon-background-color: {{VALUE}}', + ], + ] + ); + + $this->add_borders_control( + 'icons_border', + [ + 'selectors' => [], + ], + [ + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-icon-border-width: {{SIZE}}{{UNIT}}', + ], + ], + [ + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-icon-border-color: {{VALUE}}', + ], + ] + ); + + $this->end_injection(); + + $this->start_injection( + [ + 'type' => 'control', + 'at' => 'after', + 'of' => 'icons_size', + ] + ); + + $this->add_control( + 'icons_color_text', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-link-in-bio' => '--e-link-in-bio-icon-text-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'icons_typography', + 'selector' => '{{WRAPPER}} .e-link-in-bio__icon-label', + ] + ); + + $this->end_injection(); + } + +} diff --git a/modules/loop-builder/assets/images/loop-item.svg b/modules/loop-builder/assets/images/loop-item.svg new file mode 100644 index 00000000..cf6d305b --- /dev/null +++ b/modules/loop-builder/assets/images/loop-item.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/loop-builder/documents/loop.php b/modules/loop-builder/documents/loop.php new file mode 100644 index 00000000..2e2abcd0 --- /dev/null +++ b/modules/loop-builder/documents/loop.php @@ -0,0 +1,547 @@ + esc_html__( 'What is a loop?', 'elementor-pro' ), + 'content' => esc_html__( 'A Loop is a layout you can customize to display recurring dynamic content - like listings, posts, portfolios, products, , etc.', 'elementor-pro' ), + 'tip' => esc_html__( 'Start by creating a master item. All the other instances in the grid will match this design. Then go back to the widget in the editor panel and assign both a template and a source of content. Your grid should populate automatically.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-loop', + 'video_url' => 'https://www.youtube.com/embed/zMvY9XaE1YY', + ]; + } + + protected static function get_site_editor_thumbnail_url() { + return ELEMENTOR_PRO_MODULES_URL . 'loop-builder/assets/images/loop-item.svg'; + } + + public static function get_properties() { + $properties = parent::get_properties(); + + $properties['support_conditions'] = false; + + return $properties; + } + + public function save( $data ) { + if ( isset( $data['settings']['source'] ) ) { + update_post_meta( $this->get_main_id(), '_elementor_source', $data['settings']['source'] ); + } + + parent::save( $data ); + } + + private function get_data_id() { + if ( Taxonomy_Loop_Provider::is_loop_taxonomy() ) { + return $this->get_data_id_from_taxonomy_loop_query(); + } + + return get_the_ID(); + } + + public function get_container_attributes() { + $attributes = Document::get_container_attributes(); + $post_id = $this->get_data_id(); + + $attributes['class'] .= ' e-loop-item'; + $attributes['class'] .= ' e-loop-item-' . $post_id; + $attributes['class'] .= ' ' . esc_attr( implode( ' ', get_post_class( [], $post_id ) ) ); + + $attributes['data-custom-edit-handle'] = true; + + return $attributes; + } + + public function get_initial_config() { + $config = parent::get_initial_config(); + $loop_builder_module = new LoopBuilderModule(); + + if ( 'post' === $loop_builder_module->get_source_type_from_post_meta( $this->get_main_id() ) ) { + foreach ( static::RECOMMENDED_POSTS_WIDGET_NAMES as $recommended_posts_widget_name ) { + $config['panel']['widgets_settings'][ $recommended_posts_widget_name ] = [ + 'categories' => [ 'recommended' ], + 'show_in_panel' => true, + ]; + } + } + + $config['panel']['widgets_settings']['container'] = [ + 'categories' => [ 'layout' ], + ]; + + foreach ( static::WIDGETS_TO_HIDE as $widget_to_hide ) { + $config['panel']['widgets_settings'][ $widget_to_hide ] = [ + 'show_in_panel' => false, + ]; + } + + $config['container_attributes'] = $this->get_container_attributes(); + + return $config; + } + + public static function get_site_editor_config() { + $config = parent::get_site_editor_config(); + + $config['show_instances'] = false; + + return $config; + } + + public function get_location_label() { + return ''; + } + + public function get_css_wrapper_selector() { + return '.e-loop-item-' . $this->get_main_id(); + } + + public static function get_preview_as_options() { + $post_types = Utils::get_public_post_types(); + + $post_types_options = []; + + foreach ( $post_types as $post_type => $label ) { + $post_types_options[ self::SINGLE_PREFIX . $post_type ] = get_post_type_object( $post_type )->labels->singular_name; + } + + return [ + 'single' => [ + 'label' => esc_html__( 'Single', 'elementor-pro' ), + 'options' => $post_types_options, + ], + ]; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['type'] = self::DOCUMENT_TYPE; + $config['default_route'] = 'templates/loop-items'; + + return $config; + } + + /** + * Get Edit Url + * + * Disable the Library modal for non-container (section) users. + * + * @return string + */ + public function get_edit_url() { + $url = parent::get_edit_url(); + + if ( ! Plugin::elementor()->experiments->is_feature_active( 'container' ) ) { + $url = str_replace( '#library', '', $url ); + } + + return $url; + } + + protected static function get_editor_panel_categories() { + $new_categories = [ + 'recommended' => [ + 'title' => esc_html__( 'Recommended', 'elementor-pro' ), + ], + 'layout' => [ + 'title' => esc_html__( 'Layout', 'elementor-pro' ), + 'hideIfEmpty' => true, + ], + ]; + return static::insert_categories_after_favorites( $new_categories ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->remove_control( 'content_wrapper_html_tag' ); + + $this->update_preview_control(); + + $this->inject_width_control(); + + $this->add_query_section(); + + Plugin::elementor()->controls_manager->add_custom_css_controls( $this ); + + } + + /** + * Get Wrapper Tags + * + * We remove the `content_wrapper_html_tag` control in this document and default to using a `div`. + * The setting no longer exists when printing the document element, so we need to override this method so that + * the extended document class defaults to using a `div` when printing the element. + * + * @since 3.8.0 + * + * @return false + */ + public function get_wrapper_tags() { + return false; + } + + /** + * Print elements with wrapper. + * + * Overwrite method from theme-document.php to render some custom markup if a variable + * $elements_data['empty_loop_template'] is set. This variable is set via a filter hook + * 'elementor/frontend/builder_content_data' in the loop builder module. + * + * @since 3.8.0 + * + * @param $elements_data + * + * @return void + */ + public function print_elements_with_wrapper( $elements_data = null ) { + if ( isset( $elements_data['empty_loop_template'] ) ) { + $this->print_empty_loop_template_markup( $elements_data['empty_loop_template_id'] ); + } else { + parent::print_elements_with_wrapper( $elements_data ); + } + } + + private function enqueue_loop_css() { + if ( $this->is_autosave() ) { + $css_file = Loop_Preview::create( $this->post->ID ); + } else { + $css_file = Loop_CSS::create( $this->post->ID ); + } + + $css_file->print_all_css( $this->post->ID ); + } + + /** + * Get content. + * + * Override the parent method to retrieve the content with CSS in the Editor. + * + * @since 3.8.0 + */ + public function get_content( $with_css = false ) { + $edit_mode = Plugin::elementor()->editor->is_edit_mode(); + + $document = Plugin::elementor()->documents->get_current(); + + $should_switch_document = $document && $document::get_type() !== self::DOCUMENT_TYPE; + + if ( $should_switch_document ) { + Plugin::elementor()->documents->switch_to_document( $this ); + } + + add_filter( 'elementor/frontend/builder_content/before_print_css', [ $this, 'prevent_inline_css_printing' ] ); + + $this->enqueue_loop_css(); + + Plugin::elementor()->editor->set_edit_mode( false ); + + $content = parent::get_content(); + + remove_filter( 'elementor/frontend/builder_content/before_print_css', [ $this, 'prevent_inline_css_printing' ] ); + + Plugin::elementor()->editor->set_edit_mode( $edit_mode ); + + if ( $should_switch_document ) { + Plugin::elementor()->documents->restore_document(); + } + + return $content; + } + + /** + * Runs on the 'elementor/frontend/builder_content/before_print_css' hook. + * + * @return false + */ + public function prevent_inline_css_printing() { + return false; + } + + /** + * Print empty loop template markup. + * + * This function is used to render markup in the editor when a loop template is empty/blank. + * Currently, nothing will be rendered in the editor if the template is empty. + * This markup is needed in the DOM for us to be able to switch to this document in place. + * + * @since 3.8.0 + * + * @param int $post_id The post ID of the document. + * + * @return void + */ + protected function print_empty_loop_template_markup( $post_id ) { + ?> +
      +
      +
      + start_controls_section( + '_section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_SETTINGS, + ] + ); + + $loop_builder_module = new LoopBuilderModule(); + $source_type = $loop_builder_module->get_source_type_from_post_meta( $this->get_main_id() ); + + $this->add_control( + 'source', + [ + 'label' => esc_html__( 'Source Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'post' => esc_html__( 'Posts', 'elementor-pro' ), + ], + 'default' => $source_type, + 'prefix_class' => 'elementor-view-', + ] + ); + + do_action( 'elementor-pro/modules/loop-builder/documents/loop/query_settings', $this ); + + $this->add_control( + 'apply_query_source', + [ + 'type' => Controls_Manager::BUTTON, + 'label' => esc_html__( 'Apply', 'elementor-pro' ), + 'label_block' => true, + 'show_label' => false, + 'text' => esc_html__( 'Apply', 'elementor-pro' ), + 'event' => 'elementorLoopBuilder:ApplySourceChange', + ] + ); + + $this->add_control( + 'query_source_description', + [ + 'raw' => esc_html__( 'This affects the types of widgets and templates you can use for your master item.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->end_controls_section(); + } + + /** + * @return void + */ + protected function inject_width_control() { + $this->start_injection([ + 'type' => 'section', + 'at' => 'start', + 'of' => 'preview_settings', + ]); + + $this->add_responsive_control( + 'preview_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 200, + 'max' => 1140, + ], + 'em' => [ + 'min' => 20, + 'max' => 100, + ], + 'rem' => [ + 'min' => 20, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--preview-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_injection(); + } + + /** + * @return void + */ + protected function update_preview_control() { + $loop_builder_module = new LoopBuilderModule(); + $source_type = $loop_builder_module->get_source_type_from_post_meta( $this->get_main_id() ); + + if ( Taxonomy_Loop_Provider::is_source_type_taxonomy( $source_type ) ) { + $this->update_taxonomy_settings_controls( $source_type ); + } else { + $this->update_post_settings_controls( $source_type ); + } + } + + /** + * @param array $new_categories + * @return array + */ + private static function insert_categories_after_favorites( array $new_categories ) { + $existing_categories = parent::get_editor_panel_categories(); + $category_keys = array_keys( $existing_categories ); + $index = array_search( 'favorites', $category_keys, true ); + return array_splice( $existing_categories, 0, $index + 1 ) + $new_categories + array_splice( $existing_categories, $index + 1 ); + } + + private function update_post_settings_controls( $source_type ) { + $this->update_control( + self::PREVIEW_TYPE, + [ + 'default' => self::SINGLE_PREFIX . $source_type, + 'label' => esc_html__( 'Preview a specific post or item', 'elementor-pro' ), + ] + ); + + $latest_posts = get_posts( [ + 'posts_per_page' => 1, + 'post_type' => $source_type, + ] ); + + if ( ! empty( $latest_posts ) ) { + $this->update_control( + self::PREVIEW_ID, + [ + 'default' => $latest_posts[0]->ID, + ] + ); + } + } + + private function update_taxonomy_settings_controls( $source_type ) { + $this->update_taxonomy_preview_type_control( $source_type ); + $this->update_taxonomy_preview_id_control( $source_type ); + } + + private function update_taxonomy_preview_type_control( $source_type ) { + $post_type_slug = $this->extract_taxonomy_type( $source_type ); + $allowed_post_types = Taxonomy_Loop_Provider::get_supported_cpts( $post_type_slug ); + $options_prefix = $source_type . '/'; + $taxonomy_options = $this->get_taxonomy_options( $allowed_post_types, $options_prefix ); + + $this->update_control( + self::PREVIEW_TYPE, + [ + 'default' => Taxonomy_Loop_Provider::get_default_source_type( $source_type, $options_prefix ), + 'groups' => [ + 'archive' => [ + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + 'options' => $taxonomy_options, + ], + ], + 'label' => esc_html__( 'Preview a specific post or item', 'elementor-pro' ), + ] + ); + } + + private function update_taxonomy_preview_id_control( $source_type ) { + $term_id = $this->get_settings_for_display( self::PREVIEW_ID ) ?? null; + + $filter_args = [ + 'taxonomy' => Taxonomy_Loop_Provider::get_default_source_type( $source_type ), + 'show_empty_items' => 'yes', + 'show_child_taxonomy' => 'yes', + ]; + + if ( $term_id ) { + $filter_args['term_taxonomy_id'] = $term_id; + } + + $latest_terms = $this->get_filtered_taxonomies( $filter_args, [] ); + + if ( ! empty( $latest_terms ) ) { + $term = array_values( $latest_terms )[0]; + $this->update_control( + self::PREVIEW_ID, + [ + 'default' => $term->term_id, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_TAX, + ], + ], + ); + } + } + + private function extract_taxonomy_type( $source_type ) { + return str_replace( '_taxonomy', '', $source_type ); + } +} diff --git a/modules/loop-builder/files/css/loop-css-trait.php b/modules/loop-builder/files/css/loop-css-trait.php new file mode 100644 index 00000000..72ce9b1c --- /dev/null +++ b/modules/loop-builder/files/css/loop-css-trait.php @@ -0,0 +1,175 @@ +editor->is_edit_mode() ) { + return true; + } + + return 'internal' !== get_option( 'elementor_css_print_method' ); + } + + /** + * @param array $fonts + * @return void + */ + private function enqueue_fonts( array $fonts ) { + foreach ( $fonts as $font ) { + Plugin::elementor()->frontend->enqueue_font( $font ); + } + } + + /** + * @param $icon_fonts + * @return void + */ + private function enqueue_icon_fonts( $icon_fonts ) { + $icons_types = Icons_Manager::get_icon_manager_tabs(); + + foreach ( $icon_fonts as $icon_font ) { + if ( ! isset( $icons_types[ $icon_font ] ) ) { + continue; + } + Plugin::elementor()->frontend->enqueue_font( $icon_font ); + } + } + + private function enqueue_font_links() { + $meta = $this->get_meta(); + + if ( Base::CSS_STATUS_EMPTY === $meta['status'] ) { + return; + } + + // First time after clear cache etc. + if ( '' === $meta['status'] || $this->is_update_required() ) { + $this->update(); + + $meta = $this->get_meta(); + } + + // Handle fonts. + if ( ! empty( $meta['fonts'] ) ) { + $this->enqueue_fonts( $meta['fonts'] ); + } + + if ( ! empty( $meta['icons'] ) ) { + $this->enqueue_icon_fonts( $meta['icons'] ); + } + } + + /** + * @param array $early_access_google_fonts + * @return void + */ + private function print_early_access_google_font_link_tags( array $early_access_google_fonts ) { + $early_access_google_fonts_urls = Plugin::elementor()->frontend->get_early_access_google_font_urls( $early_access_google_fonts ); + + foreach ( $early_access_google_fonts_urls as $font_url ) { + echo ''; + } + } + + private function print_fonts_links() { + $google_fonts = Plugin::elementor()->frontend->get_list_of_google_fonts_by_type(); + + if ( ! empty( $google_fonts['google'] ) ) { + $stable_google_fonts_url = Plugin::elementor()->frontend->get_stable_google_fonts_url( $google_fonts['google'] ); + + echo ''; + } + + if ( ! empty( $google_fonts['early'] ) ) { + $this->print_early_access_google_font_link_tags( $google_fonts['early'] ); + } + } + + public function enqueue_and_print_font_links() { + $this->enqueue_font_links(); + + $this->print_fonts_links(); + } + + public function print_all_css( int $post_id ) { + // Avoid re-print CSS + if ( isset( self::$printed_with_css[ $this->get_file_handle_id() ] ) ) { + return; + } + + $template_custom_css = $post_id > 0 ? $this->get_custom_css( $post_id ) : ''; + + echo ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + if ( Plugin::elementor()->editor->is_edit_mode() && method_exists( Plugin::elementor()->frontend, 'get_list_of_google_fonts_by_type' ) ) { + $this->enqueue_and_print_font_links(); + } + + // Avoid re-print CSS + self::$printed_with_css[ $this->get_file_handle_id() ] = true; + } + + private function get_custom_css( $post_id ) { + $loop_doc = Plugin::elementor()->documents->get( $post_id ); + return $loop_doc->get_settings( 'custom_css' ); + } + + public function print_css() { + $this->print_all_css( 0 ); + } + + public function print_dynamic_css( $post_id, $post_id_for_data ) { + $document = Plugin::elementor()->documents->get_doc_for_frontend( $post_id_for_data ); + + if ( ! $document ) { + return; + } + + Plugin::elementor()->documents->switch_to_document( $document ); + + $css_file = Loop_Dynamic_CSS::create( $post_id, $post_id_for_data ); + $post_css = $css_file->get_content(); + + if ( empty( $post_css ) ) { + return; + } + + $css = ''; + $css = str_replace( '.elementor-' . $post_id, '.e-loop-item-' . $post_id, $post_css ); + $css = sprintf( '', 'loop-dynamic-' . $post_id_for_data, $css ); + + echo $css; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + Plugin::elementor()->documents->restore_document(); + } +} diff --git a/modules/loop-builder/files/css/loop-dynamic-css.php b/modules/loop-builder/files/css/loop-dynamic-css.php new file mode 100644 index 00000000..70eb2aa8 --- /dev/null +++ b/modules/loop-builder/files/css/loop-dynamic-css.php @@ -0,0 +1,23 @@ +post_id_for_data = $post_id_for_data; + + $post_css_file = Post::create( $post_id_for_data ); + + parent::__construct( $post_id, $post_css_file ); + } + + public function get_post_id_for_data() { + return $this->post_id_for_data; + } +} diff --git a/modules/loop-builder/files/css/loop-preview.php b/modules/loop-builder/files/css/loop-preview.php new file mode 100644 index 00000000..3ed32d43 --- /dev/null +++ b/modules/loop-builder/files/css/loop-preview.php @@ -0,0 +1,27 @@ +post_id; + } + + /** + * Loop CSS file constructor. + * + * Initializing the CSS file of the loop widget. Set the post ID and initiate the stylesheet. + * + * @since 1.2.0 + * @access public + * + * @param int $post_id Post ID. + */ + public function __construct( $loop_template_id ) { + $this->post_id = $loop_template_id; + + parent::__construct( $loop_template_id ); + } +} diff --git a/modules/loop-builder/module.php b/modules/loop-builder/module.php new file mode 100644 index 00000000..a4e8748d --- /dev/null +++ b/modules/loop-builder/module.php @@ -0,0 +1,344 @@ +get_css_assets_url( 'widget-loop-common', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + + wp_register_style( + 'widget-loop-carousel', + $this->get_css_assets_url( 'widget-loop-carousel', null, true, true ), + [ 'elementor-frontend', 'e-swiper', 'widget-loop-common' ], + ELEMENTOR_PRO_VERSION + ); + + $direction_suffix = is_rtl() ? '-rtl' : ''; + $has_custom_breakpoints = Plugin::elementor()->breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-loop-grid', + Plugin::get_frontend_file_url( "widget-loop-grid{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend', 'widget-loop-common' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } + + public function __construct() { + parent::__construct(); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + + add_action( 'elementor/documents/register', function ( $documents_manager ) { + $this->register_documents( $documents_manager ); + }, 11 /* After WC documents */ ); + + add_filter( 'elementor/finder/categories', [ $this, 'add_finder_items' ] ); + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'add_posts_type_to_template_popup' ], 10 ); + + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'add_taxonomies_type_to_template_popup' ], 12 ); + add_action( 'elementor-pro/modules/loop-builder/documents/loop/query_settings', [ $this, 'add_taxonomies_type_to_loop_settings_query' ], 12 ); + + add_filter( 'elementor/frontend/builder_content_data', [ $this, 'filter_content_data' ], 10, 2 ); + + add_action( 'manage_' . Source_Local::CPT . '_posts_columns', function ( $columns ) { + return $this->manage_posts_columns( $columns ); + } ); + + add_action('elementor/editor/init', function () { + Plugin::elementor()->common->add_template( __DIR__ . '/views/cta-template.php' ); + }); + + if ( $this->is_loop_theme_builder() ) { + add_filter( 'template_include', [ $this, 'filter_template_to_canvas_view' ], 999 ); + add_filter( 'body_class', [ $this, 'filter_body_class' ] ); + } + + // Prevent enqueue default dynamic CSS for loop item templates + add_filter( 'elementor/css-file/dynamic/should_enqueue', + function ( $should_enqueue, $post_id ) { + if ( $this->is_loop_item_document_type_meta_key( $post_id ) ) { + $should_enqueue = false; + } + return $should_enqueue; + }, + 10, 2 ); + + // Prevent enqueue default Post CSS for loop item templates + add_action( + 'elementor/css-file/post/enqueue', + function( $css_file ) { + $post_id = $css_file->get_post_id(); + $file_handle = 'elementor-post-' . $post_id; + + if ( $this->is_loop_item_document_type_meta_key( $post_id ) && wp_style_is( $file_handle, 'enqueued' ) ) { + wp_dequeue_style( $file_handle ); + } + } + ); + + add_filter( 'elementor/editor/localize_settings', function ( $config ) { + $config['admin_url'] = admin_url(); + return $config; + } ); + + foreach ( static::LOOP_WIDGETS as $widget_type ) { + add_action( 'elementor/widget/' . $widget_type . '/skins_init', function ( Widget_Base $widget ) { + $widget->add_skin( new Skin_Loop_Post_Taxonomy( $widget ) ); + }, 12 ); + } + } + + public function filter_template_to_canvas_view() { + return ELEMENTOR_PATH . 'modules/page-templates/templates/canvas.php'; + } + + private function get_preview_loop_item_id() { + $post_id = false; + + // Editor preview. + $post_id = Utils::_unstable_get_super_global_value( $_GET, 'elementor-preview' ); + + if ( ! $post_id ) { + $library_type = Utils::_unstable_get_super_global_value( $_GET, 'elementor_library' ); + + if ( 'elementor-' . self::TEMPLATE_LIBRARY_TYPE_SLUG === $library_type ) { + // Frontend Loop Item template preview. + $post_id = get_the_ID(); + } + } + + return $post_id; + } + + public function filter_body_class( $classes ) { + $classes[] = 'e-loop-template-canvas'; + + $post_id = $this->get_preview_loop_item_id(); + + if ( $post_id && 'product' === $this->get_source_type_from_post_meta( $post_id ) ) { + $classes[] = 'woocommerce'; + } + + return $classes; + } + + /** + * Filter content data. + * + * Determine whether we are in the Editor and are trying to Edit an empty loop template. + * + * If this is the case, we add some elements to the $data array in order for frontend.php + * to not 'return' an empty string and reach the print_elements_with_wrapper() function. + * + * We then override print_elements_with_wrapper() in the loop document using the variables + * we added here. + * + * @since 3.8.0 + * + * @param array $data + * @param int $post_id + * + * @return mixed + */ + public function filter_content_data( $data, $post_id ) { + if ( + empty( $data ) + && LoopDocument::get_type() === get_post_meta( $post_id, Document::TYPE_META_KEY, true ) + && wp_doing_ajax() + ) { + $data['empty_loop_template'] = true; + $data['empty_loop_template_id'] = $post_id; + } + + return $data; + } + + public function add_finder_items( array $categories ) { + $categories['create']['items']['loop-template'] = [ + 'title' => esc_html__( 'Add New Loop Template', 'elementor-pro' ), + 'icon' => 'plus-circle-o', + 'url' => $this->get_admin_templates_url() . '#add_new', + 'keywords' => [ 'template', 'theme', 'new', 'create', 'loop', 'dynamic', 'listing', 'archive', 'repeater' ], + ]; + + return $categories; + } + + public function add_posts_type_to_template_popup( $form ) { + if ( empty( $form ) ) { + return; + } + $form->add_control( '_elementor_source', [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Choose source type', 'elementor-pro' ), + 'options' => $this->get_post_type_options(), + 'section' => 'main', + 'required' => true, + 'conditions' => [ + 'template-type' => self::TEMPLATE_LIBRARY_TYPE_SLUG, + ], + ] ); + } + + public function get_source_type_from_post_meta( $post_id ) { + $source_type = get_post_meta( intval( $post_id ), '_elementor_source', true ); + return empty( $source_type ) ? 'post' : $source_type; + } + + private function is_editing_existing_loop_item() { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required. + $elementor_library = Utils::_unstable_get_super_global_value( $_GET, 'elementor_library' ) ?? ''; + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required. + $post_id = Utils::_unstable_get_super_global_value( $_GET, 'elementor-preview' ); + + return ! empty( $elementor_library ) && $this->is_loop_item_document_type_meta_key( $post_id ); + } + + private function is_creating_new_loop_item() { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required. + $post_type = Utils::_unstable_get_super_global_value( $_GET, 'post_type' ); + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required. + $post_id = Utils::_unstable_get_super_global_value( $_GET, 'p' ); + return 'elementor_library' === $post_type && $this->is_loop_item_document_type_meta_key( $post_id ); + } + + private function is_loop_item_document_type_meta_key( $post_id ) { + return static::TEMPLATE_LIBRARY_TYPE_SLUG === get_post_meta( $post_id, Document::TYPE_META_KEY, true ); + } + + private function is_loop_theme_builder() { + return $this->is_editing_existing_loop_item() || $this->is_creating_new_loop_item(); + } + + /** + * @param Documents_Manager $documents_manager + */ + private function register_documents( $documents_manager ) { + $documents_manager->register_document_type( Documents\Loop::get_type(), Documents\Loop::get_class_full_name() ); + } + + private function get_admin_templates_url( $relative = false ) { + $base_url = Source_Local::ADMIN_MENU_SLUG; + if ( ! $relative ) { + $base_url = admin_url( $base_url ); + } + + return add_query_arg( + [ + 'tabs_group' => 'theme', + 'elementor_library_type' => self::TEMPLATE_LIBRARY_TYPE_SLUG, + ], + $base_url + ); + } + + private function manage_posts_columns( $columns ) { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required. + $taxonomy_type_slug = Utils::_unstable_get_super_global_value( $_REQUEST, Source_Local::TAXONOMY_TYPE_SLUG ); + if ( self::TEMPLATE_LIBRARY_TYPE_SLUG === $taxonomy_type_slug ) { + unset( $columns['instances'] ); + } + + return $columns; + } + + private function get_post_type_options() { + $options = [ self::LOOP_POST_SKIN_ID => esc_html__( 'Posts', 'elementor-pro' ) ]; + + return $options; + } + + public function add_taxonomies_type_to_template_popup( $form ) { + $this->add_taxonomies_to_options( $form, '_elementor_source' ); + } + + public function add_taxonomies_type_to_loop_settings_query( $form ) { + $this->add_taxonomies_to_options( $form, 'source' ); + } + + protected function add_taxonomies_to_options( $form, $control_name ) { + $controls = $form->get_controls( $control_name ); + + if ( ! $controls || ! isset( $controls['options'] ) ) { + return; + } + + $options = $controls['options']; + $options[ self::LOOP_POST_TAXONOMY_SKIN_ID ] = esc_html__( 'Post Taxonomy', 'elementor-pro' ); + + $form->update_control($control_name, [ + 'options' => $options, + ] ); + } +} diff --git a/modules/loop-builder/providers/taxonomy-loop-provider.php b/modules/loop-builder/providers/taxonomy-loop-provider.php new file mode 100644 index 00000000..554da272 --- /dev/null +++ b/modules/loop-builder/providers/taxonomy-loop-provider.php @@ -0,0 +1,388 @@ +skin_id = $skin_id; + $this->default_source_type = $default_source_type; + } + + public function get_query_settings( array $display_settings ): array { + $taxonomy_type = $display_settings[ $this->get_query_property_name( self::POST_TYPE ) ] ?? self::POST_CATEGORY_TAXONOMY; + $term_taxonomy_id = $display_settings[ $this->get_property_name( self::QUERY_ID ) ]; + $depth = (int) $display_settings[ $this->get_property_name( self::QUERY_DEPTH ) ]; + $hierarchical = $display_settings[ $this->get_property_name( self::HIERARCHICAL ) ]; + + $settings = [ + 'taxonomy' => empty( $taxonomy_type ) ? $this->default_source_type : $taxonomy_type, + 'show_empty_items' => 'yes' === $display_settings[ $this->get_property_name( self::HIDE_EMPTY ) ] ? 'no' : 'yes', + 'include' => $display_settings[ $this->get_property_name( self::INCLUDE ) ], + 'exclude' => $display_settings[ $this->get_property_name( self::EXCLUDE ) ], + 'term_taxonomy_id' => strlen( $term_taxonomy_id ) ? $term_taxonomy_id : null, + 'child_of' => $display_settings[ $this->get_property_name( self::PARENT ) ], + 'offset' => $display_settings[ $this->get_property_name( self::OFFSET ) ], + 'number' => $display_settings['posts_per_page'], + 'orderby' => $display_settings[ $this->get_property_name( self::ORDER_BY ) ], + 'order' => $display_settings[ $this->get_property_name( self::ORDER ) ], + 'avoid_reset_parent' => true, + 'show_child_taxonomy' => 'no', + ]; + + if ( $depth && 'yes' === $hierarchical ) { + $settings['hierarchical'] = 'yes'; + $settings['child_taxonomy_depth'] = $depth - 1; + $settings['show_child_taxonomy'] = 'yes'; + } + + return $settings; + } + + public function get_control_args( string $key, bool $is_prefixed ): array { + $tabs_wrapper = $this->get_query_property_name( self::TABS_WRAPPER ); + $include_tab = $this->get_query_property_name( self::INCLUDE_TAB ); + $exclude_tab = $this->get_query_property_name( self::EXCLUDE_TAB ); + $include_exclude_conditions = $this->get_include_exclude_conditions( $is_prefixed ); + $filter_related_conditions = $this->get_depth_related_filter_conditions( $is_prefixed, false ); + + $post_type_key = $is_prefixed ? $this->get_query_property_name( self::POST_TYPE ) : self::POST_TYPE; + $filter_by_key = $is_prefixed ? $this->get_query_property_name( self::FILTER_BY ) : self::FILTER_BY; + $hierarchical_key = $is_prefixed ? $this->get_property_name( self::HIERARCHICAL ) : self::HIERARCHICAL; + + $filter_by_parent_term = Utils::format_control_condition( $filter_by_key, '===', self::PARENT ); + $is_hierarchical_term = Utils::format_control_condition( $hierarchical_key, '===', 'yes' ); + + $control_options = [ + self::FILTER_BY => [ + 'label' => esc_html__( 'Filter By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'show_all', + 'options' => [ + self::SHOW_ALL => esc_html__( 'Show All', 'elementor-pro' ), + self::MANUAL_SELECTION => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + 'conditions' => $filter_related_conditions, + ], + self::PARENT => [ + 'label' => esc_html__( 'Parent', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ 1, 2, 3, 4 ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => $this->get_related_tags_conditions( $post_type_key, '!==', [ $filter_by_parent_term ] ), + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + self::INCLUDE_TAB => [ + 'type' => Controls_Manager::TAB, + 'label' => esc_html__( 'Include', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'conditions' => $include_exclude_conditions, + ], + self::EXCLUDE_TAB => [ + 'type' => Controls_Manager::TAB, + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'conditions' => $include_exclude_conditions, + ], + self::INCLUDE => [ + 'label' => esc_html__( 'Include By', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_TAX, + 'autocomplete' => [], + ], + 'default' => '', + 'conditions' => $include_exclude_conditions, + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + self::EXCLUDE => [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_TAX, + ], + 'default' => '', + 'conditions' => $include_exclude_conditions, + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_tab, + ], + self::ORDER_BY => [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => self::ORDER_BY_NAME, + 'options' => [ + self::ORDER_BY_NAME => esc_html__( 'Name', 'elementor-pro' ), + self::ORDER_BY_ID => esc_html__( 'ID', 'elementor-pro' ), + ], + 'separator' => 'before', + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + 'condition' => [], + ], + self::ORDER => [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => self::DESC_ORDER, + 'options' => [ + self::ASC_ORDER => esc_html__( 'ASC', 'elementor-pro' ), + self::DESC_ORDER => esc_html__( 'DESC', 'elementor-pro' ), + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + 'condition' => [], + ], + self::AVOID_DUPLICATES => [ + 'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up. This only effects the frontend.', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_tab, + ], + self::HIDE_EMPTY => [ + 'label' => esc_html__( 'Hide Empty', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'separator' => 'before', + 'condition' => [], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + self::OFFSET => [ + 'label' => esc_html__( 'Skip Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'description' => esc_html__( 'Start grid from chosen taxonomy', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_tab, + ], + self::HIERARCHICAL => [ + 'label' => esc_html__( 'Filter by depth', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'conditions' => $this->get_depth_related_filter_conditions( $is_prefixed, true ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + self::QUERY_DEPTH => [ + 'label' => esc_html__( 'Depth', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '0', + 'options' => [ + '0' => esc_html__( 'All', 'elementor-pro' ), + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'conditions' => $this->get_depth_related_filter_conditions( $is_prefixed, true, [ $is_hierarchical_term ] ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + self::QUERY_ID => [ + 'label' => esc_html__( 'Query ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'description' => esc_html__( 'Give your Query a custom unique id to allow server side filtering', 'elementor-pro' ), + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_tab, + ], + ]; + + return $control_options[ $key ] ?? $control_options; + } + + /** + * Get settings key names. + * + * Adds prefix to the desired key. + */ + public function get_property_name( string $key ): string { + return $this->skin_id . '_' . $key; + } + + /** + * Get query settings key names. + * + * Adds prefix and '_query_' to the desired key. + */ + public function get_query_property_name( string $key ): string { + return $this->get_property_name( 'query_' . $key ); + } + + public static function is_source_type_taxonomy( $source_type ) { + $available_source_types = self::get_loop_taxonomy_types(); + + return in_array( $source_type, $available_source_types, true ); + } + + public static function get_loop_taxonomy_types() { + return [ + LoopBuilderModule::LOOP_POST_TAXONOMY_SKIN_ID, + WoocommerceModule::LOOP_PRODUCT_TAXONOMY_SKIN_ID, + ]; + } + + public static function get_default_source_type( $taxonomy_loop_type, $prefix = '' ): string { + $options = [ + WoocommerceModule::LOOP_PRODUCT_TAXONOMY_SKIN_ID => self::PRODUCT_CATEGORY_TAXONOMY, + LoopBuilderModule::LOOP_POST_TAXONOMY_SKIN_ID => self::POST_CATEGORY_TAXONOMY, + ]; + + return isset( $options[ $taxonomy_loop_type ] ) + ? $prefix . $options[ $taxonomy_loop_type ] + : ''; + } + + public static function get_supported_cpts( $taxonomy_loop_type ) { + $post_types = array_merge( [ 'post' ], self::get_post_additional_cpts() ); + $options = [ + WoocommerceModule::LOOP_PRODUCT_TAXONOMY_SKIN_ID => [ 'product' ], + 'product' => [ 'product' ], + LoopBuilderModule::LOOP_POST_TAXONOMY_SKIN_ID => $post_types, + 'post' => $post_types, + ]; + + return $options[ $taxonomy_loop_type ] ?? []; + } + + private function get_include_exclude_conditions( bool $is_prefixed = false ): array { + $post_type_name = $is_prefixed ? $this->get_query_property_name( self::POST_TYPE ) : self::POST_TYPE; + $filter_by_key = $is_prefixed ? $this->get_query_property_name( self::FILTER_BY ) : self::FILTER_BY; + + $manual_selection_terms = Utils::format_control_condition( $filter_by_key, '===', self::MANUAL_SELECTION ); + + return [ + 'relation' => 'or', + 'terms' => $this->get_related_tags_conditions( $post_type_name, '===', [ $manual_selection_terms ] ), + ]; + } + + private function get_depth_related_filter_conditions( $is_prefixed, $should_add_hierarchy_condition, $extra_terms = [] ) { + $filter_by_key = $is_prefixed ? $this->get_query_property_name( self::FILTER_BY ) : self::FILTER_BY; + $post_type_key = $is_prefixed ? $this->get_query_property_name( self::POST_TYPE ) : self::POST_TYPE; + + $conditions = [ + 'relation' => 'and', + 'terms' => $this->get_related_tags_conditions( $post_type_key, '!==' ), + ]; + + if ( $should_add_hierarchy_condition ) { + $conditions['terms'][] = Utils::format_control_condition( $filter_by_key, '!==', self::MANUAL_SELECTION ); + } + + $conditions['terms'] = array_merge( $conditions['terms'], $extra_terms ); + + return $conditions; + } + + private function get_related_tags_conditions( $name, $operator, $extra_terms = [] ) { + $tags = [ self::POST_TAG_TAXONOMY, self::PRODUCT_TAG_TAXONOMY ]; + + return $this->get_related_taxonomy_condition_terms( $tags, $name, $operator, $extra_terms ); + } + + private function get_related_taxonomy_condition_terms( $value_options, $name, $operator, $extra_terms = [] ) { + $terms = []; + + foreach ( $value_options as $value ) { + $terms[] = Utils::format_control_condition( $name, $operator, $value ); + } + + return array_merge( $terms, $extra_terms ); + } + + public static function is_loop_taxonomy(): bool { + global $wp_query; + + return $wp_query->is_loop_taxonomy ?? false; + } + + public static function is_loop_taxonomy_strict(): bool { + global $wp_query; + + return self::is_loop_taxonomy() && ( $wp_query->loop_term ?? false ); + } + + private static function get_post_additional_cpts() { + $post_types = get_post_types( [ + 'public' => true, + '_builtin' => false, + ] ); + + return array_filter( $post_types, function( $post_type ) { + return ! in_array( $post_type, [ 'product', 'e-landing-page', 'elementor_library' ] ); + } ); + } +} diff --git a/modules/loop-builder/skins/skin-loop-base.php b/modules/loop-builder/skins/skin-loop-base.php new file mode 100644 index 00000000..e240a623 --- /dev/null +++ b/modules/loop-builder/skins/skin-loop-base.php @@ -0,0 +1,259 @@ +parent = $widget; + + $this->add_group_control( + Group_Control_Related::get_type(), + [ + 'name' => Module::QUERY_ID, + 'presets' => [ 'full' ], + 'exclude' => [ + 'posts_per_page', // Use the one from Layout section + ], + ] + ); + + if ( 'loop-grid' === $widget->get_name() && $this->is_editing_archive_template() ) { + $this->inject_archive_query_note( 'post_query_query_id', 'post_query_post_type', $widget ); + } + } + + protected function maybe_add_load_more_wrapper_class() { + $settings = $this->parent->get_settings_for_display(); + /** @var Loop_Widget_Base $widget */ + $widget = $this->parent; + + if ( isset( $settings['pagination_type'] ) && 'load_more_on_click' === $settings['pagination_type'] ) { + // If Pagination is enabled with the Load More On Click option, a class is needed for targeting. + // The 'wrapper' element tag is used by the Button Widget Trait. + $widget->add_render_attribute( 'wrapper', 'class', 'e-loop__load-more' ); + } + } + + public function query_posts() { + return $this->query_posts_for_alternate_templates(); + } + + /** + * Enqueue Loop Document CSS Meta + * + * Process the template before beginning to loop through the items. This ensures that + * elements with dynamic CSS are identified before each individual item is rendered. + * + * @param int $post_id + * + * @return void + */ + protected function enqueue_loop_document_css_meta( $post_id ) { + if ( $this->post_meta_css_exists( $post_id ) ) { + return; + } + + if ( wp_is_post_autosave( $post_id ) ) { + $css_file = Loop_Preview::create( $post_id ); + } else { + $css_file = Loop_CSS::create( $post_id ); + } + + /** @var Loop|Loop_Preview $css_file */ + $css_file->update(); + } + + private function post_meta_css_exists( $post_id ) { + return ! empty( get_post_meta( $post_id, Post_CSS::META_KEY ) ); + } + + public function render() { + $template_id = $this->parent->get_settings_for_display( 'template_id' ); + $is_edit_mode = Plugin::elementor()->editor->is_edit_mode(); + /** @var Loop_Widget_Base $widget */ + $widget = $this->parent; + $current_document = Plugin::elementor()->documents->get_current(); + + if ( $template_id ) { + $this->enqueue_loop_document_css_meta( $template_id ); + $this->alternate_template_before_skin_render(); + + $this->maybe_add_load_more_wrapper_class(); + + $widget->before_skin_render(); + + parent::render(); + + $widget->after_skin_render(); + + $this->alternate_template_after_skin_render(); + } elseif ( $is_edit_mode ) { + $this->render_empty_view(); + } + + if ( $current_document ) { + Plugin::elementor()->documents->switch_to_document( $current_document ); + } + } + + protected function add_render_hooks() { + global $wp_query; + $wp_query->is_loop_widget = true; + + add_filter( 'elementor-pro/off-canvas/id', [ $this, 'filter_off_canvas_id' ] ); + } + + protected function remove_render_hooks() { + global $wp_query; + unset( $wp_query->is_loop_widget ); + + remove_filter( 'elementor-pro/off-canvas/id', [ $this, 'filter_off_canvas_id' ] ); + } + + public function filter_off_canvas_id( $off_canvas_id ) { + return $this->parent->get_id() . '-' . get_the_ID() . '-' . $off_canvas_id; + } + + protected function handle_no_posts_found() { + $settings = $this->parent->get_settings_for_display(); + + ?> +
      + + < class="e-loop-nothing-found-message__text"> + + > +
      + parent; + + $classes = $widget->get_loop_header_widget_classes(); + + $classes[] = 'elementor-loop-container'; + + return $classes; + } + + protected function _register_controls_actions() { + add_action( 'elementor/element/' . $this->parent->get_name() . '/section_query/after_section_start', [ $this, 'register_query_controls' ] ); + } + + /** + * Render Post + * + * Uses the chosen custom template to render Loop posts. + * + * @since 3.8.0 + */ + protected function render_post() { + if ( $this->has_alternate_templates() ) { + $this->render_post_if_widget_has_alternate_templates(); + } else { + $this->render_post_content( $this->parent->get_settings_for_display( 'template_id' ) ); + } + } + + private function render_post_content( $template_id ) { + $post_id = get_the_ID(); + + /** @var LoopDocument $document */ + $document = Plugin::elementor()->documents->get( $template_id ); + + if ( ! $document ) { + return; + } + + $this->print_dynamic_css( $post_id, $template_id ); + $document->print_content(); + } + + protected function render_loop_header() { + /** @var Loop_Widget_Base $widget */ + $widget = $this->parent; + $config = $widget->get_config(); + + if ( $config['add_parent_render_header'] ) { + parent::render_loop_header(); + } + + $widget->render_loop_header(); + } + + protected function render_loop_footer() { + /** @var Loop_Widget_Base $widget */ + $widget = $this->parent; + $config = $widget->get_config(); + + if ( $config['add_parent_render_footer'] ) { + parent::render_loop_footer(); + } + + $widget->render_loop_footer(); + } + + /** + * Render Empty View + * + * Renders the Loop widget's view if there is no default template (empty view). + * + * @since 3.8.0 + */ + protected function render_empty_view() { + ?> +
      + parent; + + $this->enqueue_loop_document_css_meta( $template_id ); + $this->maybe_add_load_more_wrapper_class(); + $widget->before_skin_render(); + $this->render_loop_header(); + } + + protected function get_default_source_option() { + return Taxonomy_Loop_Provider::POST_CATEGORY_TAXONOMY; + } +} diff --git a/modules/loop-builder/skins/skin-loop-post.php b/modules/loop-builder/skins/skin-loop-post.php new file mode 100644 index 00000000..873e80ce --- /dev/null +++ b/modules/loop-builder/skins/skin-loop-post.php @@ -0,0 +1,19 @@ +parent = $widget; + } + + protected function init_provider() { + $this->provider = new Taxonomy_Loop_Provider( $this->get_id(), $this->get_default_source_option() ); + } + + public function render() { + $template_id = $this->parent->get_settings_for_display( 'template_id' ); + $is_edit_mode = Plugin::elementor()->editor->is_edit_mode(); + $current_document = Plugin::elementor()->documents->get_current(); + + if ( $template_id ) { + $this->prepare_template_loop( $this->get_terms(), $template_id ); + } elseif ( $is_edit_mode ) { + $this->render_empty_view(); + } + + if ( $current_document ) { + Plugin::elementor()->documents->switch_to_document( $current_document ); + } + } + + protected function prepare_template_loop( $terms, $template_id ) { + global $wp_query; + $wp_query->is_loop_taxonomy = ! empty( $terms ); + + $this->render_before_loop( $template_id ); + $this->render_loop_content( $terms, $template_id ); + $this->render_loop_end(); + + $wp_query->is_loop_taxonomy = false; + } + + protected function render_before_loop( $template_id ) { + $widget = $this->parent; + + $this->enqueue_loop_document_css_meta( $template_id ); + $this->maybe_add_load_more_wrapper_class(); + $widget->before_skin_render(); + $this->render_loop_header(); + } + + protected function render_loop_content( $terms, $template_id ) { + global $wp_query; + + foreach ( $terms as $term ) { + $wp_query->loop_term = $term; + $this->render_post(); + $wp_query->loop_term = null; + } + } + + /** + * Render Post + * + * Uses the chosen custom template to render Loop posts. + * + * @since 3.8.0 + */ + protected function render_post() { + $template_id = $this->parent->get_settings_for_display( 'template_id' ); + + /** @var LoopDocument $document */ + $document = Plugin::elementor()->documents->get( $template_id ); + + if ( ! $document ) { + return; + } + + $this->print_dynamic_css( $this->get_data_id_from_taxonomy_loop_query(), $template_id ); + $document->print_content(); + } + + protected function render_loop_end() { + /** @var Loop_Widget_Base $widget */ + $widget = $this->parent; + + $this->render_loop_footer(); + $widget->after_skin_render(); + } + + /** + * Register Query Controls + * + * Registers the controls for the query used by the Loop. + * + * @since 3.8.0 + */ + public function register_query_controls( Loop_Widget_Base $widget ) { + $this->init_parent( $widget ); + $this->init_provider(); + $post_type_options = $this->get_taxonomy_options( ( Taxonomy_Loop_Provider::get_supported_cpts( $this->post_type ) ) ); + $default_source_type = $this->get_default_source_option(); + + $this->add_group_control( + Group_Control_Taxonomy::get_type(), + [ + 'name' => Taxonomy_Loop_Provider::QUERY_CONTROL_GROUP_NAME, + Taxonomy_Loop_Provider::POST_TYPE => Taxonomy_Loop_Provider::get_default_source_type( $this->get_id() ), + 'presets' => [ 'include', 'exclude' ], + 'fields_options' => [ + Taxonomy_Loop_Provider::POST_TYPE => [ + 'default' => $default_source_type, + 'options' => $post_type_options, + ], + Taxonomy_Loop_Provider::FILTER_BY => $this->provider->get_control_args( Taxonomy_Loop_Provider::FILTER_BY, false ), + Taxonomy_Loop_Provider::INCLUDE_TAB => $this->provider->get_control_args( Taxonomy_Loop_Provider::INCLUDE_TAB, false ), + Taxonomy_Loop_Provider::EXCLUDE_TAB => $this->provider->get_control_args( Taxonomy_Loop_Provider::EXCLUDE_TAB, false ), + ], + 'exclude' => [ + 'include', + 'exclude', + ], + ], + ); + + // Filtering controls + $this->add_query_control( Taxonomy_Loop_Provider::PARENT, true ); + $this->add_query_control( Taxonomy_Loop_Provider::INCLUDE, true ); + $this->add_query_control( Taxonomy_Loop_Provider::EXCLUDE, true ); + + // Order controls + $this->add_query_control( Taxonomy_Loop_Provider::ORDER_BY, true ); + $this->add_query_control( Taxonomy_Loop_Provider::ORDER, true ); + + // Result exclusion controls + $this->add_query_control( Taxonomy_Loop_Provider::AVOID_DUPLICATES, true ); + $this->add_query_control( Taxonomy_Loop_Provider::HIDE_EMPTY, true ); + $this->add_query_control( Taxonomy_Loop_Provider::OFFSET, true ); + + // Hierarchical controls + $this->add_query_control( Taxonomy_Loop_Provider::HIERARCHICAL, true ); + $this->add_query_control( Taxonomy_Loop_Provider::QUERY_DEPTH, true ); + + // Result inclusion controls + $this->add_query_control( Taxonomy_Loop_Provider::QUERY_ID, true ); + } + + /** + * Returns desired taxonomy items. + * + * Uses control values from get_settings_for_display. + */ + protected function get_terms() { + $display_settings = $this->parent->get_settings_for_display(); + $settings = $this->provider->get_query_settings( $display_settings ); + + add_filter( 'elementor/loop_taxonomy/args', [ $this, 'filter_loop_taxonomy_args' ], 10, 3 ); + + $terms = $this->get_filtered_taxonomies( $settings, $settings ); + + remove_filter( 'elementor/loop_taxonomy/args', [ $this, 'filter_loop_taxonomy_args' ] ); + + Module::add_to_taxonomies_avoid_list( wp_list_pluck( $terms, 'term_id' ) ); + + return $terms; + } + + public function filter_loop_taxonomy_args( $args, $settings, $display_settings ) { + $avoid_duplicates_key = $this->provider->get_property_name( 'avoid_duplicates' ); + $current_settings = $this->parent->get_settings_for_display(); + + $should_avoid_duplicates = isset( $current_settings[ $avoid_duplicates_key ] ) && + 'yes' === $current_settings[ $avoid_duplicates_key ]; + + if ( $should_avoid_duplicates ) { + $exclude = isset( $args['exclude'] ) && is_array( $args['exclude'] ) ? $args['exclude'] : []; + $exclude = array_merge( $exclude, Module::get_taxonomies_avoid_list_ids() ); + $args['exclude'] = $exclude; + } + + return $args; + } + + private function add_query_control( $control_id, $is_prefixed ) { + $this->add_control( $control_id, $this->provider->get_control_args( $control_id, $is_prefixed ) ); + } +} diff --git a/modules/loop-builder/traits/alternate-templates-trait.php b/modules/loop-builder/traits/alternate-templates-trait.php new file mode 100644 index 00000000..ee9a4a0c --- /dev/null +++ b/modules/loop-builder/traits/alternate-templates-trait.php @@ -0,0 +1,560 @@ +found_posts` + * and `$query->max_num_pages` so the pagination, and any standard WP Query elements, display as expected. + * + * @return false|\WP_Query + */ + public function query_posts_for_alternate_templates() { + // If there are no static alternate templates, no need to modify the query. + if ( ! $this->has_static_alternate_templates() ) { + return false; + } + + $widget = $this->parent; + + /** @var QueryControlModule $elementor_query */ + $elementor_query = QueryControlModule::instance(); + + /** + * Construct the `static_alternate_template_query_data` used for the new query and when rendering each post. + */ + $query = $elementor_query->get_query( $widget, $widget->get_query_name(), [ + 'posts_per_page' => 1, + 'paged' => 1, + ] ); + $this->init_static_alternate_template_query_data( $query->found_posts ); + + if ( ! $this->query_contains_static_alternate_templates() ) { + return false; + } + + $adjusted_found_posts = $this->get_static_alternate_template_adjusted_found_posts(); + $adjusted_max_num_pages = $this->get_static_alternate_template_adjusted_max_num_pages(); + + /** + * New query using `offset` in place of `paged`. + */ + $query = $elementor_query->get_query( $widget, $widget->get_query_name(), [ + 'posts_per_page' => $widget->get_posts_per_page_value(), + 'offset' => $this->get_static_alternate_template_query_offset(), + ] ); + + /** + * Increase size of the query using the adjusted values calculated after + * constructing `static_alternate_template_query_data`. + */ + $query->found_posts = $adjusted_found_posts; + $query->max_num_pages = $adjusted_max_num_pages; + + return $query; + } + + /** + * Init Alternate Templates Settings + * + * Improve performance by storing the `alternate_templates` repeater settings, so we don't use + * `get_settings_for_display()` each time we check if a post should use an alternate template. + * + * At the same time we store `$has_alternate_templates` and `$has_static_alternate_templates` used by their + * accompanying helper functions, for efficiency, and so we don't need to loop through the `alternate_templates` + * each time we check. + * + * We also re-arrange the `alternate_templates` array for two reasons: + * (1) The last template added by the user should take preference, so we reverse the array so that when we loop + * through the repeater settings array to check if a post should use an alternate template, we find the last + * added template first. + * (2) 'Static' alternate templates should take preference over 'non-static' templates, so we group all static + * templates before first, so when we loop through the array to check if a post should use an alternate template + * we find the 'static' template first. + * + * @return void + */ + private function init_alternate_template_settings(): void { + $settings = $this->parent->get_settings_for_display(); + + if ( empty( $settings['alternate_templates'] ) || empty( $settings['template_id'] ) ) { + return; + } + + // Note that the user has added alternate templates. + $this->has_alternate_templates = true; + + // Store the alternate templates. + $alternate_templates = $settings['alternate_templates']; + + // Reverse the alternate template settings so the last template added by the user takes preference over + // the previous templates. + $alternate_templates = array_reverse( $alternate_templates ); + + // Rearrange the alternate template settings to group all static templates before the standard templates. + $static_alternate_templates = []; + $standard_alternate_templates = []; + foreach ( $alternate_templates as $alternate_template ) { + // Skip the alternate template from any calculations until a repeat template number is specified. + if ( empty( $alternate_template['repeat_template'] ) ) { + continue; + } + + if ( $this->is_alternate_template_static_position( $alternate_template ) ) { + $static_alternate_templates[ $alternate_template['_id'] ] = $alternate_template; + + // Note that the user has added 'static' alternate templates. + $this->has_static_alternate_templates = true; + } else { + $standard_alternate_templates[ $alternate_template['_id'] ] = $alternate_template; + } + } + + $this->alternate_templates = $static_alternate_templates + $standard_alternate_templates; + } + + private function alternate_template_before_skin_render(): void { + // Init Alternate Template Settings should occur as early in the load order as possible as it's responsible + // for setting flags used in helper functions, that can be called quite early in the widget + // e.g. `has_alternate_templates()` & `has_static_alternate_templates()`. + $this->init_alternate_template_settings(); + + if ( ! $this->has_alternate_templates() ) { + return; + } + + $this->maybe_add_alternate_template_wrapper_classes(); + } + + private function alternate_template_after_skin_render(): void { + if ( ! $this->has_alternate_templates() ) { + return; + } + + $this->reset_alternate_template_data(); + $this->maybe_remove_alternate_template_wrapper_classes(); + } + + /** + * @return void + */ + private function reset_alternate_template_data() { + // Reset all the Alternate Template data at the end of the widget so that it does not affect any widgets + // below the current widget. + $this->current_post_index = 0; + $this->alternate_templates = []; + $this->rendered_alternate_templates = []; + $this->has_alternate_templates = false; + $this->has_static_alternate_templates = false; + $this->query_contains_static_alternate_templates = false; + $this->static_alternate_template_query_data = []; + } + + /** + * @return void + */ + private function maybe_add_alternate_template_wrapper_classes(): void { + add_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_alternate_template_wrapper_classes' ] ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + add_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_alternate_template_editor_wrapper_classes' ] ); + } + } + + /** + * @return void + */ + private function maybe_remove_alternate_template_wrapper_classes(): void { + remove_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_alternate_template_wrapper_classes' ] ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + remove_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_alternate_template_editor_wrapper_classes' ] ); + } + } + + /** + * @param $attributes + * @return array + */ + public function add_alternate_template_wrapper_classes( $attributes ): array { + $template = $this->get_template_data_for_current_post(); + + if ( $this->is_alternate_template( $template ) ) { + $attributes['class'] .= ' elementor-repeater-item-' . $template['_id']; + } + + return $attributes; + } + + /** + * @param $attributes + * @return array + */ + public function add_alternate_template_editor_wrapper_classes( $attributes ): array { + $template = $this->get_template_data_for_current_post(); + + if ( $this->is_alternate_template( $template ) && $this->is_alternate_template_first_occurrence( $template ) ) { + $attributes['class'] .= ' e-loop-alternate-template'; + } + + return $attributes; + } + + /** + * @return void + */ + private function render_post_if_widget_has_alternate_templates(): void { + // If any static templates are rendered they will result in this function being called recursively, so we need + // to make sure we don't render more posts than the user has chosen in their `posts_per_page` widget control. + if ( $this->current_post_index >= $this->parent->get_posts_per_page_value() ) { + return; + } + + $template = $this->get_template_data_for_current_post(); + $this->render_post_content( $template['template_id'] ); + $this->store_rendered_alternate_templates( $template['template_id'] ); + $this->current_post_index++; + + // If the current post has a 'static' alternate template the above will render an extra empty post in the loop. + // We need to render this post again (with incremented `current_post_index`) so it is not skipped as a result + // of a static template. + if ( $this->is_alternate_template_static_position( $template ) ) { + $this->render_post_if_widget_has_alternate_templates(); + } + } + + /** + * @param $template_id + * @return void + */ + private function store_rendered_alternate_templates( $template_id ): void { + if ( ! in_array( $template_id, $this->rendered_alternate_templates, true ) ) { + $this->rendered_alternate_templates[] = $template_id; + } + } + + /** + * Has Alternate Templates + * + * Has the user added any alternate templates to the widget. + * + * Improve performance by storing `has_alternate_templates` once when the widget is rendered + * to avoid using `get_settings_for_display()` each time. + * + * @return bool + */ + private function has_alternate_templates(): bool { + return $this->has_alternate_templates; + } + + /** + * Has Static Alternate Templates + * + * Has the user added any 'static' alternate templates to the widget. + * + * Improve performance by storing `has_static_alternate_templates` once when the widget is rendered + * to avoid iterating through the repeater settings each time. + * + * @return bool + */ + private function has_static_alternate_templates(): bool { + return $this->has_static_alternate_templates; + } + + /** + * Query Contains Static Alternate Templates + * + * After constructing the `init_static_alternate_template_query_data` array, we want to make sure - based on + * the alternate templates settings - that we definitely have valid 'static' alternate templates to display. + * + * This flag is used to avoid modifying the query or re-rendering posts if we don't have to. + * + * @return bool + */ + private function query_contains_static_alternate_templates(): bool { + return $this->query_contains_static_alternate_templates; + } + + /** + * Init Static Alternate Template Query Data + * + * Construct `static_alternate_template_query_data` if the user has added any valid 'static' alternate templates. + * Used to modify the widget query and when rendering a post. + * + * @param $query + * @return void + */ + private function init_static_alternate_template_query_data( $required_posts_count ): void { + $this->static_alternate_template_query_data = [ + 'templates' => [], + 'page_settings' => [], + ]; + + $posts_per_page = $this->parent->get_posts_per_page_value(); + $static_alternate_template_count = 0; + + for ( $current_index = 0; $current_index < $required_posts_count; $current_index++ ) { + $template = $this->get_template_data_by_index( $current_index ); + $this->set_static_alternate_template_query_data_item( $template, $current_index, $static_alternate_template_count, $posts_per_page ); + + if ( 'yes' === $template['static_position'] ) { + $static_alternate_template_count++; + $required_posts_count++; + } + } + + // Note if any valid 'static' alternate templates need to be displayed, after the above calculations. + $this->query_contains_static_alternate_templates = 0 < $static_alternate_template_count; + } + + /** + * Set Static Alternate Template Query Data Item + * + * Store which template to use when each post is rendered. + * + * `init_static_alternate_template_query_data()` stores each template's data in the + * `static_alternate_template_query_data['templates']` and, at the same time, stores + * `static_alternate_template_query_data['page_settings']` used to adjust the query. + * + * @param $template + * @param $current_post_index + * @param $static_alternate_template_count + * @param $posts_per_page + * @return void + */ + private function set_static_alternate_template_query_data_item( $template, $current_post_index, $static_alternate_template_count, $posts_per_page ): void { + // Store template - used when we render the post. + $this->static_alternate_template_query_data['templates'][ $current_post_index ] = $template; + + // Store `page_settings`. + // `query_offset` is used when we query posts and `start_index` when we render posts. + $current_page = ceil( $current_post_index / $posts_per_page ) + 1; + $this->static_alternate_template_query_data['page_settings'][ $current_page ] = [ + 'query_offset' => $current_post_index - $static_alternate_template_count, + 'start_index' => $current_post_index, + ]; + } + + /** + * Get Static Alternate Template Current Page Settings + * + * Used to modify the widget query and when rendering a post. + * + * @return array|bool + */ + private function get_static_alternate_template_current_page_settings() { + $current_page = $this->parent->get_current_page(); + if ( empty( $this->static_alternate_template_query_data['page_settings'][ $current_page ] ) ) { + return false; + } + return $this->static_alternate_template_query_data['page_settings'][ $current_page ]; + } + + /** + * Get Static Alternate Template Query Offset + * + * Used to modify the widget query. + * + * @return array|bool + */ + private function get_static_alternate_template_query_offset() { + $current_page_settings = $this->get_static_alternate_template_current_page_settings(); + if ( ! $current_page_settings ) { + return false; + } + return $current_page_settings['query_offset']; + } + + /** + * Get Static Alternate Template Start Index + * + * Used when calling `render_post_if_widget_has_alternate_templates()`. + * + * @return array|bool + */ + private function get_static_alternate_template_start_index() { + $current_page_settings = $this->get_static_alternate_template_current_page_settings(); + if ( ! $current_page_settings ) { + return false; + } + return $current_page_settings['start_index']; + } + + /** + * Get Static Alternate Template Adjusted Found Posts + * + * Used to modify the widget query. + * + * @return int + */ + private function get_static_alternate_template_adjusted_found_posts(): int { + if ( empty( $this->static_alternate_template_query_data['templates'] ) ) { + return 0; + } + return count( $this->static_alternate_template_query_data['templates'] ); + } + + /** + * Get Static Alternate Template Adjusted Max Num Pages + * + * Used to modify the widget query. + * + * @return float + */ + private function get_static_alternate_template_adjusted_max_num_pages(): float { + return ceil( $this->get_static_alternate_template_adjusted_found_posts() / $this->parent->get_posts_per_page_value() ); + } + + /** + * Get Data For Static Alternate Template + * + * Used when rendering the current post. + * + * @param $index + * @return array + */ + private function get_data_for_static_alternate_template( $index ): array { + if ( ! empty( $this->static_alternate_template_query_data['templates'][ $index ] ) ) { + return $this->static_alternate_template_query_data['templates'][ $index ]; + } + return $this->get_default_template(); + } + + /** + * @return array + */ + private function get_template_data_for_current_post() { + $current_post_index = $this->get_current_post_index(); + + if ( $this->query_contains_static_alternate_templates() ) { + return $this->get_data_for_static_alternate_template( $current_post_index ); + } + + return $this->get_template_data_by_index( $current_post_index ); + } + + /** + * @return int + */ + private function get_current_post_index() { + if ( $this->query_contains_static_alternate_templates() ) { + return $this->get_static_alternate_template_start_index() + $this->current_post_index; + } + + return $this->parent->get_query()->current_post; + } + + /** + * @param $index + * @return array + */ + private function get_template_data_by_index( $index ): array { + if ( ! $this->has_alternate_templates() ) { + return $this->get_default_template(); + } + + foreach ( $this->alternate_templates as $alternate_template ) { + $found_alternate_template = $this->is_alternate_template_show_once( $alternate_template ) ? + $this->should_show_alternate_template_once( $alternate_template, $index ) : + $this->should_show_repeating_alternate_template( $alternate_template, $index ); + + if ( $found_alternate_template ) { + return [ + 'template_id' => $alternate_template['template_id'], + 'alternate_template' => 'yes', + 'static_position' => $alternate_template['static_position'] ? 'yes' : 'no', + '_id' => $alternate_template['_id'], + ]; + } + } + + return $this->get_default_template(); + } + + /** + * @return array + */ + private function get_default_template(): array { + return [ + 'template_id' => $this->parent->get_settings_for_display( 'template_id' ), + 'alternate_template' => 'no', + 'static_position' => 'no', + '_id' => '-', + ]; + } + + /** + * @param $alternate_template + * @return bool + */ + private function is_alternate_template( $alternate_template ): bool { + return isset( $alternate_template['alternate_template'] ) && 'yes' === $alternate_template['alternate_template']; + } + + /** + * @param $alternate_template + * @return bool + */ + private function is_alternate_template_static_position( $alternate_template ): bool { + return isset( $alternate_template['static_position'] ) && 'yes' === $alternate_template['static_position']; + } + + /** + * @param $alternate_template + * @return bool + */ + private function is_alternate_template_show_once( $alternate_template ): bool { + return isset( $alternate_template['show_once'] ) && 'yes' === $alternate_template['show_once']; + } + + /** + * @param $number_to_check + * @param $multiple_to_check + * @return bool + */ + private function is_repeating_alternate_template_multiple_of( $number_to_check, $multiple_to_check ): bool { + return 0 === $multiple_to_check % $number_to_check; + } + + /** + * @param $template + * @return bool + */ + private function is_alternate_template_first_occurrence( $template ): bool { + return ! in_array( $template['template_id'], $this->rendered_alternate_templates, true ); + } + + /** + * @param $alternate_template + * @param $current_item_index + * @return bool + */ + private function should_show_alternate_template_once( $alternate_template, $current_item_index ): bool { + return $alternate_template['repeat_template'] === $current_item_index + 1; + } + + /** + * @param $alternate_template + * @param $current_item_index + * @return bool + */ + private function should_show_repeating_alternate_template( $alternate_template, $current_item_index ): bool { + return $this->is_repeating_alternate_template_multiple_of( $alternate_template['repeat_template'], $current_item_index + 1 ); + } +} diff --git a/modules/loop-builder/views/cta-template.php b/modules/loop-builder/views/cta-template.php new file mode 100644 index 00000000..0867b510 --- /dev/null +++ b/modules/loop-builder/views/cta-template.php @@ -0,0 +1,78 @@ + + + + + diff --git a/modules/loop-builder/widgets/base.php b/modules/loop-builder/widgets/base.php new file mode 100644 index 00000000..bd13fcfc --- /dev/null +++ b/modules/loop-builder/widgets/base.php @@ -0,0 +1,370 @@ +get_current_skin_id() ); + return $skin_id . '_' . Module::QUERY_ID; + } + + protected function get_initial_config() { + $config = parent::get_initial_config(); + + $config['is_loop'] = true; + $config['add_parent_render_header'] = true; + $config['add_parent_render_footer'] = true; + + return $config; + } + + public function query_posts() { + $skin = $this->get_current_skin(); + $query = false; + if ( $skin ) { + $query = $skin->query_posts( $this ); + } + + if ( $query ) { + $this->query = $query; + } else { + parent::query_posts(); + } + } + + /** + * Get Posts Per Page Value + * + * Returns the value of the Posts Per Page control of the widget. + * + * @since 3.8.0 + * @access protected + * + * @return mixed + */ + public function get_posts_per_page_value() { + return $this->get_settings_for_display( 'posts_per_page' ); + } + + protected function register_skins() { + $this->add_skin( new Skin_Loop_Post( $this ) ); + } + + protected function register_controls() { + $this->register_layout_section(); + $this->register_query_section(); + + // Carousel + $this->register_settings_section_controls(); + $this->register_navigation_section_controls(); + + $this->register_pagination_section_controls(); + $this->register_additional_options_section_controls(); + + $this->register_design_layout_controls(); + $this->register_design_nothing_found_message_controls(); + $this->register_design_navigation_controls(); + $this->register_design_pagination_controls(); + + // The `_skins` control determines the Loop's query source, so it is renamed for this to be clearer to the user. + $this->update_control( '_skin', [ + 'label' => esc_html__( 'Choose template type', 'elementor-pro' ), + 'label_block' => true, + 'frontend_available' => true, + ] ); + } + + /** + * Register Layout Section + * + * This registers the Layout section in order to allow Skins to register their layout controls. + * + * @since 3.8.0 + */ + protected function register_layout_section() { + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'template_id', + [ + 'label' => esc_html__( 'Choose a template', 'elementor-pro' ), + 'type' => Template_Query::CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'post_status' => Document::STATUS_PUBLISH, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => LoopDocument::get_type(), + 'compare' => 'IN', + ], + ], + ], + ], + 'actions' => [ + 'new' => [ + 'visible' => true, + 'document_config' => [ + 'type' => LoopDocument::get_type(), + ], + ], + 'edit' => [ + 'visible' => true, + ], + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + } + + /** + * Register Query Section + * + * This registers the Query section in order to allow Skins to register their query controls. + * + * @since 3.8.0 + */ + protected function register_query_section() { + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->end_controls_section(); + } + + public function register_pagination_section_controls() { + parent::register_pagination_section_controls(); + + $this->remove_responsive_control( 'align' ); + + $this->start_injection( [ + 'of' => 'pagination_align', + 'at' => 'after', + ] ); + + $this->add_responsive_control( + 'load_more_button_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'default' => 'center', + 'condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--load-more-button-align: start;', + 'center' => '--load-more-button-align: center;', + 'end' => '--load-more-button-align: end;', + 'justify' => '--load-more-button-width: 100%;', + ], + ] + ); + + $this->add_control( + 'pagination_load_type', + [ + 'label' => esc_html__( 'Load Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'page_reload', + 'options' => [ + 'page_reload' => esc_html__( 'Page Reload', 'elementor-pro' ), + 'ajax' => esc_html__( 'AJAX', 'elementor-pro' ), + ], + 'frontend_available' => true, + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'prev_next', + 'numbers_and_prev_next', + ], + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'auto_scroll', + [ + 'label' => esc_html__( 'Autoscroll', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_load_type' => [ + 'ajax', + ], + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'auto_scroll_offset', + [ + 'label' => esc_html__( 'Autoscroll offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'selectors' => [ + '{{WRAPPER}}' => '--auto-scroll-offset: {{VALUE}}px;', + ], + 'condition' => [ + 'pagination_load_type' => [ + 'ajax', + ], + 'auto_scroll' => 'yes', + ], + ] + ); + + $this->end_injection(); + + // Remove the HTML Entity arrows inherited from the Posts widget from the prev/next pagination link labels. + $this->update_control( + 'pagination_prev_label', + [ + 'default' => esc_html__( 'Previous', 'elementor-pro' ), + ] + ); + + $this->update_control( + 'pagination_next_label', + [ + 'default' => esc_html__( 'Next', 'elementor-pro' ), + ] + ); + + $this->update_control( + 'pagination_individual_divider', + [ + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + 'pagination_load_type' => [ + 'page_reload', + ], + ], + ] + ); + + $this->update_control( + 'pagination_individual_handle', + [ + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + 'pagination_load_type' => [ + 'page_reload', + ], + ], + ] + ); + + $this->update_control( + 'pagination_individual_handle_message', + [ + 'raw' => esc_html__( 'For multiple Loop Widgets on the same page, toggle this on to control the pagination for each individually. Note: It affects the page\'s URL structure.', 'elementor-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + 'pagination_load_type' => [ + 'page_reload', + ], + ], + ] + ); + } + + protected function register_additional_options_section_controls() {} + + protected function register_design_layout_controls() {} + + protected function register_design_nothing_found_message_controls() {} + + protected function register_design_navigation_controls() {} + + protected function register_design_pagination_controls() {} + + public function register_settings_section_controls() {} + + public function register_navigation_section_controls() {} + + public function get_loop_header_widget_classes(): array { + return []; + } + + public function render_loop_header() {} + + public function render_loop_footer() {} + + public function before_skin_render() {} + + public function after_skin_render() {} +} diff --git a/modules/loop-builder/widgets/loop-carousel.php b/modules/loop-builder/widgets/loop-carousel.php new file mode 100644 index 00000000..a6e72441 --- /dev/null +++ b/modules/loop-builder/widgets/loop-carousel.php @@ -0,0 +1,266 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function get_initial_config() { + $config = parent::get_initial_config(); + + $config['add_parent_render_footer'] = false; + + return $config; + } + + public function register_settings_section_controls() { + $this->add_carousel_settings_controls( [ + 'css_prefix' => '', + ] ); + } + + public function register_navigation_section_controls() { + $this->add_carousel_navigation_controls( [ + 'css_prefix' => '', + 'navigation_custom_settings' => [ + 'condition' => [ + 'template_id!' => '', + ], + ], + ] ); + } + + public function register_pagination_section_controls() { + $this->add_carousel_pagination_controls( [ + 'css_prefix' => '', + 'section_carousel_pagination' => [ + 'condition' => [ + 'template_id!' => '', + ], + ], + ] ); + } + + public function register_design_layout_controls() { + $this->start_controls_section( + 'section_layout_style', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'image_spacing_custom', + [ + 'label' => esc_html__( 'Gap between slides', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ + 'px' => [ + 'max' => 400, + ], + ], + 'default' => [ + 'size' => 10, + ], + 'frontend_available' => true, + 'render_type' => 'none', + 'selectors' => [ + '{{WRAPPER}}' => '--swiper-slides-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_design_navigation_controls() { + $this->add_carousel_navigation_styling_controls( [ + 'css_prefix' => '', + 'navigation_styling_custom_settings' => [ + 'condition' => [ + 'arrows' => 'yes', + 'template_id!' => '', + ], + ], + ] ); + } + + public function register_design_pagination_controls() { + $this->add_carousel_pagination_style_controls( [ + 'css_prefix' => '', + ] ); + } + + public function render_loop_header() { + $has_autoplay_enabled = 'yes' === $this->get_settings_for_display( 'autoplay' ); + + $this->add_render_attribute( 'swiper-wrapper', [ + 'class' => 'swiper-wrapper', + 'aria-live' => $has_autoplay_enabled ? 'off' : 'polite', + ] ); + ?> +
      print_render_attribute_string( 'swiper-wrapper' ); ?>> + +
      +
      + get_settings_for_display(); + $this->render_carousel_footer( $settings ); + } + + public function add_swiper_slide_attributes_to_loop_item( $attributes, $document ) { + if ( LoopDocument::DOCUMENT_TYPE === $document::get_type() ) { + $attributes['class'] .= ' swiper-slide'; + $attributes['role'] = 'group'; + $attributes['aria-roledescription'] = 'slide'; + } + + return $attributes; + } + + public function add_loop_header_attributes( $render_attributes ) { + $settings = $this->get_settings_for_display(); + + if ( ! empty( $settings['direction'] ) ) { + $render_attributes['dir'] = $settings['direction']; + } + + return $render_attributes; + } + + + public function get_loop_header_widget_classes(): array { + return [ 'swiper' ]; + } + + public function before_skin_render() { + add_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_swiper_slide_attributes_to_loop_item' ], 10, 2 ); + add_filter( 'elementor/skin/loop_header_attributes', [ $this, 'add_loop_header_attributes' ], 10, 1 ); + } + + public function after_skin_render() { + remove_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_swiper_slide_attributes_to_loop_item' ] ); + remove_filter( 'elementor/skin/loop_header_attributes', [ $this, 'add_loop_header_attributes' ] ); + } + + protected function register_layout_section() { + parent::register_layout_section(); + + $this->start_injection( [ + 'of' => 'template_id', + ] ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Number of slides', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + 'min' => 1, + 'condition' => [ + 'template_id!' => '', + ], + 'separator' => 'before', + ] + ); + + $this->add_carousel_layout_controls( [ + 'css_prefix' => '', + 'slides_to_show_custom_settings' => [ + 'default' => '3', + 'widescreen_default' => '3', + 'laptop_default' => '3', + 'tablet_extra_default' => '3', + 'tablet_default' => '2', + 'mobile_extra_default' => '2', + 'mobile_default' => '1', + 'condition' => [ + 'posts_per_page!' => 1, + 'template_id!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--swiper-slides-to-display: {{VALUE}}', + ], + ], + 'slides_to_scroll_custom_settings' => [ + 'default' => '1', + 'condition' => [ + 'posts_per_page!' => 1, + 'template_id!' => '', + ], + ], + 'equal_height_custom_settings' => [ + 'condition' => [ + 'posts_per_page!' => 1, + 'template_id!' => '', + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide > .elementor-element' => 'height: 100%', + ], + ], + 'slides_on_display' => 8, + ] ); + + // Location for the Edit handle. + $this->add_control( + 'edit_handle_selector', + [ + 'label' => esc_html__( 'Edit Handle Selector', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => '.elementor-loop-container', + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->end_injection(); + } +} diff --git a/modules/loop-builder/widgets/loop-grid.php b/modules/loop-builder/widgets/loop-grid.php new file mode 100644 index 00000000..2c437b32 --- /dev/null +++ b/modules/loop-builder/widgets/loop-grid.php @@ -0,0 +1,603 @@ +start_injection( [ + 'of' => 'template_id', + ] ); + + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '3', + 'tablet_default' => '2', + 'mobile_default' => '1', + 'min' => 1, + 'max' => 12, + 'prefix_class' => 'elementor-grid%s-', + 'frontend_available' => true, + 'separator' => 'before', + 'condition' => [ + 'template_id!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-columns: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Items Per Page', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + 'min' => 1, + 'condition' => [ + 'template_id!' => '', + ], + ] + ); + + $this->add_control( + 'masonry', + [ + 'label' => esc_html__( 'Masonry', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'columns!' => 1, + 'template_id!' => '', + ], + 'render_type' => 'ui', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'equal_height', + [ + 'label' => esc_html__( 'Equal height', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'columns!' => 1, + 'template_id!' => '', + 'masonry' => '', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-loop-container' => 'grid-auto-rows: 1fr', + // `.elementor-section-wrap` exists only when editing the loop template. + '{{WRAPPER}} .e-loop-item > .elementor-section, {{WRAPPER}} .e-loop-item > .elementor-section > .elementor-container, {{WRAPPER}} .e-loop-item > .e-con, {{WRAPPER}} .e-loop-item .elementor-section-wrap > .e-con' => 'height: 100%', + ], + ] + ); + + $this->add_control( + 'alternate_template', + [ + 'label' => esc_html__( 'Apply an alternate template', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'posts_per_page!' => 1, + 'template_id!' => '', + '_skin!' => [ + LoopBuilderModule::LOOP_POST_TAXONOMY_SKIN_ID, + WoocommerceModule::LOOP_PRODUCT_TAXONOMY_SKIN_ID, + ], + ], + 'render_type' => 'template', + 'frontend_available' => true, + 'separator' => 'before', + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'template_id', + [ + 'label' => esc_html__( 'Choose a template', 'elementor-pro' ), + 'type' => Template_Query::CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'post_status' => Document::STATUS_PUBLISH, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => LoopDocument::get_type(), + 'compare' => 'IN', + ], + ], + ], + ], + 'actions' => [ + 'new' => [ + 'visible' => true, + 'document_config' => [ + 'type' => LoopDocument::get_type(), + ], + 'after_action' => 'redirect', + ], + 'edit' => [ + 'visible' => true, + 'after_action' => 'redirect', + ], + ], + 'frontend_available' => true, + ] + ); + + $repeater->add_control( + 'repeat_template', + [ + 'label' => esc_html__( 'Position in grid', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'condition' => [ + 'template_id!' => '', + ], + ] + ); + + $repeater->add_control( + 'repeat_template_note', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Note: Repeat the alternate template once every chosen number of items.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'template_id!' => '', + ], + ] + ); + + $repeater->add_control( + 'show_once', + [ + 'label' => esc_html__( 'Apply Once', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'condition' => [ + 'template_id!' => '', + ], + 'render_type' => 'template', + ] + ); + + $repeater->add_responsive_control( + 'column_span', + [ + 'label' => esc_html__( 'Column Span', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '1', + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + '7' => esc_html__( '7', 'elementor-pro' ), + '8' => esc_html__( '8', 'elementor-pro' ), + '9' => esc_html__( '9', 'elementor-pro' ), + '10' => esc_html__( '10', 'elementor-pro' ), + '11' => esc_html__( '11', 'elementor-pro' ), + '12' => esc_html__( '12', 'elementor-pro' ), + ], + 'condition' => [ + 'template_id!' => '', + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}}' => 'grid-column: span min( {{VALUE}}, var(--grid-columns) );', + ], + ] + ); + + $repeater->add_control( + 'column_span_note', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Note: Item will span across a number of columns.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'template_id!' => '', + ], + ] + ); + + $repeater->add_control( + 'column_span_masonry_note', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'warning', + 'content' => esc_html__( 'Note: The Masonry option combined with Column Span might cause unexpected results and break the layout.', 'elementor-pro' ), + 'condition' => [ + 'column_span!' => '1', + ], + ] + ); + + $repeater->add_control( + 'static_position', + [ + 'label' => esc_html__( 'Static item position', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'template_id!' => '', + ], + 'render_type' => 'template', + ] + ); + + $repeater->add_control( + 'static_position_note', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Note: Static Items remain in place when new items are added to grid. Other items appear according to query settings.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'static_position!' => '', + 'template_id!' => '', + ], + ] + ); + + $this->add_control( + 'alternate_templates', + [ + 'label' => esc_html__( 'Templates', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'title_field' => 'Alternate Template', + 'condition' => [ + 'alternate_template' => 'yes', + 'posts_per_page!' => 1, + 'template_id!' => '', + ], + 'default' => [ + [ + 'template_id' => null, + ], + ], + ] + ); + + // Location for the Edit handle. + $this->add_control( + 'edit_handle_selector', + [ + 'label' => esc_html__( 'Edit Handle Selector', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => '[data-elementor-type="loop-item"]', + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->end_injection(); + } + + protected function register_additional_options_section_controls() { + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + 'condition' => [ + 'template_id!' => '', + ], + ] + ); + + $this->add_control( + 'enable_nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'description' => esc_html__( 'Note: This message will appear when no content is loaded in the grid.', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'nothing_found_message_text', + [ + 'type' => Controls_Manager::TEXTAREA, + 'ai' => [ + 'type' => 'text', + ], + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'enable_nothing_found_message' => 'yes', + ], + 'default' => esc_html__( 'It seems we can’t find what you’re looking for.', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-loop-nothing-found-message-align: {{VALUE}};', + ], + 'condition' => [ + 'enable_nothing_found_message' => 'yes', + ], + 'render_type' => 'ui', + ] + ); + + $this->add_control( + 'nothing_found_message_html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'div', + 'condition' => [ + 'enable_nothing_found_message' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_design_layout_controls() { + $this->start_controls_section( + 'section_design_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'column_gap', + [ + 'label' => esc_html__( 'Gap between columns', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'row_gap', + [ + 'label' => esc_html__( 'Gap between rows', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_design_nothing_found_message_controls() { + $this->start_controls_section( + 'section_nothing_found_message_design', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'template_id!' => '', + 'enable_nothing_found_message' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_space_from_top', + [ + 'label' => esc_html__( 'Space from top', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-loop-nothing-found-message-space-from-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_space_from_bottom', + [ + 'label' => esc_html__( 'Space from bottom', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-loop-nothing-found-message-space-from-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'nothing_found_message_typography', + 'selector' => '{{WRAPPER}} .e-loop-nothing-found-message__text', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'nothing_found_message_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-loop-nothing-found-message-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'nothing_found_message_text_shadow', + 'selector' => '{{WRAPPER}} .e-loop-nothing-found-message__text', + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'nothing_found_message_text_stroke', + 'selector' => '{{WRAPPER}} .e-loop-nothing-found-message__text', + ] + ); + + $this->end_controls_section(); + } + + public static function on_import_update_dynamic_content( array $element_config, array $data, $controls = null ) : array { + if ( isset( $element_config['settings']['template_id'] ) && isset( $data['post_ids'] ) ) { + $element_config['settings']['template_id'] = $data['post_ids'][ $element_config['settings']['template_id'] ]; + } + + return $element_config; + } +} diff --git a/modules/loop-filter/data/controller.php b/modules/loop-filter/data/controller.php new file mode 100644 index 00000000..fa800a14 --- /dev/null +++ b/modules/loop-filter/data/controller.php @@ -0,0 +1,19 @@ +register_endpoint( Endpoints\Get_Post_Type_Taxonomies::class ); + $this->register_endpoint( Endpoints\Refresh_Loop::class ); + } +} diff --git a/modules/loop-filter/data/endpoints/get-post-type-taxonomies.php b/modules/loop-filter/data/endpoints/get-post-type-taxonomies.php new file mode 100644 index 00000000..b846a689 --- /dev/null +++ b/modules/loop-filter/data/endpoints/get-post-type-taxonomies.php @@ -0,0 +1,58 @@ +get_params(); + + return $this->get_taxonomy_options( [ $data['post_type'] ] ); + } + + protected function register() { + register_rest_route( $this->controller->get_namespace(), $this->get_route(), [ + [ + 'args' => [ + 'post_type' => [ + 'description' => 'The post type for which to fetch the list of taxonomies.', + 'type' => 'string', + 'required' => true, + 'validate_callback' => function ( $param ) { + return ! empty( $param ) && is_string( $param ); + }, + ], + ], + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => function ( $request ) { + return $this->permission_callback( $request ); + }, + ], + ] ); + } +} diff --git a/modules/loop-filter/data/endpoints/refresh-loop.php b/modules/loop-filter/data/endpoints/refresh-loop.php new file mode 100644 index 00000000..5950598b --- /dev/null +++ b/modules/loop-filter/data/endpoints/refresh-loop.php @@ -0,0 +1,119 @@ +get_params(); + + /** @var Module $loop_filter */ + $loop_filter = Plugin::instance()->modules_manager->get_modules( 'loop-filter' ); + + $loop_filter->register_widget_filter( $data['widget_id'], $data['widget_filters'] ); + + if ( $this->is_edit_mode( $data['post_id'] ) ) { + $widget_instance = Plugin::elementor()->elements_manager->create_element_instance( $data['widget_model'] ); + } else { + $widget_instance = $this->create_widget_instance_from_db( $data['post_id'], $data['widget_id'] ); + } + + set_query_var( 'pagination_base_url', $data['pagination_base_url'] ); + + ob_start(); + + /** @var Module $loop_filter */ + $loop_filter = Plugin::instance()->modules_manager->get_modules( 'loop-filter' ); + + add_filter( 'elementor/query/query_args', [ $loop_filter, 'filter_loop_query' ], 10, 2 ); + + /** @var Widget_Base $widget_instance */ + $widget_instance->render_content(); + + remove_filter( 'elementor/query/query_args', [ $loop_filter, 'filter_loop_query' ] ); + + $markup = ob_get_clean(); + + set_query_var( 'pagination_base_url', null ); + + return [ + 'data' => $markup, + ]; + } + + protected function register() { + register_rest_route( $this->controller->get_namespace(), $this->get_route(), [ + [ + 'args' => [ + 'post_id' => [ + 'description' => 'The post ID of the page containing the loop.', + 'type' => 'integer', + 'required' => true, + 'validate_callback' => function ( $param ) { + return ! empty( $param ) && is_numeric( $param ); + }, + ], + 'widget_id' => [ + 'description' => 'The ID of the loop widget.', + 'type' => 'string', + 'required' => true, + 'validate_callback' => function ( $param ) { + return $this->is_widget_id_valid( $param ); + }, + ], + 'widget_filters' => [ + 'description' => 'The filters for the loop widget.', + 'type' => 'object', + 'required' => true, + 'validate_callback' => function( $param ) { + // TODO: Build a validator for this that iterates over all passed filters and validates them. + return is_array( $param ); + }, + ], + 'widget_model' => [ + 'description' => 'The model of the loop widget. In Editor mode only.', + 'type' => 'object', + 'required' => false, + 'validate_callback' => function ( $param, $request ) { + $params = $request->get_params(); + + if ( ! $this->is_edit_mode( $params['post_id'] ) ) { + return false; + } + + return $this->is_widget_model_valid( $param ); + }, + ], + 'pagination_base_url' => [ + 'required' => false, + 'validate_callback' => function ( $param ) { + return filter_var( $param, FILTER_VALIDATE_URL ); + }, + 'sanitize_callback' => 'esc_url_raw', + ], + ], + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_updated_loop_widget_markup' ], + 'permission_callback' => function ( $request ) { + return $this->permission_callback( $request, 'loop-grid' ); + }, + ], + ] ); + } +} diff --git a/modules/loop-filter/module.php b/modules/loop-filter/module.php new file mode 100644 index 00000000..9a0970b6 --- /dev/null +++ b/modules/loop-filter/module.php @@ -0,0 +1,413 @@ +get_css_assets_url( 'widget-loop-filter', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + public function get_post_type_taxonomies( $data ) { + if ( ! current_user_can( 'edit_posts' ) || empty( $data['post_type'] ) ) { + return []; + } + + $post_type_taxonomies = get_object_taxonomies( $data['post_type'], 'objects' ); + + $control_options = []; + + foreach ( $post_type_taxonomies as $taxonomy ) { + $control_options[ $taxonomy->name ] = $taxonomy->label; + } + + return $control_options; + } + + public function register_widget_filter( $widget_id, $filter_data ) { + if ( empty( $this->filters[ $widget_id ] ) ) { + $this->filters[ $widget_id ] = $filter_data; + return; + } + + foreach ( $filter_data as $filter_type => $filter ) { + if ( empty( $this->filters[ $widget_id ][ $filter_type ] ) ) { + $this->filters[ $widget_id ][ $filter_type ] = $filter; + continue; + } + + $this->filters[ $widget_id ][ $filter_type ] = array_merge( $this->filters[ $widget_id ][ $filter_type ], $filter ); + } + } + + public function filter_loop_query( $query_args, $widget ) { + $widget_id = $widget->get_id(); + + if ( empty( $this->filters[ $widget_id ] ) ) { + return $query_args; + } + + /** @var array $filter_types An array containing all of a widget's different filters - e.g. taxonomy, price, rating... */ + $filter_types = $this->filters[ $widget_id ]; + + // TODO: This part is non-generic and should be refactored to allow for multiple types of filters. + $query_args['tax_query']['relation'] = $this->query['AND']['relation']; + + foreach ( $filter_types as $filters ) { + // The $filters array contains all filters of a specific type. For example, for the taxonomy filter type, + // it would contain all taxonomies to be filtered - e.g. 'category', 'tag', 'product-cat', etc. + $tax_query = []; + + foreach ( $filters as $filter_taxonomy => $filter ) { + if ( 'logicalJoin' === $filter_taxonomy ) { + continue; + } + + if ( $this->is_filter_empty( $filter ) ) { + continue; + } + + // Sanitize request data. + $taxonomy = sanitize_key( $filter_taxonomy ); + ( new Taxonomy_Query_Builder() )->get_merged_queries( $tax_query, $taxonomy, $filter ); + } + } + + $query_args['tax_query'] = array_merge( $query_args['tax_query'], $tax_query ?? [] ); + + return $query_args; + } + + /** + * @description Check if the filter is empty. + * Taxonomy Filter URL parameter is empty but not removed i.e. `&e-filter-389c132-product_cat=`. + * This edge case happens if a user clears terms and not the Taxonomy filter parameter + * @param $filter + * @return bool + */ + public function is_filter_empty( $filter ) { + if ( '' === $filter['terms'][0] ) { + return true; + } + return false; + } + + public function add_localize_data( $config ) { + $current_query_vars = $this->get_current_query_vars(); + + $config['loopFilter'] = [ + 'mainQueryPostType' => $current_query_vars['post_type'] ?? 'post', + 'nonce' => wp_create_nonce( 'wp_rest' ), + ]; + + return $config; + } + + private function get_current_query_vars() { + $current_query_vars = $GLOBALS['wp_query']->query_vars; + + /** + * Current query variables. + * + * Filters the query variables for the current query. This hook allows + * developers to alter those variables. + * + * @param array $current_query_vars Current query variables. + */ + return apply_filters( 'elementor/query/get_query_args/current_query', $current_query_vars ); + } + + private function parse_query_string( $param_key ) { + // Check if the query param is a filter. match a regex for `e-filter-14f9e1d-post_tag` where `14f9e1d` is the widget ID and must be 7 characters long and have only letters and numbers, then followed by a string that can only have letters, numbers, dashes and underscores. + if ( ! preg_match( '/^e-filter-[a-z0-9]{7}-[a-z0-9_\-]+$/', $param_key ) ) { + return []; + } + + // Remove the 'filter_' prefix from the query param + $filter = str_replace( 'e-filter-', '', $param_key ); + + // Split the filter into an array of widget ID and filter type + $filter = explode( '-', $filter ); + + if ( count( $filter ) !== 2 ) { + return []; + } + + // Get the widget ID + $widget_id = $filter[0]; + + // Get the taxonomy + $taxonomy = $filter[1]; + + return [ + 'taxonomy' => $taxonomy, + 'widget_id' => $widget_id, + ]; + } + + private function maybe_populate_filters_from_query_string() { + if ( ! isset( $_SERVER['QUERY_STRING'] ) ) { + return; + } + + $query_params = []; + wp_parse_str( htmlspecialchars_decode( Utils::_unstable_get_super_global_value( $_SERVER, 'QUERY_STRING' ) ), $query_params ); + + foreach ( $query_params as $param_key => $param_value ) { + // TODO: This part is not generic - it only supports taxonomy filters. It should be refactored to allow for multiple types of filters. + $parsed_query_string = $this->parse_query_string( $param_key ); + + if ( empty( $parsed_query_string ) || empty( $parsed_query_string['taxonomy'] ) || empty( $parsed_query_string['widget_id'] ) ) { + continue; + } + + $terms = $this->get_terms_array_from_params( $param_value ); + $logical_join = $this->get_logical_join_from_params( $param_value ); + + if ( empty( $terms ) ) { + continue; + } + + $filter_data = [ + 'taxonomy' => [ + $parsed_query_string['taxonomy'] => [ + 'terms' => $terms, + 'logicalJoin' => $logical_join, + ], + ], + ]; + + $this->register_widget_filter( $parsed_query_string['widget_id'], $filter_data ); + } + } + + private function get_seperator_from_params( $param_value ) { + $separator = $this->query['AND']['separator']['from-browser']; // The web browser automatically replaces the plus sign with a space character before sending the data to the server. + + if ( strstr( $param_value, $this->query['OR']['separator']['from-browser'] ) ) { + $separator = $this->query['OR']['separator']['from-browser']; + $this->operator = $this->query['OR']['operator']; + } + return $separator; + } + + private function get_terms_array_from_params( $param_value ) { + $separator = $this->get_seperator_from_params( $param_value ); + return explode( $separator, $param_value ); + } + + private function get_logical_join_from_params( $param_value ) { + $separator = $this->get_seperator_from_params( $param_value ); + + foreach ( $this->query as $index => $data ) { + if ( $data['separator']['decoded'] === $separator ) { + return $index; // Return the index when the decoded separator is found + } + } + + return 'AND'; // Default logical join + } + + /** + * @return array + */ + public function get_query_string_filters() { + return $this->filters; + } + + public function remove_rest_route_parameter( $link ) { + return remove_query_arg( 'rest_route', $link ); + } + + /** + * @return boolean + */ + public function is_term_not_selected_for_inclusion( $loop_widget_settings, $term, $skin ) { + if ( ! $this->is_loop_grid_include_exclude_tax_belong_to_filter_tax( $loop_widget_settings, $term, $skin ) ) { + return false; + } + + return ! empty( $loop_widget_settings[ $skin . '_query_include' ] ) && + in_array( 'terms', $loop_widget_settings[ $skin . '_query_include' ] ) && + isset( $loop_widget_settings[ $skin . '_query_include_term_ids' ] ) && + ! in_array( $term->term_id, $loop_widget_settings[ $skin . '_query_include_term_ids' ] ); + } + + public function is_loop_grid_include_exclude_tax_belong_to_filter_tax( array $loop_widget_settings, WP_Term $term, string $skin ) : bool { + $include_exclude_term_ids = array_merge( + $loop_widget_settings[ $skin . '_query_include_term_ids' ] ?? [], + $loop_widget_settings[ $skin . '_query_exclude_term_ids' ] ?? [] + ); + + foreach ( $include_exclude_term_ids as $term_id ) { + $term_to_include_exclude = get_term_by( 'term_taxonomy_id', $term_id ); + + if ( $term_to_include_exclude && $term_to_include_exclude->taxonomy === $term->taxonomy ) { + return true; + } + } + + return false; + } + + /** + * @return boolean + */ + public function is_term_selected_for_exclusion( $loop_widget_settings, $term, $skin ) { + return ! empty( $loop_widget_settings[ $skin . '_query_exclude' ] ) && + in_array( 'terms', $loop_widget_settings[ $skin . '_query_exclude' ] ) && + isset( $loop_widget_settings[ $skin . '_query_exclude_term_ids' ] ) && + in_array( $term->term_id, $loop_widget_settings[ $skin . '_query_exclude_term_ids' ] ); + } + + /** + * @return boolean + */ + public function should_exclude_term_by_manual_selection( $loop_widget_settings, $term, $user_selected_taxonomy, $skin ) { + if ( ! $this->loop_widget_has_manual_selection( $loop_widget_settings, $skin ) ) { + return false; + } + + $terms_to_exclude_by_manual_selection = $this->get_terms_to_exclude_by_manual_selection( $loop_widget_settings[ $skin . '_query_exclude_ids' ] ?? [], $user_selected_taxonomy ); + + if ( in_array( $term->term_id, $terms_to_exclude_by_manual_selection ) ) { + return true; + } + + return false; + } + + /** + * @return boolean + */ + private function loop_widget_has_manual_selection( $loop_widget_settings, $skin ) { + return ! empty( $loop_widget_settings[ $skin . '_query_exclude' ] ) && + in_array( 'manual_selection', $loop_widget_settings[ $skin . '_query_exclude' ] ) && + ! empty( $loop_widget_settings[ $skin . '_query_exclude_ids' ] ); + } + + /** + * @return array + */ + private function get_terms_to_exclude_by_manual_selection( $selected_posts, $user_selected_taxonomy ) { + $terms_to_exclude = []; + $term_exclude_counts = []; + $term_actual_counts = []; + + foreach ( $selected_posts as $post_id ) { + $this->calculate_post_terms_counts( $post_id, $user_selected_taxonomy, $term_exclude_counts, $term_actual_counts ); + } + + foreach ( $term_exclude_counts as $term_id => $selected_count ) { + $this->maybe_add_term_to_exclusion( $term_id, $selected_count, $term_actual_counts, $terms_to_exclude ); + } + + return $terms_to_exclude; + } + + /** + * @return void + */ + private function calculate_post_terms_counts( $post_id, $user_selected_taxonomy, &$term_exclude_counts, &$term_actual_counts ) { + $post_terms = wp_get_post_terms( $post_id, $user_selected_taxonomy ); + + foreach ( $post_terms as $term ) { + $this->calculate_term_counts( $term, $term_exclude_counts, $term_actual_counts ); + } + } + + /** + * @return void + */ + private function calculate_term_counts( $term, &$term_exclude_counts, &$term_actual_counts ) { + if ( empty( $term_exclude_counts[ $term->term_id ] ) ) { + $term_exclude_counts[ $term->term_id ] = 0; + } + + $term_exclude_counts[ $term->term_id ] = (int) $term_exclude_counts[ $term->term_id ] + 1; + $term_actual_counts[ $term->term_id ] = (int) $term->count; + } + + /** + * @return void + */ + private function maybe_add_term_to_exclusion( $term_id, $selected_count, $term_actual_counts, &$terms_to_exclude ) { + $user_selected_all_the_posts_for_this_term = $selected_count >= $term_actual_counts[ $term_id ]; + + if ( $user_selected_all_the_posts_for_this_term ) { + $terms_to_exclude[] = $term_id; + } + } + + public function __construct() { + parent::__construct(); + + $this->query = Query_Constants::DATA; + + if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { + $this->maybe_populate_filters_from_query_string(); + } + + // Register the controller. + new Controller(); + + add_filter( 'elementor/query/query_args', [ $this, 'filter_loop_query' ], 10, 2 ); + + add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_localize_data' ] ); + + add_filter( 'paginate_links', [ $this, 'remove_rest_route_parameter' ] ); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + } +} diff --git a/modules/loop-filter/query/data/query-constants.php b/modules/loop-filter/query/data/query-constants.php new file mode 100644 index 00000000..652e68b6 --- /dev/null +++ b/modules/loop-filter/query/data/query-constants.php @@ -0,0 +1,44 @@ + [ + 'separator' => [ + 'decoded' => '+', + 'from-browser' => ' ', + 'encoded' => '%2B', + ], + 'operator' => 'AND', + 'relation' => 'AND', + ], + 'OR' => [ + 'separator' => [ + 'decoded' => '~', + 'from-browser' => '~', + 'encoded' => '%7C', + ], + 'operator' => 'IN', + 'relation' => 'OR', + ], + 'NOT' => [ + 'separator' => [ + 'decoded' => '!', + 'from-browser' => '!', + 'encoded' => '%21', + ], + 'operator' => 'NOT IN', + 'relation' => 'AND', + ], + 'DISABLED' => [ + 'separator' => [ + 'decoded' => '', + 'from-browser' => '', + 'encoded' => '', + ], + 'operator' => 'AND', + 'relation' => 'AND', + ], + ]; +} diff --git a/modules/loop-filter/query/interfaces/query-interface.php b/modules/loop-filter/query/interfaces/query-interface.php new file mode 100644 index 00000000..a2a7cd67 --- /dev/null +++ b/modules/loop-filter/query/interfaces/query-interface.php @@ -0,0 +1,10 @@ +query = Query_Constants::DATA; + $this->taxonomy_manager = $taxonomy_manager; + $this->terms = $filter_terms['hierarchical-terms'] ?? []; + $this->taxonomy = $filter_terms['taxonomy']; + $this->logical_join = $filter_terms['logicalJoin']; + } + + /** + * @return array + */ + public function get_query() { + $query = []; + + if ( empty( $this->terms ) ) { + return $query; + } + + foreach ( $this->terms as $parent_term => $terms ) { + $filtered_terms = $this->filter_query_terms( $parent_term, $terms ); + $query[] = $this->get_hierarchy_query( $filtered_terms ); + } + + return $query; + } + + /** + * @param $parent_term + * @param $terms + * @return array + */ + private function filter_query_terms( $parent_term, $terms ) { + $query_terms = []; + $filters_on_parent_term = in_array( $parent_term, $terms ); + $filters_on_parent_and_child_terms = count( $terms ) > 1 && $filters_on_parent_term; + $is_parent_term_only = $filters_on_parent_term && ! $filters_on_parent_and_child_terms; + $has_child_terms_only = ! $filters_on_parent_term; + + // For an AND Queries exclude parent term if there are child and parent terms. + if ( $filters_on_parent_and_child_terms ) { + $query_terms = array_diff( $terms, [ $parent_term ] ); //drop parent term + } + + if ( $is_parent_term_only || $has_child_terms_only ) { + $query_terms = $terms; + } + + return $query_terms; + } + + + /** + * Create the Inner query for AND OR queries with one or more filter terms targeted at the same Widget. + * @param array $terms + * @return array + */ + private function get_hierarchy_query( $terms ) { + $inner_query = [ + 'taxonomy' => $this->taxonomy, + 'field' => 'slug', + 'terms' => [], + 'operator' => $this->query['OR']['operator'], + ]; + + foreach ( $terms as $term ) { + if ( 1 < count( $terms ) && $this->taxonomy_manager->is_parent_term_with_children( $term, $this->taxonomy ) ) { + $parent_query = $this->get_hierarchy_query( [ $term ] ); + continue; + } + + $inner_query['terms'] = [ urldecode( sanitize_title( $term ?? '' ) ) ]; //decode non-latin strings + $child_queries[] = $inner_query; + } + + $hierarchy_query = array_merge( $parent_query ?? [], $child_queries ?? [] ); + $hierarchy_query['relation'] = $this->query['OR']['relation']; //broaden search results when two child terms are selected. And relation between unrelated terms. + return $hierarchy_query; + } +} diff --git a/modules/loop-filter/query/query-types/hierarchy-or-query.php b/modules/loop-filter/query/query-types/hierarchy-or-query.php new file mode 100644 index 00000000..5c1285d8 --- /dev/null +++ b/modules/loop-filter/query/query-types/hierarchy-or-query.php @@ -0,0 +1,90 @@ +query = Query_Constants::DATA; + $this->terms = $filter_terms['hierarchical-terms'] ?? []; + $this->taxonomy = $filter_terms['taxonomy']; + $this->logical_join = $filter_terms['logicalJoin']; + } + + /** + * @return array + */ + public function get_query() { + $query = []; + + if ( empty( $this->terms ) ) { + return $query; + } + + foreach ( $this->terms as $parent_term => $terms ) { + $filtered_terms = $this->filter_query_terms( $parent_term, $terms ); + $query[] = $this->get_hierarchy_query( $filtered_terms ); + } + + return $query; + } + + /** + * @description + * @param $parent_term + * @param $terms + * @return array + */ + private function filter_query_terms( $parent_term, $terms ) { + $query_terms = []; + $filters_on_parent_term = in_array( $parent_term, $terms ); + $filters_on_parent_and_child_terms = count( $terms ) > 1 && $filters_on_parent_term; + $is_parent_term_only = $filters_on_parent_term && ! $filters_on_parent_and_child_terms; + $has_child_terms_only = ! $filters_on_parent_term; + + // For an OR Queries exclude child terms if there is a parent term in the terms. + if ( $filters_on_parent_and_child_terms ) { + $query_terms = [ $parent_term ]; // drop child terms + } + + if ( $is_parent_term_only || $has_child_terms_only ) { + $query_terms = $terms; + } + + return $query_terms; + } + + /** + * Create the Inner query for AND OR queries with one or more filter terms targeted at the same Widget. + * @param array $terms + * @return array + */ + private function get_hierarchy_query( $terms ) { + $inner_query = [ + 'taxonomy' => $this->taxonomy, + 'field' => 'slug', + 'terms' => [], + 'operator' => $this->query['OR']['operator'], + ]; + + foreach ( $terms as $term ) { + if ( 1 < count( $terms ) && $this->taxonomy_manager->is_parent_term_with_children( $term, $this->taxonomy ) ) { + $parent_query = $this->get_hierarchy_query( [ $term ] ); + continue; + } + + $inner_query['terms'] = [ urldecode( sanitize_title( $term ?? '' ) ) ]; //decode non-latin strings + $child_queries[] = $inner_query; + } + + $hierarchy_query = array_merge( $parent_query ?? [], $child_queries ?? [] ); + $hierarchy_query['relation'] = $this->query['OR']['relation']; //broaden search results when two child terms are selected. And relation between unrelated terms. + return $hierarchy_query; + } +} diff --git a/modules/loop-filter/query/query-types/single-terms-query.php b/modules/loop-filter/query/query-types/single-terms-query.php new file mode 100644 index 00000000..d4b36fc0 --- /dev/null +++ b/modules/loop-filter/query/query-types/single-terms-query.php @@ -0,0 +1,88 @@ +query = Query_Constants::DATA; + $this->taxonomy_manager = $taxonomy_manager; + $this->set_single_or_multiple_selection_terms( $filter_terms ); + $this->taxonomy = $filter_terms['taxonomy'] ?? []; + $this->logical_join = $filter_terms['logicalJoin']; + } + + /** + * Create the Inner query for AND OR queries with one or more filter terms targeted at the same Widget using terms with no parent and no children + * @return array + */ + public function get_query() { + if ( empty( $this->terms ) ) { + return []; + } + + $query = [ + [ + 'taxonomy' => $this->taxonomy, + 'field' => 'slug', + 'terms' => [], + 'operator' => $this->get_inner_query_operator(), + ], + ]; + + foreach ( $this->terms as $term ) { + $query[0]['terms'][] = urldecode( sanitize_title( $term ?? '' ) ); //decode non-latin strings + } + + return $query; + } + + /** + * @param $filter_terms + * @return void + */ + private function set_single_or_multiple_selection_terms( $filter_terms ) { + // Single Selection + if ( ! empty( $filter_terms['single-term'][0] ) ) { + $this->terms = $filter_terms['single-term']; + return; + } + + $this->terms = $filter_terms['parent-terms-without-children']; + + } + + /** + * @return string 'IN' / 'AND' (default) + */ + private function get_inner_query_operator() { + if ( $this->is_single_parent_term() ) { + return $this->query['OR']['operator']; // Allow showing posts from parent category when it's selected. + } + + if ( 'DISABLED' !== $this->logical_join ) { + return $this->query[ $this->logical_join ?? 'DISABLED' ]['operator']; + } + + return $this->query['AND']['operator']; + } + + /** + * @return boolean + */ + private function is_single_parent_term() { + if ( empty( $this->terms ?? [] ) ) { + return false; + } + + $is_parent_term = $this->taxonomy_manager->is_parent_term_with_children( $this->terms[0], $this->taxonomy ); + return 1 === count( $this->terms ?? [] ) && $is_parent_term; + } +} diff --git a/modules/loop-filter/query/taxonomy-manager.php b/modules/loop-filter/query/taxonomy-manager.php new file mode 100644 index 00000000..7aa120df --- /dev/null +++ b/modules/loop-filter/query/taxonomy-manager.php @@ -0,0 +1,260 @@ + $taxonomy, + 'hide_empty' => true, + ]; + + $terms = get_terms( $args ); + + if ( is_wp_error( $terms ) ) { + return; + } + + $this->get_terms_by_slug_and_id( $terms ); + $this->terms_hierarchy = $this->filter_child_terms_by_depth( $terms, 100 ); + } + + private function get_term_id( $slug, $taxonomy ) { + if ( ! isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) ) { + return -1; + } + return $this->terms_by_slug[ $taxonomy ][ $slug ]['term_id']; + } + + /** + * Check if a term is a parent term. + * @param string $slug + * @param string $taxonomy + * @return bool; + */ + public function is_parent_term_without_children( $slug, $taxonomy ) { + // Empty terms do not exist in $terms_by_slug + $has_children = $this->has_children( $slug, $taxonomy ); + $is_top_level_parent_term = $this->is_top_level_parent_term( $slug, $taxonomy ); + return ( isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) && $is_top_level_parent_term && ! $has_children ); + } + + public function is_parent_term_with_children( $slug, $taxonomy ) { + // Empty terms do not exist in $terms_by_slug + return ( isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) && $this->has_children( $slug, $taxonomy ) ); + } + + private function has_children( $slug, $taxonomy ) { + $term_id = $this->get_term_id( $slug, $taxonomy ); + return isset( $this->terms_hierarchy[ $term_id ] ) && count( $this->terms_hierarchy[ $term_id ] ) > 0; + } + + private function get_children( $slug, $taxonomy ) { + $term_id = $this->get_term_id( $slug, $taxonomy ); + return $this->terms_hierarchy[ $term_id ]; + } + + private function is_child_term( $slug, $taxonomy ) { + return ( isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) && 0 !== $this->terms_by_slug[ $taxonomy ][ $slug ]['parent'] ); + } + + public function is_top_level_parent_term( $slug, $taxonomy ) { + return ( isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) && 0 === $this->terms_by_slug[ $taxonomy ][ $slug ]['parent'] ); + } + + private function get_parent( $slug, $taxonomy ) { + return $this->terms_by_slug[ $taxonomy ][ $slug ]['parent']; + } + + private function get_parent_id( $child_slug, $taxonomy ) { + if ( ! isset( $this->terms_by_slug[ $taxonomy ][ $child_slug ]['parent'] ) ) { + return -1; + } + + return $this->terms_by_slug[ $taxonomy ][ $child_slug ]['parent']; + } + + private function get_parent_slug( $child_slug, $taxonomy ) { + $parent_id = $this->get_parent_id( $child_slug, $taxonomy ); + + if ( -1 === $parent_id ) { + return 'UNDEFINED'; + } + + return $this->terms_by_id[ $taxonomy ][ $parent_id ]['slug']; + } + + /** + * @param array $filter_terms + * @param string $taxonomy + * @return array + */ + public function get_hierarchy_of_selected_terms( $filter_terms, $taxonomy ) { + // Taxonomy Filter parameter is empty i.e. `e-filter-389c132-product_cat=`. + if ( ! empty( $filter_terms['terms'] ) && '' === $filter_terms['terms'][0] ) { + return [ + 'single-term' => [], + 'parent-terms-without-children' => [], + 'hierarchical-terms' => [], + 'logicalJoin' => $filter_terms['logicalJoin'], + 'taxonomy' => $taxonomy, + ]; + } + + $parents_without_children = []; + $parents_with_children_by_parent = []; + $single_selection_term = []; + + if ( 1 === count( $filter_terms['terms'] ) ) { + $single_selection_term = $filter_terms['terms']; + } + + foreach ( $filter_terms['terms'] as $term ) { + + if ( ! empty( $single_selection_term ) ) { + break; + } + + $term = urldecode( sanitize_title( $term ) ); // decode non-latin slugs. + $is_parent_term_without_children = $this->is_parent_term_without_children( $term, $taxonomy ); + $is_parent_term_with_children = $this->is_parent_term_with_children( $term, $taxonomy ); + + if ( $is_parent_term_without_children ) { + $parents_without_children[] = $term; + continue; + } + + if ( $is_parent_term_with_children ) { + $parents_with_children_by_parent[ $term ][] = $term; + continue; + } + + $parent_slug = $this->get_parent_slug( $term, $taxonomy ); + if ( 'UNDEFINED' === $parent_slug ) { + continue; + } + $parents_with_children_by_parent[ $parent_slug ][] = $term; + } + + return [ + 'single-term' => $single_selection_term, + 'parent-terms-without-children' => $parents_without_children, + 'hierarchical-terms' => $parents_with_children_by_parent, + 'logicalJoin' => $filter_terms['logicalJoin'], + 'taxonomy' => $taxonomy, + ]; + } + + /** + * @param array $terms + * @return void + */ + private function get_terms_by_slug_and_id( $terms = [] ) { + $this->terms_by_slug = []; + foreach ( $terms as $term ) { + $slug = urldecode( $term->slug ); + + $this->try_set_terms_by_slug( $slug, $term ); + $this->try_set_terms_by_id( $slug, $term ); + } + } + + /** + * @param string $slug + * @param string $term + * @return void + */ + public function try_set_terms_by_slug( $slug, $term ) { + $term_id = $term->term_id; + $taxonomy = $term->taxonomy; + + if ( ! isset( $this->terms_by_slug[ $taxonomy ][ $slug ] ) ) { + $this->terms_by_slug[ $taxonomy ][ $slug ] = [ + 'term_id' => $term_id, + 'parent' => $term->parent, + 'count' => $term->count, + ]; + } + } + + /** + * @param string $slug + * @param string $term + * @return void + */ + public function try_set_terms_by_id( $slug, $term ) { + $term_id = $term->term_id; + $taxonomy = $term->taxonomy; + + if ( ! isset( $this->terms_by_id[ $taxonomy ][ $slug ] ) ) { + $this->terms_by_id[ $taxonomy ][ $term_id ] = [ + 'slug' => $slug, + 'parent' => $term->parent, + 'count' => $term->count, + ]; + } + } + + /** + * @param \WP_Term[] $terms + * @param int $target_depth + * @return \WP_Term[] + */ + private function filter_child_terms_by_depth( $terms, $target_depth ) { + $filtered = []; + + foreach ( $terms as $term ) { + $this->filter_single_term( $filtered, $terms, $term, $target_depth ); + } + + return $filtered; + } + + /** + * @param \WP_Term[] $terms + * @param \WP_Term $current_term + * @param int $target_depth + * @return void + */ + private function filter_single_term( &$result, $terms, $current_term, $target_depth ) { + if ( 0 === $current_term->parent ) { + $result[ $current_term->parent ][ $current_term->term_id ] = $current_term; + return; + } + + $item_depth = $this->calculate_depth_for_child_term_recursively( $terms, $current_term, 0 ); + + if ( $item_depth <= $target_depth ) { + $result[ $current_term->parent ][ $current_term->term_id ] = $current_term; + } + } + + /** + * @param \WP_Term[] $terms + * @param \WP_Term $child_term + * @param int $depth + * @return int|void + */ + private function calculate_depth_for_child_term_recursively( $terms, $child_term, $depth ) { + $depth++; + + foreach ( $terms as $term ) { + if ( $term->term_id !== $child_term->parent ) { + continue; + } + + if ( 0 === $term->parent ) { + return $depth; + } + return $this->calculate_depth_for_child_term_recursively( $terms, $term, $depth ); + } + } + +} diff --git a/modules/loop-filter/query/taxonomy-query-builder.php b/modules/loop-filter/query/taxonomy-query-builder.php new file mode 100644 index 00000000..959653e7 --- /dev/null +++ b/modules/loop-filter/query/taxonomy-query-builder.php @@ -0,0 +1,81 @@ +query = Query_Constants::DATA; + } + + public function get_merged_queries( &$tax_query, $taxonomy, $filter ) { + $this->tax_query = &$tax_query; + + // Taxonomy Filter parameter is empty i.e. `e-filter-389c132-product_cat=`. + if ( ! empty( $filter['terms'] ) && '' === $filter['terms'][0] ) { + return; + } + + $this->taxonomy_manager = new Taxonomy_Manager(); + $this->taxonomy_manager->get_taxonomy_terms( $taxonomy ); + $this->filter_terms = $this->taxonomy_manager->get_hierarchy_of_selected_terms( $filter, $taxonomy ); + + if ( ! empty( $this->filter_terms['single-term'] ) ) { + $this->get_single_selection_query( $tax_query ); + return; + } + + $this->get_multiple_selection_query( $tax_query ); + } + + private function get_single_selection_query( &$tax_query ) { + $this->single_terms_query = $this->get_query( new Single_Terms_Query( $this->filter_terms, $this->taxonomy_manager ) ); + $this->merge_single_selection_query( $tax_query ); + } + + private function get_multiple_selection_query( &$tax_query ) { + $this->single_terms_query = $this->get_query( new Single_Terms_Query( $this->filter_terms, $this->taxonomy_manager ) ); + + if ( 'AND' === $this->filter_terms['logicalJoin'] ) { + $this->hierarchy_query = $this->get_query( new Hierarchy_And_Query( $this->filter_terms, $this->taxonomy_manager ) ); + } + + if ( 'OR' === $this->filter_terms['logicalJoin'] ) { + $this->hierarchy_query = $this->get_query( new Hierarchy_Or_Query( $this->filter_terms, $this->taxonomy_manager ) ); + } + + $this->merge_multiple_selection_query( $tax_query ); + } + + private function merge_single_selection_query( &$tax_query ) { + if ( empty( $this->single_terms_query ?? [] ) ) { + return; + } + + $tax_query = array_merge( $tax_query, $this->single_terms_query ?? [] ); + } + + private function merge_multiple_selection_query( &$tax_query ) { + if ( empty( $this->single_terms_query ?? [] ) && empty( $this->hierarchy_query ?? [] ) ) { + return; + } + + $tax_query = [ array_merge( $tax_query, $this->single_terms_query ?? [], $this->hierarchy_query ?? [], [ 'relation' => $this->query[ $this->filter_terms['logicalJoin'] ]['relation'] ] ) ]; + } + + private function get_query( Query_Interface $query_type ) { + return $query_type->get_query(); + } +} diff --git a/modules/loop-filter/traits/hierarchical-taxonomy-trait.php b/modules/loop-filter/traits/hierarchical-taxonomy-trait.php new file mode 100644 index 00000000..a269a549 --- /dev/null +++ b/modules/loop-filter/traits/hierarchical-taxonomy-trait.php @@ -0,0 +1,80 @@ +filter_single_term( $filtered, $terms, $term, $target_depth ); + } + + return $filtered; + } + + /** + * @param \WP_Term[] $terms + * @param \WP_Term $current_term + * @param int $target_depth + * @return void + */ + private function filter_single_term( &$result, $terms, $current_term, $target_depth ) { + if ( 0 === $current_term->parent ) { + $result[ $current_term->parent ][] = $current_term; + return; + } + + $item_depth = $this->calculate_depth_for_child_term( $terms, $current_term, 0 ); + + if ( $item_depth <= $target_depth ) { + $result[ $current_term->parent ][] = $current_term; + } + } + + /** + * @param \WP_Term[] $terms + * @param \WP_Term $child_term + * @param int $depth + * @return int|void + */ + private function calculate_depth_for_child_term( $terms, $child_term, $depth ) { + $depth++; + + foreach ( $terms as $term ) { + if ( $term->term_id !== $child_term->parent ) { + continue; + } + + if ( 0 === $term->parent ) { + return $depth; + } + return $this->calculate_depth_for_child_term( $terms, $term, $depth ); + } + } + + + /** + * Transform terms hierarchy structure to plain [ parent_term_id => [ term, term ... ], ...] to [ term, term, ... ] + * + * @param array $taxonomy_plain_view + * @param array $hierarchy_terms + * @param int $parent_term_id + * @return void + */ + public function transform_taxonomy_hierarchy_to_plain( &$taxonomy_plain_view, $hierarchy_terms, $parent_term_id = 0 ) { + if ( empty( $hierarchy_terms[ $parent_term_id ] ) ) { + return; + } + + foreach ( $hierarchy_terms[ $parent_term_id ] as $term ) { + $taxonomy_plain_view[] = $term; + $this->transform_taxonomy_hierarchy_to_plain( $taxonomy_plain_view, $hierarchy_terms, $term->term_id ); + } + } +} diff --git a/modules/loop-filter/traits/taxonomy-filter-trait.php b/modules/loop-filter/traits/taxonomy-filter-trait.php new file mode 100644 index 00000000..0148e868 --- /dev/null +++ b/modules/loop-filter/traits/taxonomy-filter-trait.php @@ -0,0 +1,202 @@ +get_taxonomies_to_exclude( $post_type ) ); + } + + $control_options = []; + + foreach ( $post_type_taxonomies as $taxonomy ) { + if ( $this->should_exclude_taxonomy( $taxonomy->name, $taxonomies_to_exclude ) ) { + continue; + } + + $control_options[ $key_prefix . $taxonomy->name ] = $taxonomy->label; + } + + return $control_options; + } + + private function get_loop_widget_data( $document, $selected_element = null ) { + $elements_data = $document->get_elements_data(); + + return \Elementor\Utils::find_element_recursive( + $elements_data, + $selected_element, + ); + } + + private function get_loop_widget( $selected_element ) { + $post_id = Utils::get_current_post_id(); + + if ( ! $post_id ) { + return false; + } + + $document = Plugin::$instance->documents->get_doc_for_frontend( $post_id ); + $widget_data = $this->get_loop_widget_data( $document, $selected_element ); + + if ( ! $widget_data ) { + return false; + } + + return Plugin::$instance->elements_manager->create_element_instance( $widget_data ); + } + + /** + * Adjusts Elementor query arguments to prevent taxonomy filter conflicts. + * + * Resolves an issue where the taxonomy filter unintentionally affects itself + * when a Loop Grid widget is filtered by taxonomy. Without this adjustment, + * taxonomy terms added by the filter itself may be included in the query results, + * leading to unexpected behavior. + * + * This function ensures that only taxonomy terms specified via the query control + * (with the `term_taxonomy_id` field) are considered in the `tax_query`, + * excluding any others introduced by the filter. + * + * @param array $query_args The query arguments for the Elementor widget. + * @param object $widget The Elementor widget instance. + * @return array The modified query arguments. + */ + public function modify_elementor_query_args( $query_args, $widget ) { + global $wp_query; + + if ( isset( $query_args['tax_query'] ) && ! empty( $wp_query->include_field_ids_arg ) ) { + $query_args['tax_query'] = array_filter( + $query_args['tax_query'], + function( $tax ) { + return isset( $tax['field'] ) && 'term_taxonomy_id' === $tax['field']; + } + ); + } + + return $query_args; + } + + private function get_elementor_post_query( $loop_widget ): WP_Query { + global $wp_query; + + $wp_query->include_field_ids_arg = true; + $query_args = [ + 'posts_per_page' => -1, + 'fields' => 'ids', + ]; + + add_filter( 'elementor/query/query_args', [ $this, 'modify_elementor_query_args' ], 15, 2 ); + + $query = QueryControl::instance()->get_query_ignoring_avoid_list( $loop_widget, $loop_widget->get_query_name(), $query_args ); + + remove_filter( 'elementor/query/query_args', [ $this, 'modify_elementor_query_args' ] ); + + unset( $wp_query->include_field_ids_arg ); + + return $query; + } + + /** + * @param array $settings + * @return bool + */ + public function should_exclude_child_taxonomies( array $settings ): bool { + return ! isset( $settings['show_child_taxonomy'] ) || 'yes' !== $settings['show_child_taxonomy']; + } + + public function should_hide_empty_items( array $settings ): bool { + return 'yes' !== $settings['show_empty_items']; + } + + private function maybe_add_filtered_post_ids_to_args( array $args, $loop_widget, array $settings ): array { + if ( $loop_widget && $this->should_hide_empty_items( $settings ) ) { + $post_query = $this->get_elementor_post_query( $loop_widget ); + $post_ids = $post_query->posts; + + $args['object_ids'] = $post_ids; + } + + return $args; + } + /** + * @param array $settings + * @param array $display_settings + * @return void|\WP_Term[] + */ + public function get_filtered_taxonomies( $settings, $display_settings ) { + $args = [ + 'taxonomy' => $settings['taxonomy'], + 'hide_empty' => $this->should_hide_empty_items( $settings ), + ]; + $avoid_reset_parent = ! empty( $settings['avoid_reset_parent'] ); + + if ( $this->should_exclude_child_taxonomies( $settings ) && ! $avoid_reset_parent ) { + $args['parent'] = 0; + } + + if ( isset( $settings['selected_element'] ) && ! wp_doing_ajax() ) { + $loop_widget = $this->get_loop_widget( $settings['selected_element'] ); + $args = $this->maybe_add_filtered_post_ids_to_args( $args, $loop_widget, $settings ); + } + + $args = apply_filters( + 'elementor/loop_taxonomy/args', + $this->get_additional_allowed_args( $args, $display_settings ), + $settings, + $display_settings, + ); + + $terms = get_terms( $args ); + + if ( is_wp_error( $terms ) ) { + return; + } + + if ( isset( $settings['show_child_taxonomy'] ) && 'yes' === $settings['show_child_taxonomy'] && isset( $display_settings['child_taxonomy_depth'] ) ) { + $taxonomy_plain_view = []; + $hierarchy_terms = $this->filter_child_terms_by_depth( $terms, $display_settings['child_taxonomy_depth'] ); + $this->transform_taxonomy_hierarchy_to_plain( $taxonomy_plain_view, $hierarchy_terms ); + $terms = ! empty( $taxonomy_plain_view ) ? $taxonomy_plain_view : $terms; + } + + return $terms; + } + + private function get_additional_allowed_args( $args, $display_settings ) { + $allowed_args = [ 'include', 'exclude', 'term_taxonomy_id', 'child_taxonomy_depth', 'hierarchical', 'child_of', 'offset', 'orderby', 'order', 'number' ]; + + foreach ( $allowed_args as $arg ) { + if ( isset( $display_settings[ $arg ] ) ) { + $args[ $arg ] = $display_settings[ $arg ]; + } + } + + return $args; + } + + private function get_taxonomies_to_exclude( $post_type ) { + $excluded_taxonomies_per_post_type = [ + 'post' => [ 'post_format' ], + 'product' => [ 'product_type', 'product_visibility', 'product_shipping_class', 'pa_color', 'pa_size' ], + ]; + + return $excluded_taxonomies_per_post_type[ $post_type ] ?? []; + } + + private function should_exclude_taxonomy( $taxonomy_name, $taxonomies_to_exclude ) { + return ! empty( $taxonomies_to_exclude ) && in_array( $taxonomy_name, $taxonomies_to_exclude ); + } +} diff --git a/modules/loop-filter/widgets/taxonomy-filter.php b/modules/loop-filter/widgets/taxonomy-filter.php new file mode 100644 index 00000000..21cd9ff9 --- /dev/null +++ b/modules/loop-filter/widgets/taxonomy-filter.php @@ -0,0 +1,828 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + $this->start_controls_section( + 'section_taxonomy_filter', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'selected_element', + [ + 'label' => esc_html__( 'Selected loop grid', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Select a widget', 'elementor-pro' ), + ], + 'label_block' => true, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'taxonomy', + [ + 'label' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Select a taxonomy', 'elementor-pro' ), + ], + 'label_block' => true, + 'condition' => [ + 'selected_element!' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'direction', + [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'vertical' => esc_html__( 'Vertical', 'elementor-pro' ), + ], + 'default' => 'horizontal', + 'selectors_dictionary' => [ + 'horizontal' => '--e-filter-direction: row;--e-filter-white-space: nowrap;', + 'vertical' => '--e-filter-direction: column;--e-filter-white-space: initial;', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'condition' => [ + 'selected_element!' => '', + ], + 'control_type' => 'content', + ] + ); + + $this->add_responsive_control( + 'item_alignment_horizontal', + [ + 'label' => esc_html__( 'Item Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-align-start-h', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-align-end-h', + ], + 'stretch' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-align-stretch-h', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'start' => '--e-filter-justify-content: flex-start; --e-filter-item-width: initial; --e-filter-item-flex-grow: 0;', + 'center' => '--e-filter-justify-content: center; --e-filter-item-width: initial; --e-filter-item-flex-grow: 0;', + 'end' => '--e-filter-justify-content: flex-end; --e-filter-item-width: initial; --e-filter-item-flex-grow: 0;', + 'stretch' => '--e-filter-justify-content: initial; --e-filter-item-width: 100%; --e-filter-item-flex-grow: 1;', + ], + 'condition' => [ + 'direction' => 'horizontal', + 'selected_element!' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'title_alignment_horizontal', + [ + 'label' => esc_html__( 'Title Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-align-start-h', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-align-end-h', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'start' => '--e-filter-item-justify-content: flex-start;', + 'center' => '--e-filter-item-justify-content: center;', + 'end' => '--e-filter-item-justify-content: flex-end;', + ], + 'condition' => [ + 'direction' => 'horizontal', + 'selected_element!' => '', + 'item_alignment_horizontal' => 'stretch', + ], + ] + ); + + $this->add_responsive_control( + 'item_alignment_vertical', + [ + 'label' => esc_html__( 'Item Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-align-start-h', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-align-end-h', + ], + 'stretch' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-align-stretch-h', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'start' => '--e-filter-align-items: flex-start; --e-filter-item-width: initial; --e-filter-item-max-width: calc(100% - calc(var( --e-filter-item-padding )*3 ) ); --e-filter-item-flex-grow: initial; --e-filter-item-box-sizing: initial; --e-filter-item-align-text: start;', + 'center' => '--e-filter-align-items: center; --e-filter-item-width: initial; --e-filter-item-max-width: calc(100% - calc(var( --e-filter-item-padding )*3 ) ); --e-filter-item-flex-grow: initial; --e-filter-item-box-sizing: initial; --e-filter-item-align-text: center;', + 'end' => '--e-filter-align-items: flex-end; --e-filter-item-width: initial; --e-filter-item-max-width: calc(100% - calc(var( --e-filter-item-padding )*3 ) ); --e-filter-item-flex-grow: initial; --e-filter-item-box-sizing: initial; --e-filter-item-align-text: end;', + 'stretch' => '--e-filter-align-items: center; --e-filter-item-width: 100%; --e-filter-item-max-width: 100%; --e-filter-item-flex-grow: 1; --e-filter-item-box-sizing: border-box; --e-filter-item-align-text: center;', + ], + 'condition' => [ + 'direction' => 'vertical', + 'selected_element!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'title_alignment_vertical', + [ + 'label' => esc_html__( 'Title Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-align-start-h', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-align-end-h', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'start' => '--e-filter-item-justify-content: flex-start; --e-filter-item-align-items: flex-start; --e-filter-item-align-text: start;', + 'center' => '--e-filter-item-justify-content: center; --e-filter-item-align-items: center; --e-filter-item-align-text: center;', + 'end' => '--e-filter-item-justify-content: flex-end; --e-filter-item-align-items: flex-end; --e-filter-item-align-text: end;', + ], + 'condition' => [ + 'direction' => 'vertical', + 'selected_element!' => '', + 'item_alignment_vertical' => 'stretch', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_settings', + [ + 'label' => esc_html__( 'Settings', 'elementor-pro' ), + 'condition' => [ + 'selected_element!' => '', + ], + ] + ); + + $this->add_control( + 'heading_filter_logic', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Filter Logic', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'multiple_selection', + [ + 'label' => esc_html__( 'Multiple Selection', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'default' => 'no', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'logical_combination', + [ + 'label' => esc_html__( 'Logical Combination', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'AND', + 'options' => [ + 'AND' => esc_html__( 'AND', 'elementor-pro' ), + 'OR' => esc_html__( 'OR', 'elementor-pro' ), + ], + 'condition' => [ + 'multiple_selection' => 'yes', + ], + 'separator' => 'after', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'heading_displayed_elements', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Displayed Elements', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_empty_items', + [ + 'label' => esc_html__( 'Empty Items', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_child_taxonomy', + [ + 'label' => esc_html__( 'Taxonomy Children', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'child_taxonomy_depth', + [ + 'label' => esc_html__( 'Depth', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '1', + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'condition' => [ + 'show_child_taxonomy' => 'yes', + ], + ] + ); + $this->add_control( + 'show_first_item', + [ + 'label' => esc_html__( 'First Item', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'first_item_title', + [ + 'label' => esc_html__( 'First Item Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'All', 'elementor-pro' ), + 'label_block' => true, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'show_first_item' => 'yes', + ], + ] + ); + + $this->add_control( + 'number_of_taxonomies', + [ + 'label' => esc_html__( 'Number of taxonomies', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 1, + ] + ); + + $this->add_responsive_control( + 'horizontal_scroll', + [ + 'label' => esc_html__( 'Horizontal Scroll', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'disable' => esc_html__( 'Disable', 'elementor-pro' ), + 'enable' => esc_html__( 'Enable', 'elementor-pro' ), + ], + 'condition' => [ + 'direction' => 'horizontal', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'enable' => '--e-filter-wrap: nowrap; --e-filter-overflow-x: scroll;', + 'disable' => '--e-filter-wrap: wrap; --e-filter-overflow-x: initial;', + ], + 'default' => 'disable', + 'frontend_available' => true, + 'separator' => 'before', + 'description' => esc_html__( 'Scroll items if they don’t fit into their parent container', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->register_design_layout_controls(); + } + + protected function register_design_layout_controls() { + $this->start_controls_section( + 'section_design_layout', + [ + 'label' => esc_html__( 'Items', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'taxonomy_filter_items_space_between', + [ + 'label' => esc_html__( 'Space between Items', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-filter-space-between: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'after', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'taxonomy_filter_typography', + 'selector' => '{{WRAPPER}} .e-filter-item', + ] + ); + + $this->start_controls_tabs( 'taxonomy_filter_tabs_section' ); + + $this->start_controls_tab( 'taxonomy_filter_tabs_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'taxonomy_filter_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-filter-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_normal_text_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item:not( [aria-pressed=true] ):not( :hover )', + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'taxonomy_filter_normal_background', + 'selector' => '{{WRAPPER}} .e-filter-item:not( [aria-pressed=true] ):not( :hover )', + 'exclude' => [ 'image', 'video' ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'taxonomy_filter_normal_border', + 'selector' => '{{WRAPPER}} .e-filter-item:not( [aria-pressed=true] ):not( :hover )', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item:not( [aria-pressed=true] ):not( :hover )', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'taxonomy_filter_tabs_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'taxonomy_filter_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-filter-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_hover_text_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item:hover:not( [aria-pressed=true] )', + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'taxonomy_filter_hover_background', + 'selector' => '{{WRAPPER}} .e-filter-item:hover:not( [aria-pressed=true] )', + 'exclude' => [ 'image', 'video' ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'taxonomy_filter_hover_border', + 'selector' => '{{WRAPPER}} .e-filter-item:hover:not( [aria-pressed=true] )', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_hover_box_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item:hover:not( [aria-pressed=true] )', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'taxonomy_filter_tabs_active', [ 'label' => esc_html__( 'Active', 'elementor-pro' ) ] ); + + $this->add_control( + 'taxonomy_filter_active_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-filter-active-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_active_text_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item[aria-pressed="true"]', + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'taxonomy_filter_active_background', + 'selector' => '{{WRAPPER}} .e-filter-item[aria-pressed="true"]', + 'exclude' => [ 'image', 'video' ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'taxonomy_filter_active_border', + 'selector' => '{{WRAPPER}} .e-filter-item[aria-pressed="true"]', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'taxonomy_filter_active_box_shadow', + 'selector' => '{{WRAPPER}} .e-filter-item[aria-pressed="true"]', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'taxonomy_filter_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-filter-item-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'taxonomy_filter_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vm', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-filter-item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function get_empty_widget_message_by_key( $message_key ) { + $messages = [ + 'select_loop_widget' => esc_html__( 'Choose a Loop Grid to view the Taxonomy Filter.', 'elementor-pro' ), + 'no_taxonomy_selected' => esc_html__( 'Please select a taxonomy.', 'elementor-pro' ), + 'no_terms_found' => esc_html__( 'No taxonomy terms found.', 'elementor-pro' ), + ]; + + return $messages[ $message_key ]; + } + + protected function print_empty_results_if_editor( $message_key ) { + if ( ! Plugin::elementor()->editor->is_edit_mode() ) { + return; + } + + ?> +
      + get_empty_widget_message_by_key( $message_key ) ); ?> +
      + print_empty_results_if_editor( 'select_loop_widget' ); + + return true; + } + + if ( empty( $user_selected_taxonomy ) ) { + $this->print_empty_results_if_editor( 'no_taxonomy_selected' ); + + return true; + } + + if ( empty( $terms ) ) { + $this->print_empty_results_if_editor( 'no_terms_found' ); + + return true; + } + + return false; + } + + /** + * @return array + */ + private function get_loop_widget_settings() { + $document = Plugin::elementor()->documents->get_doc_for_frontend( $this->get_current_ID() ); + + if ( ! $document ) { + return []; + } + + $widget_data = Utils::find_element_recursive( $document->get_elements_data(), $this->get_settings_for_display( 'selected_element' ) ); + + return ! empty( $widget_data['settings'] ) ? $widget_data['settings'] : []; + } + + /** + * @return int + */ + private function get_current_ID() { + $post_id = 0; + $theme_builder = ThemeBuilderModule::instance(); + $location = $theme_builder->get_locations_manager()->get_current_location(); + $documents = $theme_builder->get_conditions_manager()->get_documents_for_location( $location ); + + if ( empty( $documents ) ) { + return get_the_ID(); + } + + foreach ( $documents as $document ) { + $post_id = $document->get_post()->ID; + } + + return $post_id; + } + + /** + * @return boolean + */ + private function is_term_excluded_by_query_control( $term, $loop_filter_module ) { + $loop_widget_settings = $this->get_loop_widget_settings(); + $skin = ! empty( $loop_widget_settings['_skin'] ) ? $loop_widget_settings['_skin'] : 'post'; + + return $loop_filter_module->is_term_not_selected_for_inclusion( $loop_widget_settings, $term, $skin ) + || $loop_filter_module->is_term_selected_for_exclusion( $loop_widget_settings, $term, $skin ) + || $loop_filter_module->should_exclude_term_by_manual_selection( $loop_widget_settings, $term, $this->get_settings_for_display( 'taxonomy' ), $skin ); + } + + public function render() { + $settings = $this->get_settings_for_display(); + $selected_element = $settings['selected_element']; + $user_selected_taxonomy = $settings['taxonomy']; + + $terms = $this->get_filtered_taxonomy_terms( $user_selected_taxonomy, $settings ); + + if ( $this->has_empty_results( $selected_element, $user_selected_taxonomy, $terms ) ) { + return; + } + + $active_filters = []; + $loop_filter_module = Plugin::instance()->modules_manager->get_modules( 'loop-filter' ); + $query_string_filters = $loop_filter_module->get_query_string_filters(); + + if ( array_key_exists( $selected_element, $query_string_filters ) ) { + $active_filters = $query_string_filters[ $selected_element ]['taxonomy']; + } + + $active_terms = 0; + $total_taxonomies = 0; + $number_of_taxonomies = $settings['number_of_taxonomies']; + + $this->add_render_attribute( 'filter-bar', [ + 'class' => 'e-filter', + 'role' => 'search', // BC for older browser versions that don't support `` element. + 'data-base-url' => $this->get_base_url(), + 'data-page-num' => max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) ), + ] ); + ?> + print_render_attribute_string( 'filter-bar' ); ?>> + taxonomy ) || $this->is_term_excluded_by_query_control( $term, $loop_filter_module ) ) { + continue; + } + + $term_taxonomy = $term->taxonomy; + + if ( array_key_exists( $term_taxonomy, $active_filters ) && in_array( urldecode( $term->slug ), $active_filters[ $term_taxonomy ]['terms'] ) ) { + $aria_pressed_value = 'true'; + $active_terms++; + } + + if ( ! empty( $number_of_taxonomies ) && $total_taxonomies > $number_of_taxonomies ) { + continue; + } + + // This filter allows us to write the slug with non-latin characters as well, such as Hebrew. + $slug = apply_filters( 'editable_slug', $term->slug, $term ); + ?> + + + + + + + + + get_settings_for_display(); + $settings['taxonomy'] = $user_selected_taxonomy; + + return $this->get_filtered_taxonomies( $settings, $display_settings ); + } +} diff --git a/modules/lottie/assets/animations/default.json b/modules/lottie/assets/animations/default.json new file mode 100644 index 00000000..3a1107f5 --- /dev/null +++ b/modules/lottie/assets/animations/default.json @@ -0,0 +1 @@ +{"v":"5.5.7","meta":{"g":"LottieFiles AE ","a":"","k":"","d":"","tc":""},"fr":25,"ip":0,"op":125,"w":1920,"h":1080,"nm":"InLogo 3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[862,408,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[28.7,53,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Turbulent Displace","np":16,"mn":"ADBE Turbulent Displace","ix":1,"en":1,"ef":[{"ty":7,"nm":"Displacement","mn":"ADBE Turbulent Displace-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Amount","mn":"ADBE Turbulent Displace-0002","ix":2,"v":{"a":0,"k":33,"ix":2}},{"ty":0,"nm":"Size","mn":"ADBE Turbulent Displace-0003","ix":3,"v":{"a":0,"k":90,"ix":3}},{"ty":3,"nm":"Offset (Turbulence)","mn":"ADBE Turbulent Displace-0004","ix":4,"v":{"a":0,"k":[960,540],"ix":4}},{"ty":0,"nm":"Complexity","mn":"ADBE Turbulent Displace-0005","ix":5,"v":{"a":0,"k":1,"ix":5}},{"ty":0,"nm":"Evolution","mn":"ADBE Turbulent Displace-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":6,"nm":"Evolution Options","mn":"ADBE Turbulent Displace-0007","ix":7,"v":0},{"ty":7,"nm":"Cycle Evolution","mn":"ADBE Turbulent Displace-0008","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Cycle (in Revolutions)","mn":"ADBE Turbulent Displace-0009","ix":9,"v":{"a":0,"k":1,"ix":9}},{"ty":0,"nm":"Random Seed","mn":"ADBE Turbulent Displace-0010","ix":10,"v":{"a":0,"k":0,"ix":10}},{"ty":6,"nm":"Random Seed","mn":"ADBE Turbulent Displace-0011","ix":11,"v":0},{"ty":7,"nm":"Pinning","mn":"ADBE Turbulent Displace-0012","ix":12,"v":{"a":0,"k":3,"ix":12}},{"ty":7,"nm":"Resize Layer","mn":"ADBE Turbulent Displace-0013","ix":13,"v":{"a":0,"k":0,"ix":13}},{"ty":7,"nm":"Antialiasing for Best Quality","mn":"ADBE Turbulent Displace-0014","ix":14,"v":{"a":0,"k":1,"ix":14}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":66.833,"s":[{"i":[[4.75,0.75],[1,-1.25],[-8,-0.25]],"o":[[-4.75,-0.75],[-1,1.25],[8,0.25]],"v":[[346.5,-0.25],[334.25,0.5],[341.75,4.25]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[1.286,0.48],[0.271,-0.799],[-2.167,-0.16]],"o":[[-1.286,-0.48],[-0.271,0.799],[2.167,0.16]],"v":[[352.589,0.471],[349.271,0.951],[351.302,3.348]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 13","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[4.18,-0.372],[0.022,-1.823],[-6.574,0.303],[0.536,2.784]],"o":[[-4.18,0.372],[-0.03,2.442],[6.574,-0.303],[-0.604,-3.14]],"v":[[-510.668,-7.313],[-517.525,-0.891],[-508.861,4.275],[-501.457,-3.208]],"c":true}],"h":1},{"t":71.833,"s":[{"i":[[1.998,-0.14],[-0.044,-1.297],[-3.151,0.02],[0.341,1.997]],"o":[[-1.998,0.14],[0.058,1.737],[3.151,-0.02],[-0.384,-2.252]],"v":[[-518.552,-4.632],[-521.656,-0.268],[-517.355,3.533],[-511.502,-1.693]],"c":true}],"h":1},{"t":73.5003255208333,"s":[{"i":[[1.184,-0.136],[-0.026,-0.772],[-2.27,0.176],[0.203,1.189]],"o":[[-2.219,0.255],[0.035,1.034],[1.87,-0.145],[-0.229,-1.341]],"v":[[-521.063,-2.58],[-523.443,0.073],[-520.398,2.327],[-517.399,-0.776]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[830.5,-2.125],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74.333,"s":[100]},{"t":75.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 12","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":68.5,"s":[{"i":[[8.475,-4.457],[-1.556,-3.859],[-13.577,6.419],[3.576,5.392]],"o":[[-8.475,4.457],[2.084,5.169],[13.577,-6.419],[-4.034,-6.081]],"v":[[-523.509,-12.882],[-532.302,6.668],[-509.517,9.93],[-500.504,-12.337]],"c":true}],"h":1},{"t":70.166,"s":[{"i":[[2.779,-0.194],[-0.061,-1.804],[-4.383,0.027],[0.474,2.778]],"o":[[-2.779,0.194],[0.081,2.416],[4.383,-0.027],[-0.535,-3.133]],"v":[[-531.232,-4.697],[-535.55,1.374],[-529.567,6.662],[-521.425,-0.608]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.516,-0.174],[-0.033,-0.988],[-2.905,0.226],[0.26,1.521]],"o":[[-2.841,0.327],[0.044,1.323],[2.393,-0.186],[-0.293,-1.716]],"v":[[-538.976,-1.008],[-542.022,2.387],[-538.125,5.273],[-534.286,1.301]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[758.5,-2.125],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67.666,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68.5,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 11","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":66.833,"s":[{"i":[[5.552,-0.494],[0.03,-2.422],[-8.733,0.403],[0.712,3.698]],"o":[[-5.552,0.494],[-0.04,3.244],[8.733,-0.403],[-0.803,-4.171]],"v":[[-518.497,-8.318],[-527.605,0.213],[-516.128,6.827],[-499.303,-3.636]],"c":true}],"h":1},{"t":68.5,"s":[{"i":[[2.779,-0.194],[-0.061,-1.804],[-4.383,0.027],[0.474,2.778]],"o":[[-2.779,0.194],[0.081,2.416],[4.383,-0.027],[-0.535,-3.133]],"v":[[-531.232,-4.697],[-535.55,1.374],[-529.567,6.662],[-521.425,-0.608]],"c":true}],"h":1},{"t":70.1663411458333,"s":[{"i":[[1.516,-0.174],[-0.033,-0.988],[-2.905,0.226],[0.26,1.521]],"o":[[-2.841,0.327],[0.044,1.323],[2.393,-0.186],[-0.293,-1.716]],"v":[[-538.976,-1.008],[-542.022,2.387],[-538.125,5.273],[-534.286,1.301]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[638,-2],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[100]},{"t":71.8333333333333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 10","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":66.833,"s":[{"i":[[5.552,-0.494],[0.03,-2.422],[-8.733,0.403],[0.712,3.698]],"o":[[-5.552,0.494],[-0.04,3.244],[8.733,-0.403],[-0.803,-4.171]],"v":[[-517.685,-5.901],[-527.515,-1.059],[-517.499,3.978],[-494.807,-3.956]],"c":true}],"h":1},{"t":68.5,"s":[{"i":[[2.327,-0.154],[-0.063,-1.604],[-3.672,-0.005],[0.416,2.473]],"o":[[-2.327,0.154],[0.084,2.149],[3.672,0.005],[-0.469,-2.789]],"v":[[-526.191,-3.085],[-530.187,-0.183],[-525.805,3.467],[-516.479,-1.084]],"c":true}],"h":1},{"t":70.1663411458333,"s":[{"i":[[0.793,-0.028],[-0.057,-0.821],[-1.256,-0.083],[0.196,1.272]],"o":[[-0.793,0.028],[0.076,1.099],[1.256,0.083],[-0.221,-1.435]],"v":[[-530.305,-0.876],[-531.609,0.52],[-530.03,2.479],[-526.94,0.358]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[542,-2],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[100]},{"t":71.8333333333333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 9","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":71.833,"s":[{"i":[[3.776,0.019],[-1.805,-0.357],[0.815,1.363]],"o":[[-1.825,-0.009],[1.641,0.325],[0.065,-0.538]],"v":[[-461.744,-1.505],[-461.964,0.088],[-452.414,-0.453]],"c":true}],"h":1},{"t":73.5003255208333,"s":[{"i":[[1.518,-0.096],[-0.453,-0.638],[-0.713,0.267]],"o":[[-0.734,0.046],[0.453,0.638],[0.713,-0.267]],"v":[[-465.108,-1.338],[-467.09,-0.546],[-461.402,-0.46]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-341.688,1.75],"ix":2},"a":{"a":0,"k":[-455.313,-0.938],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":178.598,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74.333,"s":[100]},{"t":75.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[3.776,0.019],[-1.031,-1.318],[0.815,1.363]],"o":[[-1.825,-0.009],[1.031,1.318],[0.065,-0.538]],"v":[[-461.237,-1.805],[-466.254,-0.892],[-449.162,-0.498]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-465.182,-1.777],[-467.21,-1.112],[-461.538,-0.668]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-382.875,1.25],"ix":2},"a":{"a":0,"k":[-455.313,-0.938],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":178.598,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":68.5,"s":[{"i":[[3,0],[-0.813,-1.313],[-1.438,0.438]],"o":[[-1.45,0],[0.813,1.313],[1.438,-0.438]],"v":[[-456.438,-2.188],[-460.438,-0.875],[-449.25,0]],"c":true}],"h":1},{"t":70.1663411458333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-455.498,-1.54],[-457.526,-0.875],[-451.854,-0.431]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-421.625,1.125],"ix":2},"a":{"a":0,"k":[-455.375,-1.063],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-183.942,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67.666,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68.5,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[100]},{"t":71.8333333333333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":66.833,"s":[{"i":[[4.25,-0.125],[0.477,-1.343],[-17.974,-0.972],[-17.25,-1.25],[-0.226,6.325],[9.25,-0.75]],"o":[[-4.25,0.125],[-1.375,3.875],[18.5,1],[12.53,0.908],[0.25,-7],[-9.25,0.75]],"v":[[-455.25,-3.125],[-490.125,-1.625],[-454,3.75],[-411.25,5.25],[-374.25,0.75],[-414.75,-5.25]],"c":true}],"h":1},{"t":68.5,"s":[{"i":[[4.086,-0.081],[0.458,-0.874],[-5.769,-0.163],[-16.585,-0.814],[-0.217,4.118],[8.893,-0.488]],"o":[[-4.086,0.081],[-1.322,2.523],[17.797,0.502],[12.046,0.591],[0.24,-4.557],[-8.893,0.488]],"v":[[-435.501,-2.216],[-446.678,-0.832],[-437.905,2.748],[-397.063,4.062],[-367.24,0.632],[-399.178,-3.774]],"c":true}],"h":1},{"t":70.166,"s":[{"i":[[2.531,-0.05],[0.284,-0.542],[-3.573,-0.101],[-3.522,-0.193],[-0.135,2.55],[5.508,-0.302]],"o":[[-2.531,0.05],[-0.819,1.562],[11.022,0.311],[7.458,0.409],[0.149,-2.822],[-5.508,0.302]],"v":[[-392.395,-1.267],[-399.317,-0.41],[-393.884,1.807],[-378.731,2.904],[-365.138,0.47],[-379.886,-2.8]],"c":true}],"h":1},{"t":71.833,"s":[{"i":[[1.313,-0.257],[-0.001,-0.413],[-1.873,-0.146],[-1.851,0.065],[0.075,1.157],[2.532,0.118]],"o":[[-1.138,0.223],[-0.031,0.658],[2.76,0.215],[1.761,-0.062],[-0.059,-0.909],[-2.16,-0.101]],"v":[[-371.104,-1.254],[-374.278,0.212],[-371.197,1.838],[-365.507,2.199],[-362.637,0.385],[-365.818,-1.488]],"c":true}],"h":1},{"t":73.5003255208333,"s":[{"i":[[0.895,-0.155],[-0.001,-0.249],[-1.275,-0.088],[-1.26,0.039],[0.051,0.698],[1.724,0.072]],"o":[[-0.775,0.135],[-0.021,0.397],[1.88,0.13],[1.2,-0.037],[-0.04,-0.549],[-1.471,-0.061]],"v":[[-363.818,-0.623],[-365.979,0.262],[-363.88,1.243],[-360.005,1.461],[-358.051,0.366],[-360.217,-0.764]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-384.5,2],"ix":2},"a":{"a":0,"k":[-433,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74.333,"s":[100]},{"t":75.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[430.984,2.882],"ix":2},"a":{"a":0,"k":[-383.766,1.382],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[5.552,-0.494],[0.03,-2.422],[-8.733,0.403],[1.951,2.164]],"o":[[-5.552,0.494],[-0.04,3.244],[8.733,-0.403],[-1.951,-2.164]],"v":[[-513.027,-2.965],[-524.904,1.633],[-513.464,5.984],[-492.197,-1.265]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[1.933,-0.356],[-0.386,-1.859],[-3.102,0.273],[1.062,1.668]],"o":[[-1.933,0.356],[0.517,2.489],[3.102,-0.273],[-1.062,-1.668]],"v":[[-522.22,-1.02],[-527.341,3.093],[-521.05,6.088],[-515.846,1.385]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[0.928,-0.039],[-0.058,-0.895],[-1.47,-0.077],[0.387,0.851]],"o":[[-0.928,0.039],[0.077,1.199],[1.47,0.077],[-0.387,-0.851]],"v":[[-526.389,1.435],[-529.058,3.02],[-526.312,4.838],[-523.566,2.982]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[221,-2],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[2.487,-0.104],[-0.155,-2.399],[-3.938,-0.207],[1.036,2.28]],"o":[[-2.487,0.104],[0.207,3.213],[3.938,0.207],[-1.036,-2.28]],"v":[[-504.58,-4.041],[-509.655,-0.308],[-504.157,4.8],[-495.002,-0.908]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[1.933,-0.356],[-0.386,-1.859],[-3.102,0.273],[1.062,1.668]],"o":[[-1.933,0.356],[0.517,2.489],[3.102,-0.273],[-1.062,-1.668]],"v":[[-502.876,-3.482],[-507.998,0.631],[-501.706,3.626],[-496.502,-1.077]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[0.928,-0.039],[-0.058,-0.895],[-1.47,-0.077],[0.387,0.851]],"o":[[-0.928,0.039],[0.077,1.199],[1.47,0.077],[-0.387,-0.851]],"v":[[-502.085,-1.659],[-504.754,-0.073],[-502.008,1.745],[-499.262,-0.112]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23,0],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":187.253,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[3,-0.125],[-0.187,-2.893],[-4.75,-0.25],[1.25,2.75]],"o":[[-3,0.125],[0.25,3.875],[4.75,0.25],[-1.25,-2.75]],"v":[[-502.625,-5.5],[-511.25,-0.375],[-502.375,5.5],[-493.5,-0.5]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[1.964,-0.082],[-0.122,-1.894],[-3.11,-0.164],[0.818,1.8]],"o":[[-1.964,0.082],[0.164,2.537],[3.11,0.164],[-0.818,-1.8]],"v":[[-502.355,-3.579],[-508.002,-0.224],[-502.191,3.622],[-496.381,-0.306]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[0.928,-0.039],[-0.058,-0.895],[-1.47,-0.077],[0.387,0.851]],"o":[[-0.928,0.039],[0.077,1.199],[1.47,0.077],[-0.387,-0.851]],"v":[[-502.085,-1.659],[-504.754,-0.073],[-502.008,1.745],[-499.262,-0.112]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-296,0],"ix":2},"a":{"a":0,"k":[-502,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":171.987,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[4.875,1.125],[1,-4],[-3,1.125]],"o":[[-4.7,-1.085],[-1,4],[9.843,-3.691]],"v":[[-238.125,-1.125],[-265.5,3.125],[-229.125,6.375]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[3.438,0.793],[0.705,-2.821],[-2.116,0.793]],"o":[[-3.314,-0.765],[-0.705,2.821],[6.941,-2.603]],"v":[[-232.569,0.075],[-247.202,2.984],[-228.691,5.187]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[1.056,0.411],[0.217,-1.463],[-0.65,0.411]],"o":[[-1.019,-0.397],[-0.217,1.463],[2.133,-1.35]],"v":[[-227.556,1.312],[-232.053,2.821],[-226.364,3.964]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[88,-3],"ix":2},"a":{"a":0,"k":[-241,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[3.375,3.25],[1,-4],[-10.5,-0.5]],"o":[[-6.918,-6.662],[-1,4],[10.5,0.5]],"v":[[-220.5,1],[-264.5,2],[-230,6]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[1.463,1.5],[0.55,-2.933],[-5.754,0.611]],"o":[[-4.478,-4.592],[-0.55,2.933],[5.688,-0.604]],"v":[[-219.4,1],[-243.6,1.733],[-224.625,4.667]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[0.571,0.861],[0.186,-1.867],[-1.309,0.229]],"o":[[-1.7,-2.563],[-0.186,1.867],[1.937,-0.339]],"v":[[-218.987,0.375],[-226.98,1.467],[-220.566,3.333]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[3,0],[-0.813,-1.313],[-1.438,0.438]],"o":[[-1.45,0],[0.813,1.313],[1.438,-0.438]],"v":[[-456.438,-2.188],[-460.438,-0.875],[-449.25,0]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-455.498,-1.54],[-457.526,-0.875],[-451.854,-0.431]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-350.375,1],"ix":2},"a":{"a":0,"k":[-455.313,-0.938],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":178.598,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[3,0],[-0.813,-1.313],[-1.438,0.438]],"o":[[-1.45,0],[0.813,1.313],[1.438,-0.438]],"v":[[-456.438,-2.188],[-460.438,-0.875],[-449.25,0]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-455.498,-1.54],[-457.526,-0.875],[-451.854,-0.431]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-394.5,-0.25],"ix":2},"a":{"a":0,"k":[-455.375,-1.063],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[4.25,-0.125],[4.002,-4.002],[-17.974,-0.972],[-17.25,-1.25],[1,6.25],[9.25,-0.75]],"o":[[-4.25,0.125],[-5.375,5.375],[18.5,1],[12.53,0.908],[-1.644,-10.274],[-9.25,0.75]],"v":[[-453.25,-2.625],[-490.125,-2.375],[-454,3.75],[-409,5.75],[-386.75,-0.75],[-420.5,-5.25]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[3.669,-0.106],[3.455,-3.4],[-15.518,-0.826],[-11.428,-1.229],[0.458,5.361],[7.986,-0.637]],"o":[[-3.669,0.106],[-4.64,4.567],[15.972,0.85],[10.782,1.159],[-0.637,-7.456],[-7.986,0.637]],"v":[[-440.274,-3.388],[-475.86,-2.425],[-441.922,2.029],[-406.322,3.979],[-386.613,-1.044],[-414.751,-4.618]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[2.858,-0.084],[2.774,-2.606],[-7.473,0.19],[-12.303,-2.034],[3.317,2.746],[6.221,-0.504]],"o":[[-2.858,0.084],[-4.23,3.973],[10.762,-0.273],[8.336,1.378],[-3.744,-3.1],[-6.221,0.504]],"v":[[-429.443,-1.916],[-451.964,-2.289],[-431.274,1.139],[-399.548,3.122],[-390.339,-1.364],[-414.612,-1.376]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-384.5,2],"ix":2},"a":{"a":0,"k":[-433,1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-121.266,2.382],"ix":2},"a":{"a":0,"k":[-383.766,1.382],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.726,-0.489],[0.33,0.9],[1.837,-0.574]],"o":[[1.667,0.219],[-0.408,-1.112],[-4.387,1.372]],"v":[[-416.513,1.844],[-414.744,0.325],[-418.558,-1.419]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67.666,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68.5,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 10","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[3,0],[-0.813,-1.313],[-1.438,0.438]],"o":[[-1.45,0],[0.813,1.313],[1.438,-0.438]],"v":[[-456.438,-2.188],[-460.438,-0.875],[-449.25,0]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-455.498,-1.54],[-457.526,-0.875],[-451.854,-0.431]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-350.375,1],"ix":2},"a":{"a":0,"k":[-455.313,-0.938],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":178.598,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 9","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":70.166,"s":[{"i":[[3,0],[-0.813,-1.313],[-1.438,0.438]],"o":[[-1.45,0],[0.813,1.313],[1.438,-0.438]],"v":[[-456.438,-2.188],[-460.438,-0.875],[-449.25,0]],"c":true}],"h":1},{"t":71.8333333333333,"s":[{"i":[[1.521,0],[-0.412,-0.665],[-0.729,0.222]],"o":[[-0.735,0],[0.412,0.665],[0.729,-0.222]],"v":[[-455.498,-1.54],[-457.526,-0.875],[-451.854,-0.431]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-394.5,-0.25],"ix":2},"a":{"a":0,"k":[-455.375,-1.063],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72.666,"s":[100]},{"t":73.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[4.25,-0.125],[3.792,-4.202],[-17.974,-0.972],[-17.25,-1.25],[8.5,6],[9.25,-0.75]],"o":[[-4.25,0.125],[-4.625,5.125],[18.5,1],[12.53,0.908],[-8.5,-6],[-9.25,0.75]],"v":[[-446.75,-3.875],[-485,-1.25],[-449,6.75],[-397.75,7],[-388.25,-3],[-424,-4.5]],"c":true}],"h":1},{"t":66,"s":[{"i":[[4.25,-0.125],[3.792,-4.202],[-17.974,-0.972],[-17.25,-1.25],[8.5,6],[9.25,-0.75]],"o":[[-4.25,0.125],[-4.625,5.125],[18.5,1],[12.53,0.908],[-8.5,-6],[-9.25,0.75]],"v":[[-446.75,-3.875],[-487.5,-1],[-449,6.75],[-397.75,7],[-388.25,-3],[-424,-4.5]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[3.672,-0.108],[3.564,-3.348],[-15.551,0.11],[-15.606,-1.602],[4.32,3.456],[7.992,-0.648]],"o":[[-3.672,0.108],[-5.433,5.104],[14.923,-0.106],[10.797,1.108],[-7.019,-5.615],[-7.992,0.648]],"v":[[-437.551,-2.315],[-474.355,-2.294],[-438.896,3.136],[-399.435,4.442],[-387.32,-1.606],[-419.071,-3.334]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[2.858,-0.084],[0.597,-3.759],[-7.473,0.19],[-12.303,-2.034],[3.317,2.746],[6.221,-0.504]],"o":[[-2.858,0.084],[-0.661,4.164],[10.762,-0.273],[8.336,1.378],[-3.744,-3.1],[-6.221,0.504]],"v":[[-429.443,-1.916],[-454.339,-1.539],[-431.274,1.139],[-399.548,3.122],[-390.339,-1.364],[-414.612,-1.376]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[48.5,1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-362.658,1.059],"ix":2},"a":{"a":0,"k":[-372.408,1.059],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[3,-0.125],[-0.187,-2.893],[-4.75,-0.25],[1.25,2.75]],"o":[[-3,0.125],[0.25,3.875],[4.75,0.25],[-1.25,-2.75]],"v":[[-502.625,-5.5],[-511.25,-0.375],[-502.375,5.5],[-493.5,-0.5]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[1.964,-0.082],[-0.122,-1.894],[-3.11,-0.164],[0.818,1.8]],"o":[[-1.964,0.082],[0.164,2.537],[3.11,0.164],[-0.818,-1.8]],"v":[[-502.355,-3.579],[-508.002,-0.224],[-502.191,3.622],[-496.381,-0.306]],"c":true}],"h":1},{"t":68.5003255208333,"s":[{"i":[[0.928,-0.039],[-0.058,-0.895],[-1.47,-0.077],[0.387,0.851]],"o":[[-0.928,0.039],[0.077,1.199],[1.47,0.077],[-0.387,-0.851]],"v":[[-502.085,-1.659],[-504.754,-0.073],[-502.008,1.745],[-499.262,-0.112]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46,1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69.333,"s":[100]},{"t":70.1663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":65.166,"s":[{"i":[[2.299,0],[-0.143,-2.356],[-2.244,0],[0.115,1.897]],"o":[[-2.36,0],[0.136,2.24],[1.9,0],[-0.139,-2.295]],"v":[[-527.5,-4],[-532.75,0.75],[-527,4.25],[-522.5,0.75]],"c":true}],"h":1},{"t":66.8333333333333,"s":[{"i":[[0.826,0],[-0.051,-0.847],[-0.807,0],[0.041,0.682]],"o":[[-0.848,0],[0.049,0.805],[0.683,0],[-0.05,-0.825]],"v":[[-527.589,-1.358],[-529.477,0.35],[-527.409,1.608],[-525.791,0.35]],"c":true}],"h":1}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[40.25,1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64.333,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65.166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67.666,"s":[100]},{"t":68.5003255208333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"t":56.833,"s":[{"i":[[20,0],[1,-19],[-18.998,-0.576],[0.5,25]],"o":[[-17.007,0],[-1,19],[16.5,0.5],[-0.5,-25]],"v":[[-833,-32.5],[-865,0.5],[-830,34.5],[-796.5,0.5]],"c":true}],"h":1},{"t":58.5,"s":[{"i":[[20,0],[1,-19],[-18.998,-0.576],[0.5,25]],"o":[[-17.007,0],[-1,19],[16.5,0.5],[-0.5,-25]],"v":[[-717,-32.5],[-865,0.5],[-714,33],[-668,0.5]],"c":true}],"h":1},{"t":60.166,"s":[{"i":[[20,0],[1,-19],[-18.998,-0.462],[0.5,25]],"o":[[-17.007,0],[-1,19],[16.5,0.402],[-0.5,-25]],"v":[[149,-27],[-862,0],[152,25.598],[198,-0.5]],"c":true}],"h":1},{"t":61.833,"s":[{"i":[[20,0],[1,-19],[-18.998,-0.349],[-0.45,18.001]],"o":[[-17.007,0],[-1,19],[16.5,0.303],[0.5,-20]],"v":[[559,-20.5],[-798,0],[562,19.197],[608,-0.5]],"c":true}],"h":1},{"t":63.5,"s":[{"i":[[73,0.658],[30.5,-6.5],[-19.002,-0.276],[0.5,25]],"o":[[-17.006,-0.153],[58,16.5],[68,0.987],[-0.5,-25]],"v":[[673,-22.08],[-589.5,0],[676,21.013],[776,0]],"c":true}],"h":1},{"t":65.166,"s":[{"i":[[19.987,-0.708],[221,-12],[-229,-13],[0.5,25]],"o":[[-127,4.5],[114,15],[16.481,0.936],[-0.5,-25]],"v":[[797,-26.5],[282,0],[797,26.5],[846,-0.5]],"c":true}],"h":1},{"t":66.833,"s":[{"i":[[20,0],[1,-19],[-18.998,-0.576],[0.5,25]],"o":[[-17.007,0],[-1,19],[16.5,0.5],[-0.5,-25]],"v":[[819,-33.5],[722,0],[822,32],[868,-0.5]],"c":true}],"h":1},{"t":68.5,"s":[{"i":[[18.242,0.223],[-0.24,-17.143],[-18.057,-0.023],[0.516,15.75]],"o":[[-17.559,-0.215],[0.217,15.55],[17.043,0.022],[-0.664,-20.262]],"v":[[852.508,-30.223],[821.533,-0.05],[854.057,28.773],[883.484,-0.5]],"c":true}],"h":1},{"t":70.166,"s":[{"i":[[14.169,0.174],[-0.186,-13.316],[-14.026,-0.018],[0.401,12.234]],"o":[[-13.639,-0.167],[0.169,12.078],[13.238,0.017],[-0.516,-15.738]],"v":[[871.289,-23.659],[847.229,-0.222],[872.492,22.166],[895.349,-0.572]],"c":true}],"h":1},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":71.833,"s":[{"i":[[11.26,0.138],[-0.148,-10.582],[-11.146,-0.014],[0.319,9.722]],"o":[[-10.839,-0.133],[0.134,9.598],[10.52,0.013],[-0.41,-12.507]],"v":[[882.561,-18.97],[863.441,-0.345],[883.517,17.446],[901.681,-0.623]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73.5,"s":[{"i":[[8.06,0.099],[-0.106,-7.575],[-7.978,-0.01],[0.228,6.959]],"o":[[-7.758,-0.095],[0.096,6.871],[7.53,0.01],[-0.293,-8.953]],"v":[[891.585,-13.813],[877.899,-0.481],[892.27,12.255],[905.272,-0.68]],"c":true}]},{"t":76.8333333333333,"s":[{"i":[[2.64,0.056],[-0.035,-4.335],[-2.613,-0.006],[0.075,3.982]],"o":[[-2.541,-0.054],[0.031,3.932],[2.466,0.005],[-0.096,-5.123]],"v":[[907.017,-8.256],[902.535,-0.627],[907.241,6.661],[911.499,-0.74]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56.833,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":76.833,"s":[100]},{"t":77.6663411458333,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":16,"mn":"ADBE Vector Group","hd":false}],"ip":61,"op":81.8333333333333,"st":56.8333333333333,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[779.346,392,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[43.7,48,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Turbulent Displace","np":16,"mn":"ADBE Turbulent Displace","ix":1,"en":1,"ef":[{"ty":7,"nm":"Displacement","mn":"ADBE Turbulent Displace-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Amount","mn":"ADBE Turbulent Displace-0002","ix":2,"v":{"a":0,"k":33,"ix":2}},{"ty":0,"nm":"Size","mn":"ADBE Turbulent Displace-0003","ix":3,"v":{"a":0,"k":90,"ix":3}},{"ty":3,"nm":"Offset (Turbulence)","mn":"ADBE Turbulent Displace-0004","ix":4,"v":{"a":0,"k":[960,540],"ix":4}},{"ty":0,"nm":"Complexity","mn":"ADBE Turbulent Displace-0005","ix":5,"v":{"a":0,"k":1,"ix":5}},{"ty":0,"nm":"Evolution","mn":"ADBE Turbulent Displace-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":6,"nm":"Evolution Options","mn":"ADBE Turbulent Displace-0007","ix":7,"v":0},{"ty":7,"nm":"Cycle Evolution","mn":"ADBE Turbulent Displace-0008","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Cycle (in Revolutions)","mn":"ADBE Turbulent Displace-0009","ix":9,"v":{"a":0,"k":1,"ix":9}},{"ty":0,"nm":"Random Seed","mn":"ADBE Turbulent Displace-0010","ix":10,"v":{"a":0,"k":0,"ix":10}},{"ty":6,"nm":"Random Seed","mn":"ADBE Turbulent Displace-0011","ix":11,"v":0},{"ty":7,"nm":"Pinning","mn":"ADBE Turbulent Displace-0012","ix":12,"v":{"a":0,"k":3,"ix":12}},{"ty":7,"nm":"Resize Layer","mn":"ADBE Turbulent Displace-0013","ix":13,"v":{"a":0,"k":0,"ix":13}},{"ty":7,"nm":"Antialiasing for Best Quality","mn":"ADBE Turbulent Displace-0014","ix":14,"v":{"a":0,"k":1,"ix":14}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":56.833,"s":[{"i":[[11.322,0],[0.345,-0.017],[0,-10.973],[-11.159,-0.189],[-0.118,0],[0,11.322]],"o":[[-0.349,0],[-10.838,0.542],[0,11.204],[0.118,0.002],[11.322,0],[0,-11.322]],"v":[[1.25,-21.25],[0.208,-21.224],[-19.25,-0.75],[0.896,19.747],[1.25,19.75],[21.75,-0.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":57.666,"s":[{"i":[[16.482,-0.109],[0.514,-0.021],[0.053,-10.972],[-16.369,-0.081],[-0.172,0.001],[-0.054,11.321]],"o":[[-0.508,0.003],[-16.137,0.649],[-0.054,11.203],[0.173,0.001],[16.482,-0.109],[0.054,-11.321]],"v":[[16.806,-21.487],[15.273,-21.451],[-19.303,-0.751],[16.093,19.51],[16.61,19.51],[40.383,-1.145]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":58.5,"s":[{"i":[[15.609,-0.124],[1.007,-0.027],[0.06,-10.971],[-21.26,-0.005],[-0.163,0.001],[-0.062,11.321]],"o":[[-0.482,0.004],[-31.615,0.837],[-0.061,11.203],[0.224,0],[15.609,-0.124],[0.062,-11.321]],"v":[[294.52,-15.545],[292.279,-15.499],[-19.31,-0.751],[293.715,25.453],[294.296,25.452],[316.829,4.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":59.333,"s":[{"i":[[22.713,0],[1.996,-0.02],[0,-10.973],[-36.822,-0.163],[-0.237,0],[0,11.322]],"o":[[-0.701,0],[-62.69,0.615],[0,11.204],[0.388,0.002],[22.713,0],[0,-11.322]],"v":[[732.113,-7.432],[728.047,-7.403],[-19.25,-0.75],[731.174,33.565],[732.113,33.568],[764.738,13.068]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60.166,"s":[{"i":[[22.713,0],[2.143,-0.019],[0,-10.973],[-38.457,-0.168],[-0.237,0],[0,11.322]],"o":[[-0.701,0],[-67.327,0.6],[0,11.204],[0.405,0.002],[22.713,0],[0,-11.322]],"v":[[878.053,-4.043],[873.763,-4.014],[-4.25,-1.5],[877.088,36.954],[878.053,36.957],[910.678,16.457]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[13.629,-4.561],[86.652,-5.975],[0,-10.358],[-53.446,1.16],[-22.24,8.602],[2.444,23.969]],"o":[[-9.862,3.3],[-80.243,5.533],[0,10.857],[46.354,-1.006],[18.302,-7.078],[-1.149,-11.263]],"v":[[1074.284,-36.077],[963.177,-3.705],[190.576,4.925],[941.208,34.747],[1057.908,19.478],[1102.693,-22.181]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[25.734,-14.458],[57.535,0.433],[0,-10.358],[-53.458,-0.289],[-28.449,20.495],[16.742,10.948]],"o":[[-45.444,25.531],[-80.43,-0.606],[0,10.857],[97.834,0.528],[20.653,-14.879],[-26.837,-17.549]],"v":[[1072.672,-29.604],[937.627,-1.065],[432.522,10.148],[956.717,34.381],[1120.036,-15.944],[1150.156,-76.861]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[23.815,-17.439],[60.087,-2.523],[0,-10.358],[-53.395,2.605],[-27.04,22.321],[16.742,10.948]],"o":[[-61.791,45.249],[-80.362,3.374],[0,10.857],[115.945,-5.656],[30.862,-25.477],[-26.837,-17.549]],"v":[[1107.611,-54.498],[937.531,4.434],[656.485,14.205],[956.813,28.882],[1139.838,-33.101],[1191.46,-122.647]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[18.893,-22.679],[60.087,-2.523],[-0.009,-7.129],[-53.457,0.418],[-28.313,20.683],[27.034,12.374]],"o":[[-49.538,59.465],[-80.362,3.374],[0.014,10.931],[106.359,-0.832],[43.474,-31.758],[-19.486,-8.919]],"v":[[1132.449,-73.568],[950.977,7.678],[819.989,15.441],[962.338,27.487],[1135.304,-31.18],[1210.331,-172.326]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[11.856,-27.032],[56.914,-19.432],[-1.357,-6.999],[-58.312,21.909],[-22.064,27.25],[29.714,1.04]],"o":[[-31.29,71.344],[-44.492,15.191],[2.081,10.731],[33.919,-12.744],[45.923,-56.717],[-24.377,-0.853]],"v":[[1179.204,-142.321],[1032.438,-3.447],[944.982,17.633],[1072.983,5.804],[1169.801,-60.084],[1218.771,-211.834]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[14.53,-35.892],[30.675,-23.851],[5.099,-4.983],[-50.58,36.358],[-16.698,30.832],[29.683,1.694]],"o":[[-19.208,47.446],[-37.115,28.858],[-11.962,11.69],[28.617,-20.57],[23.405,-43.217],[-25.543,-1.458]],"v":[[1178.34,-146.817],[1108.748,-47.775],[1041.305,6.278],[1128.594,-38.743],[1209.941,-137.785],[1216.557,-246.794]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[6.463,-38.179],[26.105,-35.723],[3.462,-6.232],[-38.476,48.988],[-6.091,22.999],[28.929,-6.861]],"o":[[-2.665,15.742],[-27.739,37.959],[-8.122,14.621],[16.705,-21.269],[12.583,-47.51],[-24.895,5.904]],"v":[[1195.756,-182.445],[1160.966,-93.998],[1108.528,-35.694],[1176.987,-93.916],[1220.9,-173.321],[1205.693,-274.264]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.833,"s":[{"i":[[-3.967,-38.518],[14.738,-41.718],[2.805,-6.554],[-17.135,35.515],[3.642,44.481],[5.311,-9.959]],"o":[[1.636,15.882],[-10.128,28.668],[-4.058,9.483],[11.752,-24.358],[-4.01,-48.984],[-7.603,14.257]],"v":[[1203.101,-232.396],[1185.56,-129.169],[1153.419,-77.434],[1199.41,-126.896],[1227.572,-246.524],[1191.203,-296.143]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":67.666,"s":[{"i":[[-6.517,-18.867],[6.536,-33.775],[1.403,-5.363],[-9.315,43.217],[8.841,20.883],[2.939,-8.269]],"o":[[4.053,11.734],[-4.492,23.21],[-2.03,7.758],[4.43,-20.556],[-14.898,-35.19],[-4.207,11.838]],"v":[[1193.273,-271.965],[1203.312,-170.863],[1184.545,-127.384],[1220.176,-196.608],[1217.473,-286.022],[1181.171,-312.54]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":68.5,"s":[{"i":[[-9.304,-14.906],[-0.873,-44.41],[0.562,-4.797],[-0.324,53.603],[11.725,14.991],[1.63,-7.53]],"o":[[5.786,9.27],[0.403,20.504],[-0.813,6.94],[0.11,-18.265],[-20.528,-26.245],[-2.334,10.78]],"v":[[1182.667,-295.219],[1206.787,-226.586],[1201.598,-166.302],[1220.883,-246.831],[1203.141,-311.834],[1169.962,-323.009]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":69.333,"s":[{"i":[[-9.304,-14.906],[-6.738,-23.509],[0.562,-4.797],[3.138,27.16],[11.278,15.331],[4.942,-5.911]],"o":[[5.786,9.27],[5.651,19.714],[-0.813,6.94],[-2.096,-18.145],[-13.204,-17.949],[-5.257,6.287]],"v":[[1174.843,-305.357],[1208.609,-245.057],[1211.646,-197.632],[1218.662,-262.872],[1195.807,-321.463],[1166.646,-333.568]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70.166,"s":[{"i":[[-11.178,-13.557],[-7.335,-18.018],[0.562,-4.797],[7.715,22.739],[11.278,15.331],[4.942,-5.911]],"o":[[9.466,11.481],[7.732,18.994],[-0.813,6.94],[-5.869,-17.297],[-13.204,-17.949],[-5.257,6.287]],"v":[[1164.993,-314.03],[1200.968,-265.693],[1214.144,-226.092],[1209.987,-281.526],[1186.957,-330.119],[1157.769,-340.724]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":71,"s":[{"i":[[-5.68,-5.275],[-6.615,-5.699],[-5.996,-9.279],[4.449,11.328],[8.129,7.475],[4.963,-6.237]],"o":[[9.337,8.672],[7.612,6.558],[4.077,-17.869],[-3.896,-9.921],[-10.024,-9.217],[-4.807,6.041]],"v":[[1156.32,-325.652],[1174.022,-308.569],[1196.611,-282.346],[1192.558,-321.685],[1176.913,-343.998],[1153.575,-346.545]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":71.833,"s":[{"i":[[-4.618,-4.412],[-5.383,-4.772],[-4.833,-7.713],[3.536,9.381],[6.61,6.253],[4.158,-5.076]],"o":[[7.591,7.253],[6.195,5.492],[3.56,-14.665],[-3.097,-8.217],[-8.152,-7.711],[-4.028,4.917]],"v":[[1150.562,-334.187],[1164.948,-319.907],[1183.255,-298.042],[1180.363,-330.484],[1167.73,-349.046],[1148.538,-351.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":72.666,"s":[{"i":[[-4.207,-3.771],[-4.886,-4.078],[-4.552,-6.589],[3.511,8.013],[6.019,5.343],[3.352,-4.333]],"o":[[6.916,6.198],[5.623,4.693],[2.372,-12.522],[-3.075,-7.019],[-7.422,-6.589],[-3.247,4.197]],"v":[[1147.89,-337.464],[1161.022,-325.261],[1177.911,-306.579],[1173.845,-334.286],[1162.023,-350.145],[1145.308,-352.186]],"c":true}]},{"t":73.5003255208333,"s":[{"i":[[-3.787,-3.137],[-4.403,-3.357],[-4.057,-5.786],[3.081,7.256],[5.419,4.439],[3.136,-4.492]],"o":[[6.225,5.157],[5.067,3.863],[2.373,-12.188],[-2.698,-6.355],[-6.682,-5.475],[-3.038,4.351]],"v":[[1146.958,-339.941],[1158.771,-329.735],[1173.915,-313.763],[1170.646,-339.723],[1160.09,-353.554],[1144.835,-353.689]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-721,85],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-1,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.833,"s":[{"i":[[-1.848,-1.875],[-1.957,2.875],[-0.435,6],[5,-6]],"o":[[1.848,1.875],[1.957,-2.875],[0.435,-6],[-5,6]],"v":[[404.456,17.75],[410.543,14.375],[419.348,4.625],[410.869,6.875]],"c":true}]},{"t":71.0003255208333,"s":[{"i":[[-0.708,-0.483],[-0.42,0.573],[0.389,0.655],[0.499,-1.177]],"o":[[1.05,0.716],[0.992,-1.354],[-0.735,-1.237],[-0.242,0.571]],"v":[[433.253,-14.046],[435.614,-14.589],[436.296,-17.576],[433.331,-16.399]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":66,"s":[0],"h":1},{"t":66.833,"s":[100],"h":1},{"t":71.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 11","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[5.332,-4.406],[10.05,-7.572],[1.148,-0.821],[-8.315,4.877],[-3.93,2.126]],"o":[[-3.121,2.579],[-3.833,2.888],[2.727,2.148],[6.731,-3.948],[8.785,-4.751]],"v":[[321.037,36.094],[290.353,57.89],[284.11,64.219],[302.203,53.915],[319.584,46.207]],"c":true}]},{"t":71.0003255208333,"s":[{"i":[[1.425,0.375],[0.516,-1.431],[0.049,-0.343],[-0.554,-0.143],[-0.279,0.334]],"o":[[-1.228,-0.324],[-0.141,0.391],[-0.06,0.416],[0.573,0.148],[0.944,-1.131]],"v":[[333.77,22.361],[330.951,24.963],[330.662,26.083],[331.622,26.966],[333.142,26.736]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[331.087,62.625],"ix":2},"a":{"a":0,"k":[283.928,58.982],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-0.198,"ix":6},"o":{"a":1,"k":[{"t":65.166,"s":[1],"h":1},{"t":66,"s":[100],"h":1},{"t":71.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 10","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[6.001,-3.438],[4.622,-1.369],[-9.463,3.193]],"o":[[-4.853,2.78],[-6.364,1.884],[9.463,-3.193]],"v":[[287.03,54.981],[272.713,60.955],[289.158,61.059]],"c":true}]},{"t":68.5003255208333,"s":[{"i":[[1.379,-0.683],[-0.18,-1.043],[-1.179,0.646]],"o":[[-1.734,0.859],[0.188,1.086],[1.764,-0.966]],"v":[[307.257,48.925],[305.837,51.696],[308.931,52.026]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[293.913,77.25],"ix":2},"a":{"a":0,"k":[283.928,58.982],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-0.198,"ix":6},"o":{"a":1,"k":[{"t":64.333,"s":[1],"h":1},{"t":65.166,"s":[100],"h":1},{"t":69.3333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 9","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[2.875,-0.125],[-8.035,-2.12],[-6.725,1.978]],"o":[[-2.875,0.125],[9,2.375],[8.5,-2.5]],"v":[[239.75,63.5],[218.75,70.625],[240.375,70]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[2.876,0.091],[-3.613,-2.264],[-3,1.66]],"o":[[-2.876,-0.091],[4.677,2.93],[7.752,-4.291]],"v":[[248.185,61.363],[234.385,66.845],[249.523,68.399]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.833,"s":[{"i":[[2.781,-0.74],[-1.488,-1.369],[-1.507,2.224]],"o":[[-2.781,0.74],[2.644,2.433],[1.864,-2.752]],"v":[[250.348,60.068],[244.863,65.494],[254.886,64.877]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":67.666,"s":[{"i":[[1.649,-0.439],[-0.882,-0.811],[-0.893,1.319]],"o":[[-1.649,0.439],[1.568,1.442],[1.105,-1.632]],"v":[[252.991,59.068],[251.221,62.433],[255.681,61.919]],"c":true}]},{"t":68.5003255208333,"s":[{"i":[[1.256,-0.334],[-0.672,-0.618],[-0.68,1.004]],"o":[[-1.256,0.334],[1.194,1.098],[0.842,-1.243]],"v":[[254.502,58.588],[253.154,61.152],[256.551,60.76]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[17.826,16],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":64.333,"s":[0],"h":1},{"t":65.166,"s":[100],"h":1},{"t":69.3333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[0,0],[6.25,-5.25],[-8,2.5],[8.5,2.5]],"o":[[0,0],[-6.25,5.25],[8,-2.5],[-8.5,-2.5]],"v":[[101,65.25],[80.75,66.75],[111.75,74.25],[125.5,66.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[0,0],[-3.699,-2.367],[-3.884,2.019],[4.127,2.019]],"o":[[0,0],[2.367,1.514],[3.884,-2.019],[-4.127,-2.019]],"v":[[118.172,64.837],[113.256,70.894],[123.39,72.106],[130.066,65.644]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[0,0],[-1.235,-2.726],[-2.801,1.026],[1.549,1.158]],"o":[[0,0],[0.71,1.566],[2.801,-1.026],[-2.508,-1.874]],"v":[[126.435,64.519],[123.517,68.184],[130.262,69.992],[132.951,65.48]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66.833,"s":[{"i":[[0,0],[-0.755,-1.666],[-1.712,0.627],[0.947,0.708]],"o":[[0,0],[0.434,0.957],[1.712,-0.627],[-1.533,-1.145]],"v":[[129.695,64.355],[127.912,66.595],[132.034,67.7],[133.678,64.942]],"c":true}]},{"t":67.6663411458333,"s":[{"i":[[0,0],[-0.438,-0.966],[-0.993,0.364],[0.549,0.41]],"o":[[0,0],[0.251,0.555],[0.993,-0.364],[-0.889,-0.664]],"v":[[131.885,64.447],[130.852,65.746],[133.242,66.386],[134.195,64.788]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[55.12,18.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":63.5,"s":[0],"h":1},{"t":64.333,"s":[100],"h":1},{"t":68.5003255208333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[0,0],[6.25,-5.25],[-8,2.5],[8.5,2.5]],"o":[[0,0],[-6.25,5.25],[8,-2.5],[-8.5,-2.5]],"v":[[101,65.25],[80.75,66.75],[111.75,74.25],[125.5,66.25]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[0,0],[-3.699,-2.367],[-3.884,2.019],[4.127,2.019]],"o":[[0,0],[2.367,1.514],[3.884,-2.019],[-4.127,-2.019]],"v":[[118.172,64.837],[113.256,70.894],[123.391,72.106],[130.066,65.644]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[0,0],[-1.235,-2.726],[-2.801,1.026],[1.549,1.158]],"o":[[0,0],[0.71,1.566],[2.801,-1.026],[-2.508,-1.874]],"v":[[125.685,65.769],[122.767,69.434],[129.512,71.242],[132.201,66.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[0,0],[-0.755,-1.666],[-1.712,0.627],[0.947,0.708]],"o":[[0,0],[0.434,0.957],[1.712,-0.627],[-1.533,-1.145]],"v":[[129.445,66.855],[127.662,69.095],[131.784,70.2],[133.428,67.442]],"c":true}]},{"t":66.8333333333333,"s":[{"i":[[0,0],[-0.438,-0.966],[-0.993,0.364],[0.549,0.41]],"o":[[0,0],[0.251,0.555],[0.993,-0.364],[-0.889,-0.664]],"v":[[132.073,67.572],[131.039,68.871],[133.429,69.511],[134.382,67.913]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-31.304,15],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":62.666,"s":[0],"h":1},{"t":63.5,"s":[100],"h":1},{"t":67.6663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[4.652,3.866],[0.317,-3.123],[-4.812,-0.938]],"o":[[-4.652,-3.866],[-0.317,3.123],[4.812,0.938]],"v":[[-513.42,73.625],[-538.679,74.835],[-515.78,80.171]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[2.816,2.132],[0.154,-2.732],[-2.47,0.079]],"o":[[-3.241,-2.454],[-0.154,2.732],[2.974,-0.095]],"v":[[-511.191,74.099],[-521.346,75.103],[-512.006,79.608]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[1.529,1.464],[0.083,-1.876],[-1.341,0.054]],"o":[[-1.759,-1.685],[-0.083,1.876],[1.615,-0.065]],"v":[[-509.154,74.587],[-514.667,75.277],[-511.012,78.358]],"c":true}]},{"t":66.8333333333333,"s":[{"i":[[1.046,1.002],[0.057,-1.284],[-0.917,0.037]],"o":[[-1.204,-1.153],[-0.057,1.284],[1.105,-0.045]],"v":[[-508.046,74.925],[-511.818,75.397],[-509.318,77.505]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":63.5,"s":[0],"h":1},{"t":64.333,"s":[100],"h":1},{"t":67.6663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[3.694,2.428],[-0.025,-2.294],[-3.572,-0.288]],"o":[[-3.694,-2.428],[0.025,2.294],[3.572,0.288]],"v":[[-567.944,74.515],[-577.502,78.021],[-570.185,82.462]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[2.581,1.696],[-0.018,-1.603],[-2.496,-0.201]],"o":[[-2.581,-1.696],[0.018,1.603],[2.496,0.201]],"v":[[-564.081,75.39],[-570.76,77.839],[-565.647,80.943]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":66,"s":[{"i":[[1.886,1.239],[-0.013,-1.171],[-1.823,-0.147]],"o":[[-1.886,-1.239],[0.013,1.171],[1.823,0.147]],"v":[[-562.761,75.937],[-567.64,77.726],[-563.905,79.993]],"c":true}]},{"t":66.8333333333333,"s":[{"i":[[1.329,0.736],[-0.009,-0.696],[-1.285,-0.087]],"o":[[-1.329,-0.736],[0.009,0.696],[1.285,0.087]],"v":[[-559.329,76.538],[-562.768,77.601],[-560.136,78.949]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":63.5,"s":[0],"h":1},{"t":64.333,"s":[100],"h":1},{"t":67.6663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.908,0.183],[-0.035,-4.015],[-4.965,-0.504],[-10.464,0.985],[-4.133,0.503],[-0.107,1.024],[13.717,0.931]],"o":[[-6.653,-0.42],[0.035,4.015],[1.388,0.141],[5.467,-0.515],[4.596,-0.559],[0.152,-1.445],[-10.969,-0.745]],"v":[[-566.295,72.587],[-589.833,78.972],[-559.661,83.746],[-536.761,81.379],[-521.818,79.944],[-514.015,77.696],[-533.468,70.031]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":62.666,"s":[0],"h":1},{"t":63.5,"s":[100],"h":1},{"t":64.3333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-4.701,82.841],"ix":2},"a":{"a":0,"k":[-424.093,76.841],"ix":1},"s":{"a":0,"k":[100,-77.71],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":3,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[4.652,3.866],[0.317,-3.123],[-4.812,-0.938]],"o":[[-4.652,-3.866],[-0.317,3.123],[4.812,0.938]],"v":[[-513.42,73.625],[-538.679,74.835],[-515.78,80.171]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[2.816,2.132],[0.154,-2.732],[-2.47,0.079]],"o":[[-3.241,-2.454],[-0.154,2.732],[2.974,-0.095]],"v":[[-511.191,74.099],[-521.346,75.103],[-512.006,79.608]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[1.529,1.464],[0.083,-1.876],[-1.341,0.054]],"o":[[-1.759,-1.685],[-0.083,1.876],[1.615,-0.065]],"v":[[-509.154,74.587],[-514.667,75.277],[-511.012,78.358]],"c":true}]},{"t":66.0003255208333,"s":[{"i":[[1.046,1.002],[0.057,-1.284],[-0.917,0.037]],"o":[[-1.204,-1.153],[-0.057,1.284],[1.105,-0.045]],"v":[[-508.046,74.925],[-511.818,75.397],[-509.318,77.505]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":62.666,"s":[0],"h":1},{"t":63.5,"s":[100],"h":1},{"t":66.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[3.694,2.428],[-0.025,-2.294],[-3.572,-0.288]],"o":[[-3.694,-2.428],[0.025,2.294],[3.572,0.288]],"v":[[-567.944,74.515],[-577.502,78.021],[-570.185,82.462]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":64.333,"s":[{"i":[[2.581,1.696],[-0.018,-1.603],[-2.496,-0.201]],"o":[[-2.581,-1.696],[0.018,1.603],[2.496,0.201]],"v":[[-564.081,75.39],[-570.76,77.839],[-565.647,80.943]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":65.166,"s":[{"i":[[1.886,1.239],[-0.013,-1.171],[-1.823,-0.147]],"o":[[-1.886,-1.239],[0.013,1.171],[1.823,0.147]],"v":[[-562.761,75.937],[-567.64,77.726],[-563.905,79.993]],"c":true}]},{"t":66.0003255208333,"s":[{"i":[[1.329,0.736],[-0.009,-0.696],[-1.285,-0.087]],"o":[[-1.329,-0.736],[0.009,0.696],[1.285,0.087]],"v":[[-559.329,76.538],[-562.768,77.601],[-560.136,78.949]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":62.666,"s":[0],"h":1},{"t":63.5,"s":[100],"h":1},{"t":66.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.908,0.183],[-0.035,-4.015],[-4.965,-0.504],[-10.464,0.985],[-4.133,0.503],[-0.107,1.024],[13.717,0.931]],"o":[[-6.653,-0.42],[0.035,4.015],[1.388,0.141],[5.467,-0.515],[4.596,-0.559],[0.152,-1.445],[-10.969,-0.745]],"v":[[-566.295,72.587],[-589.833,78.972],[-559.661,83.746],[-536.761,81.379],[-521.818,79.944],[-514.015,77.696],[-533.468,70.031]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":61.833,"s":[0],"h":1},{"t":62.666,"s":[100],"h":1},{"t":63.5003255208333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-115.701,82.841],"ix":2},"a":{"a":0,"k":[-424.093,76.841],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":3,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[14.298,-0.054],[0.036,-3.288],[-10.012,-0.052]],"o":[[-10.607,0.04],[-0.043,3.974],[11.703,0.061]],"v":[[-545.673,75.118],[-590.957,80.579],[-545.703,86.128]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[9.143,-0.038],[0.023,-2.29],[-6.402,-0.036]],"o":[[-6.782,0.028],[-0.028,2.768],[7.483,0.043]],"v":[[-534.518,76.79],[-563.472,80.593],[-534.537,84.457]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[6.887,-0.028],[0.017,-1.725],[-4.822,-0.027]],"o":[[-5.109,0.021],[-0.021,2.085],[5.637,0.032]],"v":[[-530.637,77.694],[-538.229,80.567],[-530.651,83.469]],"c":true}]},{"t":64.3333333333333,"s":[{"i":[[1.84,-0.014],[0.005,-0.823],[-1.289,-0.013]],"o":[[-1.365,0.01],[-0.006,0.994],[1.506,0.015]],"v":[[-525.59,79.206],[-527.619,80.576],[-525.594,81.96]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":61,"s":[0],"h":1},{"t":61.833,"s":[100],"h":1},{"t":65.1663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[4.869,1.745],[-0.033,-1.648],[-4.708,-0.207]],"o":[[-4.869,-1.745],[0.033,1.648],[4.708,0.207]],"v":[[-621.244,79.457],[-632.592,82.226],[-622.948,85.418]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[2.36,1.324],[-0.016,-1.251],[-2.281,-0.157]],"o":[[-2.36,-1.324],[0.016,1.251],[2.281,0.157]],"v":[[-618.235,79.99],[-623.734,82.092],[-619.06,84.515]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[1.686,0.946],[-0.012,-0.894],[-1.629,-0.112]],"o":[[-1.686,-0.946],[0.012,0.894],[1.629,0.112]],"v":[[-615.436,80.47],[-619.363,81.971],[-616.025,83.701]],"c":true}]},{"t":64.3333333333333,"s":[{"i":[[0.974,0.547],[-0.007,-0.516],[-0.941,-0.065]],"o":[[-0.974,-0.547],[0.007,0.516],[0.941,0.065]],"v":[[-613.099,80.976],[-615.368,81.843],[-613.44,82.843]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":61,"s":[0],"h":1},{"t":61.833,"s":[100],"h":1},{"t":65.1663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[10.353,2.306],[-0.07,-2.179],[-10.009,-0.274]],"o":[[-10.353,-2.306],[0.07,2.179],[10.009,0.274]],"v":[[-580.173,78.536],[-606.957,81.865],[-586.453,86.084]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[2.976,1.724],[-0.02,-1.629],[-2.877,-0.205]],"o":[[-2.976,-1.724],[0.02,1.629],[2.877,0.205]],"v":[[-574.601,79.232],[-582.3,81.721],[-576.406,84.876]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[1.661,0.651],[-0.012,-0.944],[-1.667,-0.119]],"o":[[-1.855,-0.727],[0.012,0.944],[1.667,0.119]],"v":[[-573.599,80.037],[-576.621,81.52],[-574.27,83.369]],"c":true}]},{"t":64.3333333333333,"s":[{"i":[[0.865,0.339],[-0.006,-0.492],[-0.868,-0.062]],"o":[[-0.966,-0.378],[0.006,0.491],[0.868,0.062]],"v":[[-571.428,80.689],[-573.002,81.462],[-571.777,82.425]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":65.1663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-284.543,85.184],"ix":2},"a":{"a":0,"k":[-567.935,80.684],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":3,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[4.652,3.866],[0.317,-3.123],[-4.812,-0.938]],"o":[[-4.652,-3.866],[-0.317,3.123],[4.812,0.938]],"v":[[-513.42,73.625],[-538.679,74.835],[-515.78,80.171]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[2.816,2.132],[0.154,-2.732],[-2.47,0.079]],"o":[[-3.241,-2.454],[-0.154,2.732],[2.974,-0.095]],"v":[[-511.191,74.099],[-521.346,75.103],[-512.006,79.608]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[1.529,1.464],[0.083,-1.876],[-1.341,0.054]],"o":[[-1.759,-1.685],[-0.083,1.876],[1.615,-0.065]],"v":[[-509.154,74.587],[-514.667,75.277],[-511.012,78.358]],"c":true}]},{"t":64.3333333333333,"s":[{"i":[[1.046,1.002],[0.057,-1.284],[-0.917,0.037]],"o":[[-1.204,-1.153],[-0.057,1.284],[1.105,-0.045]],"v":[[-508.046,74.925],[-511.818,75.397],[-509.318,77.505]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":61,"s":[0],"h":1},{"t":61.833,"s":[100],"h":1},{"t":65.1663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[3.694,2.428],[-0.025,-2.294],[-3.572,-0.288]],"o":[[-3.694,-2.428],[0.025,2.294],[3.572,0.288]],"v":[[-567.944,74.515],[-577.502,78.021],[-570.185,82.462]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[2.581,1.696],[-0.018,-1.603],[-2.496,-0.201]],"o":[[-2.581,-1.696],[0.018,1.603],[2.496,0.201]],"v":[[-564.081,75.39],[-570.76,77.839],[-565.647,80.943]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63.5,"s":[{"i":[[1.886,1.239],[-0.013,-1.171],[-1.823,-0.147]],"o":[[-1.886,-1.239],[0.013,1.171],[1.823,0.147]],"v":[[-562.761,75.937],[-567.64,77.726],[-563.905,79.993]],"c":true}]},{"t":64.3333333333333,"s":[{"i":[[1.329,0.736],[-0.009,-0.696],[-1.285,-0.087]],"o":[[-1.329,-0.736],[0.009,0.696],[1.285,0.087]],"v":[[-559.329,76.538],[-562.768,77.601],[-560.136,78.949]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":61,"s":[0],"h":1},{"t":61.833,"s":[100],"h":1},{"t":65.1663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.908,0.183],[-0.035,-4.015],[-4.965,-0.504],[-10.464,0.985],[-4.133,0.503],[-0.107,1.024],[13.717,0.931]],"o":[[-6.653,-0.42],[0.035,4.015],[1.388,0.141],[5.467,-0.515],[4.596,-0.559],[0.152,-1.445],[-10.969,-0.745]],"v":[[-566.295,72.587],[-589.833,78.972],[-559.661,83.746],[-536.761,81.379],[-521.818,79.944],[-514.015,77.696],[-533.468,70.031]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.25,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":61.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-426.701,87.841],"ix":2},"a":{"a":0,"k":[-424.093,76.841],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[14.298,-0.054],[0.036,-3.288],[-10.012,-0.052]],"o":[[-10.607,0.04],[-0.043,3.974],[11.703,0.061]],"v":[[-571.673,75.179],[-590.957,80.579],[-571.703,86.189]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[7.176,-0.042],[0.018,-2.549],[-5.025,-0.041]],"o":[[-5.323,0.031],[-0.022,3.081],[5.873,0.047]],"v":[[-563.301,77.667],[-572.978,81.853],[-563.316,86.203]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62.666,"s":[{"i":[[3.284,0.186],[0.006,-1.479],[-1.743,-0.063]],"o":[[-1.845,-0.105],[-0.008,1.788],[3.229,0.116]],"v":[[-559.482,79.432],[-562.17,81.888],[-559.487,84.384]],"c":true}]},{"t":63.5003255208333,"s":[{"i":[[2.54,0.144],[0.005,-1.144],[-1.348,-0.048]],"o":[[-1.427,-0.081],[-0.006,1.382],[2.497,0.09]],"v":[[-556.29,79.994],[-558.369,81.894],[-556.294,83.824]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.935,-4.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":64.3333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[-3.416,-2.174],[0.023,2.053],[3.303,0.258]],"o":[[3.416,2.174],[-0.023,-2.053],[-3.303,-0.258]],"v":[[-622.236,85.018],[-613.398,81.88],[-620.164,77.904]],"c":true}]},{"t":61.8333333333333,"s":[{"i":[[2.025,1.288],[-0.014,-1.217],[-1.958,-0.153]],"o":[[-2.025,-1.288],[0.014,1.217],[1.958,0.153]],"v":[[-609.15,80.128],[-614.389,81.988],[-610.378,84.345]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-4.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":62.6663411458333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[10.353,2.306],[-0.07,-2.179],[-10.009,-0.274]],"o":[[-10.353,-2.306],[0.07,2.179],[10.009,0.274]],"v":[[-580.173,78.536],[-606.957,81.865],[-586.453,86.084]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61.833,"s":[{"i":[[2.976,1.724],[-0.02,-1.629],[-2.877,-0.205]],"o":[[-2.976,-1.724],[0.02,1.629],[2.877,0.205]],"v":[[-574.601,79.232],[-582.3,81.721],[-576.406,84.876]],"c":true}]},{"t":62.6663411458333,"s":[{"i":[[1.661,0.651],[-0.012,-0.944],[-1.667,-0.119]],"o":[[-1.855,-0.727],[0.012,0.944],[1.667,0.119]],"v":[[-573.599,80.037],[-576.621,81.52],[-574.27,83.369]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-4.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":63.5003255208333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-570.543,87.684],"ix":2},"a":{"a":0,"k":[-567.935,80.684],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":3,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.49,1.863],[0,0],[-7.181,0.153]],"o":[[-7.49,-1.863],[0,0],[7.181,-0.153]],"v":[[-661.49,79.935],[-687.038,82.701],[-668.091,85.619]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.047058868408,0,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[21.739,1.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":60.166,"s":[0],"h":1},{"t":61,"s":[100],"h":1},{"t":61.8333333333333,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false}],"ip":61,"op":75.1666666666667,"st":56.8333333333333,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,539.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0,0,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":13,"s":[971,971,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.456,0],[0,-7.456],[-7.456,0],[0,7.456]],"o":[[-7.456,0],[0,7.456],[7.456,0],[0,-7.456]],"v":[[0.75,-10.75],[-12.75,2.75],[0.75,16.25],[14.25,2.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0],"y":[0]},"t":0,"s":[41]},{"t":23.8974609375,"s":[0]}],"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0.5,2.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":23,"st":-2,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-29],[1104,-195.999]],"o":[[0,0],[0,770],[0,0.001]],"v":[[-117.997,-146.999],[-118,146],[0,-0.001]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[48]},{"t":56,"s":[-41]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[0]},{"t":26.09375,"s":[4]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[296]},{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"t":45,"s":[182.4]},{"t":66,"s":[44]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":57.7,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":25,"op":57,"st":25,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-118,1028]],"o":[[0,0],[762,0],[0,-36]],"v":[[-30,117],[146,117],[0,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[48]},{"t":48,"s":[-41]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"t":18.09375,"s":[4]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":17,"s":[296]},{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"t":37,"s":[182.4]},{"t":61,"s":[44]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":17,"op":49,"st":17,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[30,0],[34.001,998]],"o":[[0,0],[-934,0],[0,-340]],"v":[[144,0],[-30,0],[0,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[48]},{"t":40,"s":[-41]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[0]},{"t":10.09375,"s":[4]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[296]},{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"t":29.227,"s":[182.4]},{"t":48,"s":[44]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9,"op":39,"st":9,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-1040]],"o":[[0,0],[898,0],[0,1172]],"v":[[-30,-118],[146,-118],[0,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[48]},{"t":30,"s":[-41]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-1,"s":[0]},{"t":0.09375,"s":[4]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":-1,"s":[296]},{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"t":19.227,"s":[182.4]},{"t":43,"s":[44]}],"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-1,"op":31,"st":-1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"E-SideLine Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[842,539.5,0],"ix":2},"a":{"a":0,"k":[30,147.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":56,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.638,148.405],[-29,148.405]],"c":true}]},{"i":{"x":0.45,"y":1},"o":{"x":0.792,"y":0},"t":61,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.319,-276.595],[-29.319,-276.595]],"c":true}]},{"i":{"x":0.353,"y":1},"o":{"x":0.766,"y":0},"t":68,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.479,-64.095],[-29.16,-64.095]],"c":true}]},{"i":{"x":0.329,"y":1},"o":{"x":0.699,"y":0},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.387,-185.524],[-29.251,-185.524]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":81,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.44,-116.136],[-29.199,-116.136]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":87,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.414,-150.83],[-29.225,-150.83]],"c":true}]},{"t":93,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.319,146.595],[29.319,146.595],[29.319,-146.595],[-29.319,-146.595]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.223,295.033],"ix":2},"a":{"a":0,"k":[0,147.516],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":57,"op":13182,"st":55,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"E-1rdLine Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":47,"s":[1068.739,656.907,0],"to":[0,0,0],"ti":[0,0,0]},{"t":76,"s":[928.739,656.907,0]}],"ix":2},"a":{"a":0,"k":[89,30,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":47,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[87.958,-29.319],[90.042,-29.731],[90.042,28.907],[87.958,29.319]],"c":true}]},{"t":66,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[87.958,-29.319],[-87.958,-29.319],[-87.958,29.319],[87.958,29.319]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.119,29.774],"ix":2},"a":{"a":0,"k":[89.1,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":49,"op":13174,"st":47,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"E-2ndLine Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":38,"s":[918,539.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":66,"s":[1018,539.5,0]}],"ix":2},"a":{"a":0,"k":[89,30.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":38,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-87.042,-29.638],[-87.958,-29.319],[-87.958,29.319],[-87.042,29]],"c":true}]},{"t":56,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[87.958,-29.319],[-87.958,-29.319],[-87.958,29.319],[87.958,29.319]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.119,30.497],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":39,"op":13164,"st":37,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"E-1stLine Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":28,"s":[1158,422,0],"to":[0,0,0],"ti":[0,0,0]},{"t":57,"s":[1018,422,0]}],"ix":2},"a":{"a":0,"k":[89,30,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"t":28,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[87.958,-29.319],[88.042,-28.319],[88.042,30.319],[87.958,29.319]],"c":true}]},{"t":47,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[87.958,-29.319],[-87.958,-29.319],[-87.958,29.319],[87.958,29.319]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.482352941176,0.898039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.119,30.221],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":31,"op":13155,"st":28,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Circle Outlines 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[959.5,539.5,0],"ix":2},"a":{"a":0,"k":[352.5,352.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.994,0.994,0.667],"y":[1,1,1]},"o":{"x":[1,1,0.333],"y":[0,0,0]},"t":29,"s":[0,0,100]},{"t":40,"s":[100,100,100]}],"ix":6,"x":"var $bm_rt;\nvar damping, elasticity, speedLimit, tempsClefProx, tempsDebut, tempsDebut, temps, spring, spring;\nvar fx = effect('Transform Spring');\ndamping = fx(2).value;\nelasticity = fx(1).value;\n$bm_rt = speedLimit = 0.1;\nif (numKeys > 1 && elasticity != 0) {\n if (nearestKey(time).index == 1) {\n $bm_rt = value;\n } else {\n if (length(velocity) <= speedLimit) {\n tempsClefProx = nearestKey(time).time;\n if (tempsClefProx <= time) {\n tempsDebut = tempsClefProx;\n } else {\n tempsDebut = key($bm_sub(nearestKey(time).index, 1)).time;\n }\n temps = $bm_sub(time, tempsDebut);\n spring = $bm_mul(velocityAtTime($bm_sub(tempsDebut, thisComp.frameDuration)), $bm_div($bm_mul($bm_div(0.15, elasticity), Math.sin($bm_mul($bm_mul($bm_mul(elasticity, temps), 2), Math.PI))), Math.exp($bm_mul(temps, damping))));\n if (speedLimit > 0)\n spring = $bm_mul(spring, $bm_sub(1, $bm_div(length(velocity), speedLimit)));\n $bm_rt = $bm_sum(valueAtTime(tempsDebut), spring);\n } else {\n $bm_rt = value;\n }\n }\n} else {\n $bm_rt = value;\n}"}},"ao":0,"ef":[{"ty":5,"nm":"Transform Spring","np":4,"mn":"Pseudo/DUIK multid spring","ix":1,"en":1,"ef":[{"ty":0,"nm":"Elasticity","mn":"Pseudo/DUIK multid spring-0001","ix":1,"v":{"a":0,"k":2.68,"ix":1}},{"ty":0,"nm":"Damping","mn":"Pseudo/DUIK multid spring-0002","ix":2,"v":{"a":0,"k":5.2,"ix":2}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-194.308],[-194.308,0],[0,194.308],[194.308,0]],"o":[[0,194.308],[194.308,0],[0,-194.308],[-194.308,0]],"v":[[-351.829,0],[0,351.829],[351.829,0],[0,-351.829]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.572549019608,0,0.23137254902,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[352.5,352.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29,"op":13156,"st":29,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/modules/lottie/classes/caption-helper.php b/modules/lottie/classes/caption-helper.php new file mode 100644 index 00000000..dc7a237b --- /dev/null +++ b/modules/lottie/classes/caption-helper.php @@ -0,0 +1,103 @@ +wp_adapter = $wp_adapter; + $this->settings = $settings; + } + + public function get_caption() { + if ( $this->has_custom_caption() ) { + return $this->get_custom_caption(); + } + + if ( $this->has_attachment_caption() ) { + return $this->get_attachment_caption(); + } + + if ( $this->has_title_caption() ) { + return $this->get_title_caption(); + } + + return ''; + } + + private function get_custom_caption() { + return $this->settings['caption'] ?? ''; + } + + private function get_attachment_caption() { + $attachment_id = $this->settings['source_json']['id']; + + if ( ! $this->user_can_access( $attachment_id ) ) { + return ''; + } + + return $this->wp_adapter->wp_get_attachment_caption( $attachment_id ); + } + + private function get_title_caption() { + $post_id = $this->settings['source_json']['id']; + + if ( ! $this->user_can_access( $post_id ) ) { + return ''; + } + + return $this->wp_adapter->get_the_title( $post_id ); + } + + private function user_can_access( $resource_id ) { + if ( $this->wp_adapter->current_user_can( 'manage_options' ) ) { + return true; + } + + if ( $this->wp_adapter->current_user_can( 'edit_post', $resource_id ) ) { + return true; + } + + if ( $this->wp_adapter->current_user_can( 'read_post', $resource_id ) ) { + return true; + } + + return false; + } + + private function has_title_caption() { + return 'title' === $this->settings['caption_source']; + } + + private function has_custom_caption() { + if ( $this->is_external_url_caption() ) { + return true; + } + + if ( 'custom' === $this->settings['caption_source'] ) { + return $this->is_media_file_caption(); + } + + return false; + } + + private function has_attachment_caption() { + return 'caption' === $this->settings['caption_source']; + } + + private function is_media_file_caption() { + return 'media_file' === $this->settings['source'] && 'none' !== $this->settings['caption_source']; + } + + private function is_external_url_caption() { + return 'external_url' === $this->settings['source'] && '' !== $this->settings['caption']; + } +} diff --git a/modules/lottie/module.php b/modules/lottie/module.php new file mode 100644 index 00000000..48410455 --- /dev/null +++ b/modules/lottie/module.php @@ -0,0 +1,103 @@ +get_css_assets_url( 'widget-lottie', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + // Fixing wordpress problem when `finfo_file()` returns wrong file type + public function handle_file_type( $file_data, $file, $filename ) { + if ( $file_data['ext'] && $file_data['type'] ) { + return $file_data; + } + + $filetype = wp_check_filetype( $filename ); + + if ( 'json' === $filetype['ext'] ) { + $file_data['ext'] = 'json'; + $file_data['type'] = 'application/json'; + } + + return $file_data; + } + + public function register_frontend_scripts() { + $suffix = Utils::is_script_debug() ? '' : '.min'; + + wp_register_script( + 'lottie', + ELEMENTOR_PRO_URL . 'assets/lib/lottie/lottie' . $suffix . '.js', + [ + 'jquery', + ], + '5.6.6', + true + ); + } + + public function localize_settings( array $settings ) { + $settings['lottie']['defaultAnimationUrl'] = ELEMENTOR_PRO_MODULES_URL . 'lottie/assets/animations/default.json'; + + return $settings; + } +} diff --git a/modules/lottie/widgets/lottie.php b/modules/lottie/widgets/lottie.php new file mode 100644 index 00000000..2f7e3b18 --- /dev/null +++ b/modules/lottie/widgets/lottie.php @@ -0,0 +1,885 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_style_depends(): array { + return [ 'widget-lottie', 'e-lottie' ]; + } + + protected function current_user_can_use_external_source() { + return current_user_can( 'publish_pages' ); + } + + protected function get_source_options() { + $options = [ + 'media_file' => esc_html__( 'Media File', 'elementor-pro' ), + ]; + + if ( $this->current_user_can_use_external_source() ) { + $options['external_url'] = esc_html__( 'External URL', 'elementor-pro' ); + } + + return $options; + } + + protected function register_controls() { + $this->start_controls_section( 'lottie', [ + 'label' => esc_html__( 'Lottie', 'elementor-pro' ), + ] ); + + $this->add_control( + 'source', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'media_file', + 'options' => $this->get_source_options(), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'source_external_url', + [ + 'label' => esc_html__( 'External URL', 'elementor-pro' ), + 'type' => $this->current_user_can_use_external_source() ? Controls_Manager::URL : Controls_Manager::HIDDEN, + 'condition' => [ + 'source' => 'external_url', + ], + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Enter your URL', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'source_json', + [ + 'label' => esc_html__( 'Upload JSON File', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'media_types' => [ 'application/json' ], + 'frontend_available' => true, + 'condition' => [ + 'source' => 'media_file', + ], + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor%s-align-', + 'default' => 'center', + ] + ); + + $this->add_control( + 'caption_source', + [ + 'label' => esc_html__( 'Caption', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'none', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'caption' => esc_html__( 'Caption', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'condition' => [ + 'source!' => 'external_url', + 'source_json[url]!' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'caption', + [ + 'label' => esc_html__( 'Custom Caption', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'caption_source', + 'value' => 'custom', + ], + [ + 'name' => 'source', + 'value' => 'external_url', + ], + ], + ], + 'dynamic' => [ + 'active' => true, + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'link_to', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'render_type' => 'none', + 'default' => 'none', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom URL', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'custom_link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'render_type' => 'none', + 'placeholder' => esc_html__( 'Enter your URL', 'elementor-pro' ), + 'condition' => [ + 'link_to' => 'custom', + ], + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'url' => '', + ], + 'show_label' => false, + 'frontend_available' => true, + ] + ); + + // lottie. + $this->end_controls_section(); + + $this->start_controls_section( 'settings', [ + 'label' => esc_html__( 'Settings', 'elementor-pro' ), + ] ); + + $this->add_control( + 'trigger', + [ + 'label' => esc_html__( 'Trigger', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'arriving_to_viewport', + 'options' => [ + 'arriving_to_viewport' => esc_html__( 'Viewport', 'elementor-pro' ), + 'on_click' => esc_html__( 'On Click', 'elementor-pro' ), + 'on_hover' => esc_html__( 'On Hover', 'elementor-pro' ), + 'bind_to_scroll' => esc_html__( 'Scroll', 'elementor-pro' ), + 'none' => esc_html__( 'None', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'viewport', + [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'trigger', + 'operator' => '===', + 'value' => 'arriving_to_viewport', + ], + [ + 'name' => 'trigger', + 'operator' => '===', + 'value' => 'bind_to_scroll', + ], + ], + ], + 'default' => [ + 'sizes' => [ + 'start' => 0, + 'end' => 100, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'effects_relative_to', + [ + 'label' => esc_html__( 'Effects Relative To', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'render_type' => 'none', + 'condition' => [ + 'trigger' => 'bind_to_scroll', + ], + 'default' => 'viewport', + 'options' => [ + 'viewport' => esc_html__( 'Viewport', 'elementor-pro' ), + 'page' => esc_html__( 'Entire Page', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'loop', + [ + 'label' => esc_html__( 'Loop', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'render_type' => 'none', + 'condition' => [ + 'trigger!' => 'bind_to_scroll', + ], + 'return_value' => 'yes', + 'default' => '', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'number_of_times', + [ + 'label' => esc_html__( 'Times', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'trigger', + 'operator' => '!==', + 'value' => 'bind_to_scroll', + ], + [ + 'name' => 'loop', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + 'min' => 0, + 'step' => 1, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'link_timeout', + [ + 'label' => esc_html__( 'Link Timeout', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'link_to', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'trigger', + 'operator' => '===', + 'value' => 'on_click', + ], + [ + 'name' => 'custom_link[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + 'description' => esc_html__( 'Redirect to link after selected timeout', 'elementor-pro' ), + 'min' => 0, + 'max' => 5000, + 'step' => 1, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'on_hover_out', + [ + 'label' => esc_html__( 'On Hover Out', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'render_type' => 'none', + 'condition' => [ + 'trigger' => 'on_hover', + ], + 'default' => 'default', + 'options' => [ + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'reverse' => esc_html__( 'Reverse', 'elementor-pro' ), + 'pause' => esc_html__( 'Pause', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'hover_area', + [ + 'label' => esc_html__( 'Hover Area', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'render_type' => 'none', + 'condition' => [ + 'trigger' => 'on_hover', + ], + 'default' => 'animation', + 'options' => [ + 'animation' => esc_html__( 'Animation', 'elementor-pro' ), + 'column' => esc_html__( 'Column', 'elementor-pro' ), + 'section' => esc_html__( 'Section', 'elementor-pro' ), + 'container' => esc_html__( 'Container', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'play_speed', + [ + 'label' => esc_html__( 'Play Speed', 'elementor-pro' ) . ' (x)', + 'type' => Controls_Manager::SLIDER, + 'render_type' => 'none', + 'condition' => [ + 'trigger!' => 'bind_to_scroll', + ], + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'min' => 0.1, + 'max' => 5, + 'step' => 0.1, + ], + ], + 'size_units' => [ 'px' ], + 'dynamic' => [ + 'active' => true, + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'start_point', + [ + 'label' => esc_html__( 'Start Point', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'frontend_available' => true, + 'render_type' => 'none', + 'default' => [ + 'size' => 0, + 'unit' => '%', + ], + 'size_units' => [ '%' ], + ] + ); + + $this->add_control( + 'end_point', + [ + 'label' => esc_html__( 'End Point', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'frontend_available' => true, + 'render_type' => 'none', + 'default' => [ + 'size' => 100, + 'unit' => '%', + ], + 'size_units' => [ '%' ], + ] + ); + + $this->add_control( + 'reverse_animation', + [ + 'label' => esc_html__( 'Reverse', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'render_type' => 'none', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'trigger', + 'operator' => '!==', + 'value' => 'bind_to_scroll', + ], + [ + 'name' => 'trigger', + 'operator' => '!==', + 'value' => 'on_hover', + ], + ], + ], + 'return_value' => 'yes', + 'default' => '', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'renderer', + [ + 'label' => esc_html__( 'Renderer', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'svg', + 'options' => [ + 'svg' => esc_html__( 'SVG', 'elementor-pro' ), + 'canvas' => esc_html__( 'Canvas', 'elementor-pro' ), + ], + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'lazyload', + [ + 'label' => esc_html__( 'Lazy Load', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'yes', + 'default' => '', + 'frontend_available' => true, + ] + ); + + // Settings. + $this->end_controls_section(); + + $this->start_controls_section( + 'style', + [ + 'label' => esc_html__( 'Lottie', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 1, + 'max' => 100, + ], + 'px' => [ + 'min' => 1, + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + 'vw' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--lottie-container-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'space', + [ + 'label' => esc_html__( 'Max Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 1, + 'max' => 100, + ], + 'px' => [ + 'min' => 1, + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + 'vw' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--lottie-container-max-width: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->start_controls_tabs( 'image_effects' ); + + $this->start_controls_tab( 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'opacity', + [ + 'label' => esc_html__( 'Opacity', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 1, + 'min' => 0.10, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--lottie-container-opacity: {{SIZE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'css_filters', + 'selector' => '{{WRAPPER}} .e-lottie__container', + ] + ); + + // Normal. + $this->end_controls_tab(); + + $this->start_controls_tab( 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'opacity_hover', + [ + 'label' => esc_html__( 'Opacity', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 1, + 'min' => 0.10, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--lottie-container-opacity-hover: {{SIZE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'css_filters_hover', + 'selector' => '{{WRAPPER}} .e-lottie__container:hover', + ] + ); + + $this->add_control( + 'background_hover_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (s)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--lottie-container-transition-duration-hover: {{SIZE}}s', + ], + ] + ); + + // Hover. + $this->end_controls_tab(); + + // Image effects. + $this->end_controls_tabs(); + + // lottie style. + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_caption', + [ + 'label' => esc_html__( 'Caption', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'caption_source!' => 'none', + ], + ] + ); + + $this->add_control( + 'caption_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}}' => '--caption-text-align: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => '--caption-color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'caption_typography', + 'selector' => '{{WRAPPER}} .e-lottie__caption', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_responsive_control( + 'caption_space', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--caption-margin-top: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + private function wp_adapter() { + return new Wordpress_Adapter(); + } + + private function get_caption( $settings ) { + return ( new Caption_Helper( $this->wp_adapter(), $settings ) ) + ->get_caption(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $caption = $this->get_caption( $settings ); + $widget_caption = $caption ? '

      ' . esc_html( $caption ) . '

      ' : ''; + $widget_container = '
      ' . $widget_caption . '
      '; + + if ( ! empty( $settings['custom_link']['url'] ) && 'custom' === $settings['link_to'] ) { + $this->add_link_attributes( 'url', $settings['custom_link'] ); + $widget_container = sprintf( '%2$s', $this->get_render_attribute_string( 'url' ), $widget_container ); + } + + // PHPCS - XSS ok. Everything that should be escaped in the way is escaped. + echo $widget_container; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + protected function content_template() { + ?> + <# + var ensureAttachmentData = function( id, type ) { + if ( 'caption' === type || 'title' === type ) { + if ( 'undefined' === typeof wp.media.attachment( id ).get( type ) ) { + wp.media.attachment( id ).fetch().then( function( data ) { + view.render(); + } ); + } + } + }; + + var getAttachmentData = function( id, type ) { + if ( id && ( 'caption' === type || 'title' === type ) ) { + ensureAttachmentData( id, type ); + return wp.media.attachment( id ).get( type ); + } + + return ''; + }; + + var getCaption = function() { + if ( ( isMediaFileCaption() && 'custom' === settings.caption_source ) || isExternalUrlCaption() ) { + return settings.caption; + } else if ( 'caption' === settings.caption_source || 'title' === settings.caption_source ) { + return getAttachmentData( settings.source_json.id, settings.caption_source ); + } + + return ''; + }; + + var isMediaFileCaption = function() { + return 'media_file' === settings.source && 'none' !== settings.caption_source; + }; + + var isExternalUrlCaption = function() { + return 'external_url' === settings.source && '' !== settings.caption; + }; + + var widget_caption = getCaption() ? '

      ' + getCaption() + '

      ' : ''; + var widget_container = '
      ' + widget_caption + '
      '; + + if ( settings.custom_link?.url && 'custom' === settings.link_to ) { + widget_container = '' + widget_container + ''; + } + + print( widget_container ); + #> + esc_html__( 'Fade in', 'elementor-pro' ), + ]; + } +} diff --git a/modules/mega-menu/module.php b/modules/mega-menu/module.php new file mode 100644 index 00000000..f4ca14b3 --- /dev/null +++ b/modules/mega-menu/module.php @@ -0,0 +1,103 @@ +register( new Control_Menu_Dropdown_Animation() ); + } ); + } + + public function get_widgets() { + return [ + 'Mega_Menu', + ]; + } + + public function get_name() { + return 'mega-menu'; + } + + public static function is_active() { + return Plugin::elementor()->experiments->is_feature_active( \Elementor\Modules\NestedElements\Module::EXPERIMENT_NAME ); + } + + /** + * Add to the experiments + * + * @return array + */ + public static function get_experimental_data() { + $experiment_data = [ + 'name' => static::EXPERIMENT_NAME, + 'title' => esc_html__( 'Menu', 'elementor-pro' ), + 'description' => sprintf( + esc_html__( 'Create beautiful menus and mega menus with new nested capabilities. Mega menus are ideal for websites with complex navigation structures and unique designs. %1$sLearn More%2$s', 'elementor-pro' ), + '', + '' + ), + 'hidden' => false, + 'release_status' => Manager::RELEASE_STATUS_BETA, + 'default' => Manager::STATE_INACTIVE, + 'new_site' => [ + 'default_active' => true, + 'minimum_installation_version' => '3.30.0', + ], + 'dependencies' => [ + 'container', + ], + ]; + + if ( version_compare( ELEMENTOR_VERSION, '3.11.0', '<' ) ) { + $experiment_data['mutable'] = false; + $experiment_data['dependencies'] = []; + } + return $experiment_data; + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/mega-menu/assets/scss/frontend.scss` + * to `/assets/css/widget-mega-menu.min.css`. + * + * @return void + */ + public function register_styles() { + $direction_suffix = is_rtl() ? '-rtl' : ''; + $has_custom_breakpoints = Plugin::elementor()->breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-mega-menu', + Plugin::get_frontend_file_url( "widget-mega-menu{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/mega-menu/traits/url-helper-trait.php b/modules/mega-menu/traits/url-helper-trait.php new file mode 100644 index 00000000..b6e40105 --- /dev/null +++ b/modules/mega-menu/traits/url-helper-trait.php @@ -0,0 +1,44 @@ + ! empty( $link_array['host'] ) ? str_replace( 'www.', '', $link_array['host'] ) : '', + 'path' => ! empty( $link_array['path'] ) ? trim( $link_array['path'], '/' ) : '', + 'query' => ! empty( $link_array['query'] ) ? $link_array['query'] : '', + ]; + } + + public function get_permalink_for_current_page() { + if ( ! is_front_page() && is_home() ) { + return get_post_type_archive_link( 'post' ); + } elseif ( is_front_page() && is_home() ) { + return home_url(); + } elseif ( is_year() ) { + return get_year_link( get_query_var( 'year' ) ); + } elseif ( is_month() ) { + return get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ); + } elseif ( is_day() ) { + return get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) ); + } elseif ( is_category() || is_tag() || is_tax() ) { + $queried_object = get_queried_object(); + return get_term_link( $queried_object->term_id, $queried_object->taxonomy ); + } elseif ( is_author() ) { + return get_author_posts_url( get_the_author_meta( 'ID' ) ); + } elseif ( is_search() ) { + return get_search_link(); + } elseif ( is_archive() ) { + return get_post_type_archive_link( get_post_type() ); + } + + return ! ( empty( get_the_permalink() ) ) ? get_the_permalink() : ''; + } +} diff --git a/modules/mega-menu/widgets/mega-menu.php b/modules/mega-menu/widgets/mega-menu.php new file mode 100644 index 00000000..b5560e41 --- /dev/null +++ b/modules/mega-menu/widgets/mega-menu.php @@ -0,0 +1,2649 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * @return array[] + */ + private function get_content_horizontal_controls(): array { + $horizontal_controls = [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ]; + + return is_rtl() ? array_reverse( $horizontal_controls ) : $horizontal_controls; + } + + protected function get_default_children_elements() { + return [ + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Item #1', 'elementor-pro' ), + ], + ], + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Item #2', 'elementor-pro' ), + ], + ], + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Item #3', 'elementor-pro' ), + ], + ], + ]; + } + + protected function get_default_repeater_title_setting_key() { + return 'item_title'; + } + + protected function get_default_children_title() { + return esc_html__( 'Item #%d', 'elementor-pro' ); + } + + protected function get_default_children_placeholder_selector() { + return '.e-n-menu-heading'; + } + + protected function get_default_children_container_placeholder_selector() { + return '.e-n-menu-content'; + } + + protected function get_html_wrapper_class() { + return 'elementor-widget-n-menu'; + } + + /** + * Define a selector class for a widget control. + * + * @param string $item The name of the element which we need to select. + * @param string $state The state of the selector, e.g. `:hover` or `:focus`. + * + * @return string The css selector for our element. + * @since 3.12.0 + */ + protected function get_control_selector_class( $control_item, $state = '' ) { + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + $widget_container_selector = $optimized_markup ? '' : ' > .elementor-widget-container'; + + if ( 'menu_toggle_icon' === $control_item ) { + return "{{WRAPPER}}{$widget_container_selector} > .e-n-menu > .e-n-menu-toggle{$state} > .e-n-menu-toggle-icon"; + } elseif ( 'active_content_container' === $control_item ) { + return ":where( {{WRAPPER}}{$widget_container_selector} > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content ) > .e-con{$state}"; + } + } + + /** + * Get Typography Selector + * + * Returns a selector class for the typography widget control. + * + * @param string $heading_selector The css selector for the menu. + * + * @return string The css selector for the typography control. + */ + protected function get_typography_selector( $heading_selector ): string { + $typography_selector = "{$heading_selector} > .e-n-menu-item > .e-n-menu-title"; + $typography_selector .= ", {$heading_selector} > .e-n-menu-item > .e-n-menu-title > .e-n-menu-title-container"; + $typography_selector .= ", {$heading_selector} > .e-n-menu-item > .e-n-menu-title > .e-n-menu-title-container > span"; + + return $typography_selector; + } + + protected function register_controls() { + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + $widget_container_selector = $optimized_markup ? '' : ' > .elementor-widget-container'; + $heading_selector = "{{WRAPPER}}{$widget_container_selector} > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading"; + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + $logical_dimensions_inline_start = is_rtl() ? '{{RIGHT}}{{UNIT}}' : '{{LEFT}}{{UNIT}}'; + $logical_dimensions_inline_end = is_rtl() ? '{{LEFT}}{{UNIT}}' : '{{RIGHT}}{{UNIT}}'; + $start_logical = is_rtl() ? 'end' : 'start'; + $end_logical = is_rtl() ? 'start' : 'end'; + + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'menu_name', + [ + 'label' => esc_html__( 'Menu Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Menu', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'item_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Item Title', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + ] + ); + + $repeater->add_control( + 'item_link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'placeholder' => esc_html__( 'Paste URL or type', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'frontend_available' => true, + ] + ); + + $repeater->add_control( + 'item_dropdown_content', + [ + 'label' => esc_html__( 'Dropdown Content', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'OFF', 'elementor-pro' ), + 'label_on' => esc_html__( 'ON', 'elementor-pro' ), + 'default' => 'no', + 'description' => esc_html__( 'Click on the menu item to edit its dropdown content.', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $repeater->add_control( + 'item_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $repeater->add_control( + 'item_icon_active', + [ + 'label' => esc_html__( 'Active Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'item_icon[value]!' => '', + ], + ] + ); + + $repeater->add_control( + 'element_id', + [ + 'label' => esc_html__( 'CSS ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor-pro' ), + 'style_transfer' => false, + ] + ); + + $this->add_control( + 'menu_items', + [ + 'label' => esc_html__( 'Menu Items', 'elementor-pro' ), + 'type' => Control_Nested_Repeater::CONTROL_TYPE, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'item_title' => esc_html__( 'Item #1', 'elementor-pro' ), + ], + [ + 'item_title' => esc_html__( 'Item #2', 'elementor-pro' ), + ], + [ + 'item_title' => esc_html__( 'Item #3', 'elementor-pro' ), + ], + ], + 'title_field' => '{{{ item_title }}}', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'content_width', + [ + 'label' => esc_html__( 'Content Width', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'full_width', + 'separator' => 'before', + 'options' => [ + 'full_width' => esc_html__( 'Full Width', 'elementor-pro' ), + 'fit_to_content' => esc_html__( 'Fit To Content', 'elementor-pro' ), + ], + 'prefix_class' => 'e-', + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-content-max-width: {{VALUE}};', + ], + 'selectors_dictionary' => [ + 'full_width' => 'initial', + 'fit_to_content' => 'fit-content', + ], + ] + ); + + $this->add_control( + 'content_horizontal_position', + [ + 'label' => esc_html__( 'Content Horizontal Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => $this->get_content_horizontal_controls(), + 'default' => 'center', + 'condition' => [ + 'content_width' => 'fit_to_content', + ], + 'frontend_available' => true, + 'render_type' => 'ui', + ] + ); + + $this->add_control( + 'item_layout', + [ + 'label' => esc_html__( 'Item Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'horizontal', + 'options' => [ + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'dropdown' => esc_html__( 'Dropdown', 'elementor-pro' ), + ], + 'prefix_class' => 'e-n-menu-layout-', + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( 'item_position_horizontal', [ + 'label' => esc_html__( 'Item Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-align-$start_logical-h", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-align-$end_logical-h", + ], + 'stretch' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-align-stretch-h', + ], + ], + 'selectors_dictionary' => [ + 'start' => '--n-menu-heading-justify-content: initial; --n-menu-title-flex-grow: initial; --n-menu-title-justify-content: initial; --n-menu-title-justify-content-mobile: initial;', + 'center' => '--n-menu-heading-justify-content: center; --n-menu-title-flex-grow: initial; --n-menu-title-justify-content: initial; --n-menu-title-justify-content-mobile: center;', + 'end' => '--n-menu-heading-justify-content: flex-end; --n-menu-title-flex-grow: initial; --n-menu-title-justify-content: initial; --n-menu-title-justify-content-mobile: flex-end;', + 'stretch' => '--n-menu-heading-justify-content: space-between; --n-menu-title-flex-grow: 1; --n-menu-title-justify-content: center; --n-menu-title-justify-content-mobile: center;', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'condition' => [ + 'item_layout' => 'horizontal', + ], + 'frontend_available' => true, + ]); + + $this->add_responsive_control( 'item_position_dropdown', [ + 'label' => esc_html__( 'Item Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-align-$start_logical-h", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-align-$end_logical-h", + ], + ], + 'selectors_dictionary' => [ + 'start' => '--n-menu-title-justify-content: initial; --n-menu-title-justify-content-mobile: initial;', + 'center' => '--n-menu-title-justify-content: center; --n-menu-title-justify-content-mobile: center;', + 'end' => '--n-menu-title-justify-content: flex-end; --n-menu-title-justify-content-mobile: flex-end;', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'condition' => [ + 'item_layout' => 'dropdown', + ], + ]); + + $this->add_control( + 'submenu_indicator_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dropdown Indicator', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'menu_item_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'default' => [ + 'value' => 'fas fa-caret-down', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-down', + 'angle-down', + 'angle-double-down', + 'caret-down', + 'caret-square-down', + ], + 'fa-regular' => [ + 'caret-square-down', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $this->add_control( + 'menu_item_icon_active', + [ + 'label' => esc_html__( 'Active Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon_active', + 'default' => [ + 'value' => 'fas fa-caret-up', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-up', + 'angle-up', + 'angle-double-up', + 'caret-up', + 'caret-square-up', + ], + 'fa-regular' => [ + 'caret-square-up', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_dropdown_effect', [ + 'label' => esc_html__( 'Dropdown Effect', 'elementor-pro' ), + ] ); + + $this->add_control( + 'open_on', + [ + 'label' => esc_html__( 'Open On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'hover', + 'options' => [ + 'hover' => esc_html__( 'Hover', 'elementor-pro' ), + 'click' => esc_html__( 'Click', 'elementor-pro' ), + ], + 'condition' => [ + 'item_layout' => 'horizontal', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'open_on_hover_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'The hover effect is inactive while editing. Preview your page to see it in action.', 'elementor-pro' ), + 'content_classes' => 'elementor-control-field-description', + 'condition' => [ + 'item_layout' => 'horizontal', + 'open_on' => 'hover', + ], + ] + ); + + $this->add_control( + 'open_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Control_Menu_Dropdown_Animation::TYPE, + 'default' => '', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'open_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + 'size' => 500, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-open-animation-duration: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'open_animation!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( 'menu_toggle_section', [ + 'label' => esc_html__( 'Menu Toggle', 'elementor-pro' ), + ] ); + + $this->add_responsive_control( + 'toggle_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-align-$start_logical-h", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-align-$end_logical-h", + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-align: {{VALUE}}', + ], + ] + ); + + $this->start_controls_tabs( 'menu_toggle_tabs_section' ); + + $this->start_controls_tab( 'menu_toggle_normal_options', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'menu_toggle_icon_normal', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => esc_html__( 'Default', 'elementor-pro' ), + 'icon' => 'eicon-menu-bar', + ], + 'icon' => [ + 'icon' => 'eicon-star', + ], + ], + ], + 'recommended' => [ + 'fa-solid' => [ + 'plus-square', + 'plus', + 'plus-circle', + 'bars', + ], + 'fa-regular' => [ + 'plus-square', + ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'menu_toggle_hover_options', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'menu_toggle_icon_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'menu_toggle_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'render_type' => 'ui', + 'default' => [ + 'unit' => 'ms', + 'size' => 500, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-wrapper-animation-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'menu_toggle_active_options', [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] ); + + $this->add_control( + 'menu_toggle_icon_active', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => esc_html__( 'Default', 'elementor-pro' ), + 'icon' => 'eicon-close', + ], + 'icon' => [ + 'icon' => 'eicon-star', + ], + ], + ], + 'recommended' => [ + 'fa-solid' => [ + 'window-close', + 'times-circle', + 'times', + 'minus-square', + 'minus-circle', + 'minus', + ], + 'fa-regular' => [ + 'window-close', + 'times-circle', + 'minus-square', + ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_responsive_mega_menu', [ + 'label' => esc_html__( 'Additional Settings', 'elementor-pro' ), + ] ); + + $this->add_responsive_control( + 'horizontal_scroll', + [ + 'label' => esc_html__( 'Horizontal Scroll', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'description' => esc_html__( 'Note: Scroll menu items if they don’t fit into their parent container.', 'elementor-pro' ), + 'options' => [ + 'disable' => esc_html__( 'Disable', 'elementor-pro' ), + 'enable' => esc_html__( 'Enable', 'elementor-pro' ), + ], + 'default' => 'disable', + 'selectors_dictionary' => [ + 'disable' => '--n-menu-heading-wrap: wrap; --n-menu-heading-overflow-x: initial;', + 'enable' => '--n-menu-heading-wrap: nowrap; --n-menu-heading-overflow-x: scroll;', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'frontend_available' => true, + 'condition' => [ + 'item_layout' => 'horizontal', + ], + ] + ); + + $dropdown_options = [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + ]; + + $excluded_breakpoints = [ + 'widescreen', + ]; + + foreach ( Plugin::elementor()->breakpoints->get_active_breakpoints() as $breakpoint_key => $breakpoint_instance ) { + // Exclude the larger breakpoints from the dropdown selector. + if ( in_array( $breakpoint_key, $excluded_breakpoints, true ) ) { + continue; + } + + $dropdown_options[ $breakpoint_key ] = sprintf( + /* translators: 1: Breakpoint label, 2: `>` character, 3: Breakpoint value. */ + esc_html__( '%1$s (%2$s %3$dpx)', 'elementor-pro' ), + $breakpoint_instance->get_label(), + '>', + $breakpoint_instance->get_value() + ); + } + + $this->add_control( + 'breakpoint_selector', + [ + 'label' => esc_html__( 'Breakpoint', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'description' => esc_html__( 'Note: Item layout will switch to dropdown on any screen smaller than the selected breakpoint.', 'elementor-pro' ), + 'options' => $dropdown_options, + 'default' => 'tablet', + 'prefix_class' => 'e-n-menu-', + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_menu_items_style', [ + 'label' => esc_html__( 'Menu Items', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $this->add_responsive_control( 'menu_item_title_space_between', [ + 'label' => esc_html__( 'Space between Items', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'default' => [ + 'size' => 0, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-space-between: {{SIZE}}{{UNIT}}', + ], + ] ); + + $this->add_responsive_control( 'menu_item_title_distance_from_content', [ + 'label' => esc_html__( 'Distance from content', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'default' => [ + 'size' => 0, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-distance-from-content: {{SIZE}}{{UNIT}}', + ], + 'frontend_available' => true, + ] ); + + $this->add_group_control( Group_Control_Typography::get_type(), [ + 'name' => 'menu_item_title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => $this->get_typography_selector( $heading_selector ), + 'fields_options' => [ + 'font_size' => [ + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-font-size: {{SIZE}}{{UNIT}}', + ], + ], + 'line_height' => [ + 'selectors' => [ + '{{SELECTOR}}' => '--e-global-typography-{{external._id.VALUE}}-line-height: {{SIZE}}{{UNIT}}', + '{{SELECTOR}}' => '--n-menu-title-line-height: {{SIZE}}', + ], + ], + ], + ] ); + + $this->start_controls_tabs( 'menu_item_title_style' ); + + $this->start_controls_tab( + 'menu_item_title_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'menu_item_title_text_color_normal', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-color-normal: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'menu_item_title_text_shadow_normal', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:not( .e-current ):not( :hover )", + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_item_title_background_color', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:not( .e-current ):not( :hover )", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_item_title_box_border', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:not( .e-current ):not( :hover )", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_item_title_box_shadow', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:not( .e-current ):not( :hover )", + ] + ); + + $divider_condition = [ + 'menu_divider' => 'yes', + 'item_layout' => 'horizontal', + ]; + + $this->add_control( + 'menu_divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'item_layout' => 'horizontal', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-divider-content: "";', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'menu_divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + ], + 'default' => 'solid', + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-divider-style: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'menu_divider_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-divider-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'menu_divider_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + '%' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-divider-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'menu_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-divider-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); // End Normal Tab + + $this->start_controls_tab( + 'menu_item_title_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'menu_item_title_text_color_hover', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--n-menu-title-color-hover: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'menu_item_title_text_shadow_hover', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:hover:not( .e-current )", + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_item_title_background_color_hover', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:hover:not( .e-current )", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_item_title_box_border_hover', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:hover:not( .e-current )", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_item_title_box_shadow_hover', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title:hover:not( .e-current )", + ] + ); + + $this->add_control( + 'hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->add_control( + 'menu_item_title_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-transition: {{SIZE}}{{UNIT}}', + ], + 'default' => [ + 'unit' => 'ms', + 'size' => 300, + ], + ] + ); + $this->end_controls_tab(); // End Hover Tab + + $this->start_controls_tab( + 'menu_item_title_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'menu_item_title_text_color_active', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--n-menu-title-color-active: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'menu_item_title_text_shadow_active', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title.e-current", + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html_x( 'Shadow', 'Text Shadow Control', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_item_title_background_color_active', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title.e-current", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_item_title_box_border_active', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title.e-current", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_item_title_box_shadow_active', + 'selector' => "{$heading_selector} > .e-n-menu-item > .e-n-menu-title.e-current", + ] + ); + + $this->end_controls_tab(); // End Active Tab + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'menu_item_title_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + "{$heading_selector} > .e-n-menu-item > .e-n-menu-title" => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'menu_item_title_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + // Icon Style + $this->start_controls_section( 'icon_section_style', [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $styling_block_start = '--n-menu-title-direction: column; --n-menu-icon-order: initial; --n-menu-icon-align-items: flex-end; --n-menu-title-justify-content: center; --n-menu-title-align-items-toggle: initial;'; + $styling_inline_end = '--n-menu-title-direction: row; --n-menu-icon-order: 1; --n-menu-icon-align-items: initial; --n-menu-title-justify-content: initial; --n-menu-title-align-items-toggle: center;'; + $styling_block_end = '--n-menu-title-direction: column; --n-menu-icon-order: 1; --n-menu-icon-align-items: flex-start; --n-menu-title-justify-content: center; --n-menu-title-align-items-toggle: initial;'; + $styling_inline_start = '--n-menu-title-direction: row; --n-menu-icon-order: initial; --n-menu-icon-align-items: initial; --n-menu-title-justify-content: initial; --n-menu-title-align-items-toggle: center;'; + + $this->add_responsive_control( 'icon_position', [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'block-start' => [ + 'title' => esc_html__( 'Above', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'inline-end' => [ + 'title' => esc_html__( 'After', 'elementor-pro' ), + 'icon' => 'eicon-h-align-' . $end, + ], + 'block-end' => [ + 'title' => esc_html__( 'Below', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + 'inline-start' => [ + 'title' => esc_html__( 'Before', 'elementor-pro' ), + 'icon' => 'eicon-h-align-' . $start, + ], + ], + 'selectors_dictionary' => [ + 'block-start' => $styling_block_start, + 'inline-end' => $styling_inline_end, + 'block-end' => $styling_block_end, + 'inline-start' => $styling_inline_start, + // Styling duplication for BC reasons. + 'top' => $styling_block_start, + 'end' => $styling_inline_end, + 'bottom' => $styling_block_end, + 'start' => $styling_inline_start, + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + ] ); + + $this->add_responsive_control( 'icon_size', [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'min' => 0, + 'max' => 10, + ], + 'rem' => [ + 'min' => 0, + 'max' => 10, + ], + ], + 'default' => [ + 'unit' => 'px', + 'size' => 16, + ], + 'size_units' => [ 'px', 'em', 'rem' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-icon-size: {{SIZE}}{{UNIT}}', + ], + ] ); + + $this->add_responsive_control( 'icon_spacing', [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 400, + ], + 'em' => [ + 'max' => 40, + ], + 'rem' => [ + 'max' => 40, + ], + 'vw' => [ + 'min' => 0, + 'max' => 50, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-icon-gap: {{SIZE}}{{UNIT}}', + ], + ] ); + + $this->start_controls_tabs( 'icon_style_states' ); + + $this->start_controls_tab( + 'icon_section_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( 'icon_color', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-icon-color: {{VALUE}};', + ], + ] ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'icon_section_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( 'icon_color_hover', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-icon-color-hover: {{VALUE}};', + ], + ] ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'icon_section_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( 'icon_color_active', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-icon-color-active: {{VALUE}};', + ], + ] ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_dropdown_indicator_style', [ + 'label' => esc_html__( 'Dropdown Indicator', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'menu_item_icon[value]', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'menu_item_icon_active[value]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] ); + + $this->add_responsive_control( + 'style_dropdown_indicator_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-indicator-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'style_dropdown_indicator_rotate', + [ + 'label' => esc_html__( 'Rotate', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'deg', 'grad', 'rad', 'turn', 'custom' ], + 'default' => [ + 'unit' => 'deg', + ], + 'tablet_default' => [ + 'unit' => 'deg', + ], + 'mobile_default' => [ + 'unit' => 'deg', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-indicator-rotate: rotate({{SIZE}}{{UNIT}})', + ], + ] + ); + + $this->add_responsive_control( + 'style_dropdown_indicator_space', + [ + 'label' => esc_html__( 'Space', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-indicator-space: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->start_controls_tabs( 'style_menu_dropdown_indicator' ); + + foreach ( [ 'normal', 'hover', 'active' ] as $state ) { + $this->add_dropdown_indicator_state_based_style_controls( $state ); + } + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_menu_toggle_style', [ + 'label' => esc_html__( 'Menu Toggle', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $this->add_control( + 'style_menu_toggle_icon_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Toggle Icon', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'style_menu_toggle_icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->start_controls_tabs( 'style_menu_toggle_tabs' ); + + $this->start_controls_tab( 'style_menu_toggle_tab_normal', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( 'menu_toggle_icon_color_normal', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'render_type' => 'ui', + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-color: {{VALUE}};', + ], + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_toggle_icon_background_color_normal', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="false"]:not( :hover )' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'selectors' => [ + '{{SELECTOR}}' => 'background: {{VALUE}}', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_toggle_icon_border_normal', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="false"]:not( :hover )' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_toggle_icon_box_shadow_normal', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="false"]:not( :hover )' ), + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'style_menu_toggle_hover', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( 'menu_toggle_icon_color_hover', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'render_type' => 'ui', + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-color-hover: {{VALUE}};', + ], + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_toggle_icon_background_color_hover', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', ':hover:is( [aria-expanded="true"], [aria-expanded="false"] )' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'selectors' => [ + '{{SELECTOR}}' => 'background: {{VALUE}}', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_toggle_icon_border_hover', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', ':hover:is( [aria-expanded="true"], [aria-expanded="false"] )' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_toggle_icon_box_shadow_hover', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', ':hover:is( [aria-expanded="true"], [aria-expanded="false"] )' ), + ] + ); + + $this->add_control( + 'menu_toggle_icon_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + 'size' => 500, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-hover-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'style_menu_toggle_active', [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] ); + + $this->add_control( 'menu_toggle_icon_color_active', [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'render_type' => 'ui', + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-color-active: {{VALUE}};', + ], + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'menu_toggle_icon_background_color_active', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="true"]' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'selectors' => [ + '{{SELECTOR}}' => 'background: {{VALUE}}', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_toggle_icon_border_active', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="true"]' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_toggle_icon_box_shadow_active', + 'selector' => $this->get_control_selector_class( 'menu_toggle_icon', '[aria-expanded="true"]' ), + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'menu_toggle_icon_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'menu_toggle_icon__padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( 'menu_toggle_icon_distance_from_dropdown', [ + 'label' => esc_html__( 'Distance from dropdown', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'default' => [ + 'size' => 0, + ], + 'placeholder' => [ + 'size' => 0, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-toggle-icon-distance-from-dropdown: {{SIZE}}{{UNIT}}', + ], + ] ); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_content_style', [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'content_background_color', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => $this->get_control_selector_class( 'active_content_container' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'content_border', + 'selector' => $this->get_control_selector_class( 'active_content_container' ), + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_responsive_control( + 'content_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + $this->get_control_selector_class( 'active_content_container' ) => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'content_shadow', + 'selector' => $this->get_control_selector_class( 'active_content_container' ), + ] + ); + + $this->add_responsive_control( + 'content_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + $this->get_control_selector_class( 'active_content_container' ) => '--padding-top: {{TOP}}{{UNIT}}; --padding-right: {{RIGHT}}{{UNIT}}; --padding-bottom: {{BOTTOM}}{{UNIT}}; --padding-left: {{LEFT}}{{UNIT}};', + // Todo: Remove in version 3.21.0: https://elementor.atlassian.net/browse/ED-11888. + // Remove together with support for physical properties inside the container widget. + ":where( [data-core-v316-plus='true'] .elementor-element.elementor-widget-n-menu{$widget_container_selector} > .e-n-menu > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-content ) > .e-con" => "--padding-block-start: {{TOP}}{{UNIT}}; --padding-inline-end: $logical_dimensions_inline_end; --padding-block-end: {{BOTTOM}}{{UNIT}}; --padding-inline-start: $logical_dimensions_inline_start;", + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( 'section_dropdown_menu_style', [ + 'label' => esc_html__( 'Dropdown Menu', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $this->add_control( + 'dropdown_menu_items_title', + [ + 'label' => esc_html__( 'Menu Items', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'dropdown_menu_items_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Styles apply to items when the menu switches to dropdown layout', 'elementor-pro' ), + 'content_classes' => 'elementor-control-field-description', + ] + ); + + $this->start_controls_tabs( 'menu_dropdown_states_section' ); + + $this->start_controls_tab( + 'normal_menu_dropdown_states', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( 'dropdown_menu_item_text_color_normal', [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-normal-color-dropdown: {{VALUE}};', + ], + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'dropdown_menu_item_background_color_normal', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{{WRAPPER}}{$widget_container_selector} > .e-n-menu[data-layout='dropdown'] > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title:not( .e-current )", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'selectors' => [ + '{{SELECTOR}}' => 'background: {{VALUE}}', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'dropdown_menu_item_box_shadow_normal', + 'selector' => "{{WRAPPER}}{$widget_container_selector} > .e-n-menu[data-layout='dropdown'] > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title:not( .e-current )", + + ] + ); + + $this->end_controls_tab(); // Normal tab end + + $this->start_controls_tab( + 'active_menu_dropdown_states', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( 'dropdown_menu_item_text_color_active', [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-title-active-color-dropdown: {{VALUE}};', + ], + ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'dropdown_menu_item_background_color_active', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{{WRAPPER}}{$widget_container_selector} > .e-n-menu[data-layout='dropdown'] > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title.e-current", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'dropdown_menu_item_box_shadow_active', + 'selector' => "{{WRAPPER}}{$widget_container_selector} > .e-n-menu[data-layout='dropdown'] > .e-n-menu-wrapper > .e-n-menu-heading > .e-n-menu-item > .e-n-menu-title.e-current", + + ] + ); + + $this->end_controls_tab(); // Active tab end + + $this->end_controls_tabs(); + + $this->add_control( + 'menu_dropdown_box_title', + [ + 'label' => esc_html__( 'Dropdown Box', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'menu_dropdown_box_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Style the dropdown box that contains menu items.', 'elementor-pro' ), + 'content_classes' => 'elementor-control-field-description', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'menu_dropdown_box_border', + 'fields_options' => [ + 'border' => [ + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-content-box-border-style: {{VALUE}}', + ], + ], + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-content-box-border-color: {{VALUE}}', + ], + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}}' => "--n-menu-dropdown-content-box-border-block-start-width: {{TOP}}{{UNIT}}; --n-menu-dropdown-content-box-border-inline-end-width: $logical_dimensions_inline_end; --n-menu-dropdown-content-box-border-block-end-width: {{BOTTOM}}{{UNIT}}; --n-menu-dropdown-content-box-border-inline-start-width: $logical_dimensions_inline_start;", + ], + ], + ], + ] + ); + + $this->add_control( + 'menu_dropdown_box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-content-box-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'menu_dropdown_box_shadow', + 'fields_options' => [ + 'box_shadow' => [ + 'selectors' => [ + '{{WRAPPER}}' => '--n-menu-dropdown-content-box-shadow-horizontal: {{HORIZONTAL}}px; --n-menu-dropdown-content-box-shadow-vertical: {{VERTICAL}}px; --n-menu-dropdown-content-box-shadow-blur: {{BLUR}}px; --n-menu-dropdown-content-box-shadow-spread: {{SPREAD}}px; --n-menu-dropdown-content-box-shadow-color: {{COLOR}}; --n-menu-dropdown-content-box-shadow-position: {{box_shadow_position.VALUE}};', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $menu_titles = ''; + $menu_containers = ''; + + $this->add_render_attribute( + 'e-n-menu', + [ + 'class' => 'e-n-menu', + 'data-widget-number' => $this->get_widget_number(), + ] + ); + + if ( $settings['menu_name'] ) { + $this->add_render_attribute( 'e-n-menu', 'aria-label', $settings['menu_name'] ); + } + + foreach ( $settings['menu_items'] as $index => $item ) { + $menu_titles .= $this->render_menu_titles_html( $index, $item ); + } + + ?> + + add_render_attribute( 'e-n-menu-wrapper', [ + 'class' => 'e-n-menu-wrapper', + 'id' => 'menubar-' . $this->get_widget_number(), + 'aria-labelledby' => 'menu-toggle-' . $this->get_widget_number(), + ] ); + + $this->print_render_attribute_string( 'e-n-menu-wrapper' ); + } + + protected function render_menu_toggle( $settings ) { + $menu_toggle_hover_animation = ! empty( $settings['menu_toggle_icon_hover_animation'] ) + ? ' elementor-animation-' . $settings['menu_toggle_icon_hover_animation'] + : ''; + + $this->add_render_attribute( 'menu-toggle', [ + 'class' => 'e-n-menu-toggle' . $menu_toggle_hover_animation, + 'id' => 'menu-toggle-' . $this->get_widget_number(), + 'aria-haspopup' => 'true', + 'aria-expanded' => 'false', + 'aria-controls' => 'menubar-' . $this->get_widget_number(), + 'aria-label' => esc_attr__( 'Menu Toggle', 'elementor-pro' ), + ] ); + + $open_class = 'e-n-menu-toggle-icon e-open'; + $close_class = 'e-n-menu-toggle-icon e-close'; + + $normal_icon = ! empty( $settings['menu_toggle_icon_normal']['value'] ) + ? $settings['menu_toggle_icon_normal'] + : [ + 'library' => 'eicons', + 'value' => 'eicon-menu-bar', + ]; + + $active_icon = ! empty( $settings['menu_toggle_icon_active']['value'] ) + ? $settings['menu_toggle_icon_active'] + : [ + 'library' => 'eicons', + 'value' => 'eicon-close', + ]; + ?> + + + <# + const menuToggleKey = 'e-n-menu-toggle-' + elementUid, + iconHoverAnimation = !! settings.menu_toggle_icon_hover_animation + ? 'elementor-animation-' + settings.menu_toggle_icon_hover_animation + : '', + openClass = 'e-n-menu-toggle-icon e-open', + closeClass = 'e-n-menu-toggle-icon e-close', + iconNormal = !! settings.menu_toggle_icon_normal.value ? settings.menu_toggle_icon_normal : '', + iconActive = !! settings.menu_toggle_icon_active.value ? settings.menu_toggle_icon_active : ''; + + view.addRenderAttribute( menuToggleKey, { + 'class': [ 'e-n-menu-toggle', 'elementor-clickable', iconHoverAnimation ], + 'id': 'menu-toggle-' + elementUid, + 'aria-haspopup': 'true', + 'aria-expanded': 'false', + 'aria-controls': 'menubar-' + elementUid, + 'aria-label': '', + } ); + #> + + get_current_menu_item_class( $item['item_link']['url'] ); + $items_open_on_click = 'click' === $this->get_settings_for_display( 'open_on' ); + + if ( ! empty( $current_class ) ) { + $classes[] = $current_class; + } + + if ( $items_open_on_click && $this->item_has_dropdown_with_content( $index, $this->get_children(), 'yes' === $item['item_dropdown_content'] ) ) { + $classes[] = 'e-click'; + } + + return array_filter( $classes ); + } + + protected function render_menu_titles_html( $index, $item ) { + $settings = $this->get_settings_for_display(); + $is_focusable_class = 'yes' === $item['item_dropdown_content'] ? 'e-focus' : ''; + $item_class = $this->merge_menu_title_classes( $index, $item, [ 'e-n-menu-title' ] ); + $item_dropdown_class = [ 'e-n-menu-dropdown-icon' ]; + + if ( ! empty( $is_focusable_class ) ) { + $item_dropdown_class[] = $is_focusable_class; + } + + $icon_html = Icons_Manager::try_get_icon_html( $settings['menu_item_icon'], [ 'aria-hidden' => 'true' ] ); + $icon_active_html = Icons_Manager::try_get_icon_html( $settings['menu_item_icon_active'], [ 'aria-hidden' => 'true' ] ); + $display_index = $index + 1; + $has_dropdown_content = 'yes' === $settings['menu_items'][ $index ]['item_dropdown_content']; + $menu_item_id = empty( $item['element_id'] ) ? 'e-n-menu-title-' . $this->get_widget_number() . $display_index : $item['element_id']; + $item_dropdown_id = 'e-n-menu-dropdown-icon-' . $this->get_widget_number() . $display_index; + $key = $this->get_repeater_setting_key( 'item_title', 'menu_items', $display_index ); + $menu_item = $settings['menu_items'][ $index ]; + $menu_item_icon = Icons_Manager::try_get_icon_html( $menu_item['item_icon'], [ 'aria-hidden' => 'true' ] ); + $menu_item_active_icon = $this->is_active_icon_exist( $menu_item ) + ? Icons_Manager::try_get_icon_html( $item['item_icon_active'], [ 'aria-hidden' => 'true' ] ) + : $menu_item_icon; + + if ( ! empty( $settings['hover_animation'] ) ) { + $item_class[] = 'elementor-animation-' . $settings['hover_animation']; + } + + $this->add_attributes_to_item( $key, $item_class, $menu_item_id, $display_index ); + $this->add_attributes_to_item_dropdown( $key . '_link', $item_dropdown_class, $item_dropdown_id, $display_index, $has_dropdown_content, $item['item_title'] ); + + ob_start(); + ?> +
    • +
      print_render_attribute_string( $key ); ?>> + get_title_container_opening_tag( $item, $item['item_link']['url'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + + + + + + + + + + get_title_container_closing_tag( $item['item_link']['url'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + + + +
      + +
      + get_widget_number() . ( $index + 1 ); + echo $this->print_child( $index, 'yes' === $item['item_dropdown_content'], $item_dropdown_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> +
      + +
    • + add_render_attribute( $key, [ + 'id' => $menu_item_id, + 'class' => $classes, + ] ); + } + + public function add_attributes_to_item_dropdown( $key, $classes, $item_dropdown_id, $display_index, $has_dropdown_content = false, $title = '' ) { + $this->add_render_attribute( $key, [ + 'id' => $item_dropdown_id, + 'class' => $classes, + 'data-tab-index' => $display_index, + 'aria-haspopup' => $has_dropdown_content ? 'true' : 'false', + 'aria-expanded' => 'false', + 'aria-controls' => 'e-n-menu-content-' . $this->get_widget_number() . $display_index, + ] ); + } + + protected function get_current_menu_item_class( $menu_link_url ) { + $menu_link_url = trim( $menu_link_url ); + + if ( str_contains( $menu_link_url, '#' ) ) { + return 'e-anchor'; + } + + $permalink_url = $this->get_permalink_for_current_page(); + + if ( empty( $menu_link_url ) || empty( $permalink_url ) ) { + return ''; + } + + $permalink_array = $this->parse_url( $permalink_url ); + $menu_item_url_array = $this->parse_url( $menu_link_url ); + $has_equal_urls = $permalink_array === $menu_item_url_array; + + return $has_equal_urls ? 'e-current' : ''; + } + + /** + * Print the content area. + * + * @param int $index + * @param boolean $has_dropdown_content + * @param string $menu_item_id + */ + public function print_child( $index, $has_dropdown_content = false, $menu_item_id = '' ) { + $children = $this->get_children(); + $menu_index = $index + 1; + $child_ids = []; + + foreach ( $children as $child ) { + $child_ids[] = $child->get_id(); + } + + $add_attribute_to_container = function ( $should_render, $container ) use ( $menu_item_id, $menu_index, $child_ids ) { + if ( in_array( $container->get_id(), $child_ids ) ) { + $this->set_container_attributes( $container, $menu_index, $menu_item_id ); + } + + return $should_render; + }; + + if ( $this->item_has_dropdown_with_content( $index, $children, $has_dropdown_content ) ) { + add_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container, 10, 3 ); + + $children[ $index ]->print_element(); + + remove_filter( 'elementor/frontend/container/should_render', $add_attribute_to_container ); + } + } + + protected function set_container_attributes( $container, $menu_index, $menu_item_id ) { + $container->add_render_attribute( '_wrapper', [ + 'id' => 'e-n-menu-content-' . $this->get_widget_number() . $menu_index, + 'data-tab-index' => $menu_index, + 'aria-labelledby' => $menu_item_id, + ] ); + } + + protected function item_has_dropdown_with_content( $index, $children, $has_dropdown_content = false ) { + $data = ! empty( $children[ $index ] ) ? $children[ $index ]->get_data() : []; + $elements = empty( $data['elements'] ) ? [] : $data['elements']; + + return ! empty( $children[ $index ] ) && ! empty( $elements ) && $has_dropdown_content; + } + + private function get_title_container_opening_tag( $item, $url ) { + $title_container_id = 'e-n-menu-title-container-' . $item['_id']; + $container_classes = [ 'e-n-menu-title-container' ]; + + if ( ! empty( $url ) ) { + array_push( $container_classes, 'e-focus', 'e-link' ); + } + + $this->remove_render_attribute( $title_container_id ); + + $this->add_render_attribute( $title_container_id, [ + 'class' => $container_classes, + ] ); + + $this->add_link_attributes( $title_container_id, $item['item_link'] ); + + $current_class = $this->get_current_menu_item_class( $url ); + + if ( ! empty( $current_class ) ) { + $this->add_render_attribute( $title_container_id, 'aria-current', 'page' ); + } + + $container_attributes = $this->get_render_attribute_string( $title_container_id ); + + if ( ! empty( $url ) ) { + $opening_tag = ''; + } else { + $opening_tag = ''; + } + + /** + * @param $item + * @return bool + */ + private function is_active_icon_exist( $item ) { + return array_key_exists( 'item_icon_active', $item ) && ! empty( $item['item_icon_active'] ) && ! empty( $item['item_icon_active']['value'] ); + } + + /** + * @param string $state + * @param $css_prefix + * @return void + */ + private function add_dropdown_indicator_state_based_style_controls( string $state ) { + $label = esc_html__( 'Normal', 'elementor-pro' ); + $selector = '--n-menu-dropdown-indicator-color-normal: {{VALUE}};'; + if ( 'hover' === $state ) { + $label = esc_html__( 'Hover', 'elementor-pro' ); + $selector = '--n-menu-dropdown-indicator-color-hover: {{VALUE}};'; + } + if ( 'active' === $state ) { + $label = esc_html__( 'Active', 'elementor-pro' ); + $selector = '--n-menu-dropdown-indicator-color-active: {{VALUE}};'; + } + $this->start_controls_tab('style_menu_dropdown_indicator_' . $state, [ + 'label' => $label, + ] ); + + $this->add_control( + 'menu_dropdown_indicator_color_' . $state, + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => $selector, + ], + ] + ); + + $this->end_controls_tab(); + } + + // Any update in this function should also be updated in the content_template_single_repeater_item function too + protected function content_template() { + ?> + <# + if ( ! settings['menu_items'] ) { + return; + } + + const menuItemIcon = elementor.helpers.renderIcon( view, settings['menu_item_icon'], { 'aria-hidden': true }, 'i' , 'object' ) ?? '', + menuItemIconActive = elementor.helpers.renderIcon( view, settings['menu_item_icon_active'], { 'aria-hidden': true }, 'i' , 'object' ) ?? '', + elementUid = view.getIDInt().toString().substr( 0, 3 ), + permalinkUrl = 'get_permalink_for_current_page() ); ?>'; + + view.addRenderAttribute( + 'e-n-menu', + { + 'class': 'e-n-menu', + 'data-widget-number': elementUid, + } + ); + + if ( '' !== settings.menu_name ) { + view.addRenderAttribute( 'e-n-menu', 'aria-label', settings.menu_name ); + } + #> + + true, + 'target_container' => [ '.e-n-menu-heading' ], + 'node' => 'li', + 'is_interlaced' => true, + ] ); + } + + // Any update in this function should be updated also in the content_template function too + protected function content_template_single_repeater_item() { + ?> + <# + const menuItemIcon = elementor.helpers.renderIcon( view, view.container.settings.attributes.menu_item_icon, { 'aria-hidden': true }, 'i' , 'object' ) ?? '', + menuItemIconActive = elementor.helpers.renderIcon( view, view.container.settings.attributes.menu_item_icon_active, { 'aria-hidden': true }, 'i' , 'object' ) ?? '', + elementUid = view.getIDInt().toString().substr( 0, 3 ), + permalinkUrl = 'get_permalink_for_current_page() ); ?>', + menuItemCount = view.collection.length + 1, + menuItemUid = view.getIDInt().toString().substr( 0, 3 ) + menuItemCount, + menuItemWrapperKey = menuItemUid, + menuItemTitleKey = 'menu-title-' + menuItemUid, + menuItemTitleContainerLinkKey = 'e-n-menu-title-container-' + menuItemUid, + menuItemDropdownIconKey = 'e-n-menu-dropdown-icon-' + menuItemUid, + menuItemIconKey = 'menu-icon-' + menuItemUid, + menuIcon = elementor.helpers.renderIcon( view, data.item_icon, { 'aria-hidden': true }, 'i' , 'object' ) ?? '', + menuIconActive = '' === data.item_icon_active.value + ? menuIcon + : elementor.helpers.renderIcon( view, data.item_icon_active, { 'aria-hidden': true }, 'i' , 'object' ), + menuItemLink = 'string' === typeof data['item_link'] ? data['item_link'] : data['item_link']['url'], + hasDropdownContent = 'yes' === data['item_dropdown_content'], + currentPageClass = elementorPro.modules.megaMenu.getCurrentMenuItemClass( menuItemLink, permalinkUrl ), + dropdownFocusClass = hasDropdownContent ? 'e-focus' : '', + menuItemClassList = ['e-n-menu-title']; + let menuItemId = 'e-n-menu-title-' + menuItemUid; + + if ( '' !== data.element_id ) { + menuItemId = data.element_id; + } + + if ( ! hasDropdownContent ) { + menuItemClassList.push( 'link-only' ); + } else { + menuItemClassList.push( 'e-click' ); + } + + if ( !! currentPageClass ) { + menuItemClassList.push( currentPageClass ); + } + + view.addRenderAttribute( menuItemWrapperKey, { + 'id': menuItemId, + 'class': menuItemClassList, + }, null, true ); + + view.addRenderAttribute( menuItemTitleKey, { + 'class': [ 'e-n-menu-title-text' ], + 'data-binding-type': 'repeater-item', + 'data-binding-repeater-name': 'menu_items', + 'data-binding-setting': ['item_title'], + 'data-binding-index': menuItemCount, + 'data-binding-dynamic': 'true', + }, null, true ); + + const menuItemContainerClasses = [ 'e-n-menu-title-container' ]; + + if ( !! data.item_link?.url ) { + menuItemContainerClasses.push( 'e-link', 'e-focus' ); + } + + view.addRenderAttribute( menuItemTitleContainerLinkKey, { + 'class': menuItemContainerClasses, + 'href': elementor.helpers.sanitizeUrl( data.item_link?.url ), + 'aria-current': 'page', + }, null, true ); + + view.addRenderAttribute( menuItemDropdownIconKey, { + 'id': 'e-n-menu-dropdown-icon-' + menuItemUid, + 'class': [ 'e-n-menu-dropdown-icon', 'e-focus' ], + 'data-tab-index': menuItemCount, + 'aria-haspopup': hasDropdownContent ? 'true' : 'false', + 'aria-expanded': 'false', + 'aria-controls': 'e-n-menu-content-' + menuItemUid, + }, null, true ); + #> +
    • +
      + <# if ( menuItemLink ) { #> + + <# } else { #> + + <# } #> + + <# if ( hasDropdownContent ) { #> + + <# } #> +
      +
      +
    • + [ + 'label' => esc_html__( 'Scrolling Effects', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'render_type' => 'ui', + 'frontend_available' => true, + ], + ]; + + $this->prepare_effects( 'scrolling', $fields ); + + $transform_origin_conditions = [ + 'terms' => [ + [ + 'name' => 'motion_fx_scrolling', + 'value' => 'yes', + ], + [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'rotateZ_effect', + 'value' => 'yes', + ], + [ + 'name' => 'scale_effect', + 'value' => 'yes', + ], + ], + ], + ], + ]; + + $fields['transform_origin_x'] = [ + 'label' => esc_html__( 'X Anchor Point', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'conditions' => $transform_origin_conditions, + 'toggle' => false, + 'render_type' => 'ui', + 'selectors' => [ + '{{SELECTOR}}' => '--e-transform-origin-x: {{VALUE}}', + ], + ]; + + $fields['transform_origin_y'] = [ + 'label' => esc_html__( 'Y Anchor Point', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'conditions' => $transform_origin_conditions, + 'selectors' => [ + '{{SELECTOR}}' => '--e-transform-origin-y: {{VALUE}}', + ], + 'toggle' => false, + ]; + + // TODO: Once Core 3.4.0 is out, get the active devices using Breakpoints/Manager::get_active_devices_list(). + $active_breakpoint_instances = Plugin::elementor()->breakpoints->get_active_breakpoints(); + // Devices need to be ordered from largest to smallest. + $active_devices = array_reverse( array_keys( $active_breakpoint_instances ) ); + + // Add desktop in the correct position. + if ( in_array( 'widescreen', $active_devices, true ) ) { + $active_devices = array_merge( array_slice( $active_devices, 0, 1 ), [ 'desktop' ], array_slice( $active_devices, 1 ) ); + } else { + $active_devices = array_merge( [ 'desktop' ], $active_devices ); + } + + $devices_options = []; + + foreach ( $active_devices as $device_key ) { + $device_label = 'desktop' === $device_key ? esc_html__( 'Desktop', 'elementor-pro' ) : $active_breakpoint_instances[ $device_key ]->get_label(); + + $devices_options[ $device_key ] = $device_label; + } + + $fields['devices'] = [ + 'label' => esc_html__( 'Apply Effects On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'label_block' => true, + 'default' => $active_devices, + 'options' => $devices_options, + 'condition' => [ + 'motion_fx_scrolling' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ]; + + $fields['range'] = [ + 'label' => esc_html__( 'Effects Relative To', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + 'viewport' => esc_html__( 'Viewport', 'elementor-pro' ), + 'page' => esc_html__( 'Entire Page', 'elementor-pro' ), + ], + 'condition' => [ + 'motion_fx_scrolling' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ]; + + $fields['motion_fx_mouse'] = [ + 'label' => esc_html__( 'Mouse Effects', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'separator' => 'before', + 'render_type' => 'none', + 'frontend_available' => true, + ]; + + $this->prepare_effects( 'mouse', $fields ); + + return $fields; + } + + protected function get_default_options() { + return [ + 'popover' => false, + ]; + } + + private function get_scrolling_effects() { + return [ + 'translateY' => [ + 'label' => esc_html__( 'Vertical Scroll', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Up', 'elementor-pro' ), + 'negative' => esc_html__( 'Down', 'elementor-pro' ), + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 4, + ], + 'range' => [ + 'px' => [ + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + 'affectedRange' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 0, + 'end' => 100, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + 'translateX' => [ + 'label' => esc_html__( 'Horizontal Scroll', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'To Left', 'elementor-pro' ), + 'negative' => esc_html__( 'To Right', 'elementor-pro' ), + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 4, + ], + 'range' => [ + 'px' => [ + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + 'affectedRange' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 0, + 'end' => 100, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + 'opacity' => [ + 'label' => esc_html__( 'Transparency', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'out-in', + 'options' => [ + 'out-in' => 'Fade In', + 'in-out' => 'Fade Out', + 'in-out-in' => 'Fade Out In', + 'out-in-out' => 'Fade In Out', + ], + ], + 'level' => [ + 'label' => esc_html__( 'Level', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + 'range' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 20, + 'end' => 80, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + 'blur' => [ + 'label' => esc_html__( 'Blur', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'out-in', + 'options' => [ + 'out-in' => 'Fade In', + 'in-out' => 'Fade Out', + 'in-out-in' => 'Fade Out In', + 'out-in-out' => 'Fade In Out', + ], + ], + 'level' => [ + 'label' => esc_html__( 'Level', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 7, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 15, + ], + ], + ], + 'range' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 20, + 'end' => 80, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + 'rotateZ' => [ + 'label' => esc_html__( 'Rotate', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'To Left', 'elementor-pro' ), + 'negative' => esc_html__( 'To Right', 'elementor-pro' ), + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + 'affectedRange' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 0, + 'end' => 100, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + 'scale' => [ + 'label' => esc_html__( 'Scale', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'out-in', + 'options' => [ + 'out-in' => 'Scale Up', + 'in-out' => 'Scale Down', + 'in-out-in' => 'Scale Down Up', + 'out-in-out' => 'Scale Up Down', + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 4, + ], + 'range' => [ + 'px' => [ + 'min' => -10, + 'max' => 10, + ], + ], + ], + 'range' => [ + 'label' => esc_html__( 'Viewport', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'sizes' => [ + 'start' => 20, + 'end' => 80, + ], + 'unit' => '%', + ], + 'labels' => [ + __( 'Bottom', 'elementor-pro' ), + __( 'Top', 'elementor-pro' ), + ], + 'scales' => 1, + 'handles' => 'range', + ], + ], + ], + ]; + } + + private function get_mouse_effects() { + return [ + 'mouseTrack' => [ + 'label' => esc_html__( 'Mouse Track', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Opposite', 'elementor-pro' ), + 'negative' => esc_html__( 'Direct', 'elementor-pro' ), + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + ], + ], + 'tilt' => [ + 'label' => esc_html__( '3D Tilt', 'elementor-pro' ), + 'fields' => [ + 'direction' => [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Direct', 'elementor-pro' ), + 'negative' => esc_html__( 'Opposite', 'elementor-pro' ), + ], + ], + 'speed' => [ + 'label' => esc_html__( 'Speed', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 4, + ], + 'range' => [ + 'px' => [ + 'max' => 10, + 'step' => 0.1, + ], + ], + ], + ], + ], + ]; + } + + private function prepare_effects( $effects_group, array &$fields ) { + $method_name = "get_{$effects_group}_effects"; + + $effects = $this->$method_name(); + + foreach ( $effects as $effect_name => $effect_args ) { + $args = [ + 'label' => $effect_args['label'], + 'type' => Controls_Manager::POPOVER_TOGGLE, + 'condition' => [ + 'motion_fx_' . $effects_group => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ]; + + if ( ! empty( $effect_args['separator'] ) ) { + $args['separator'] = $effect_args['separator']; + } + + $fields[ $effect_name . '_effect' ] = $args; + + $effect_fields = $effect_args['fields']; + + $first_field = & $effect_fields[ key( $effect_fields ) ]; + + $first_field['popover']['start'] = true; + + end( $effect_fields ); + + $last_field = & $effect_fields[ key( $effect_fields ) ]; + + $last_field['popover']['end'] = true; + + reset( $effect_fields ); + + foreach ( $effect_fields as $field_name => $field ) { + $field = array_merge( $field, [ + 'condition' => [ + 'motion_fx_' . $effects_group => 'yes', + $effect_name . '_effect' => 'yes', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] ); + + $fields[ $effect_name . '_' . $field_name ] = $field; + } + } + } +} diff --git a/modules/motion-fx/module.php b/modules/motion-fx/module.php new file mode 100644 index 00000000..bf92267a --- /dev/null +++ b/modules/motion-fx/module.php @@ -0,0 +1,222 @@ +add_actions(); + } + + /** + * Get module name. + * + * Retrieve the module name. + * + * @since 2.5.0 + * @access public + * + * @return string Module name. + */ + public function get_name() { + return 'motion-fx'; + } + + public function register_controls_group( Controls_Manager $controls_manager ) { + $controls_manager->add_group_control( Controls_Group::get_type(), new Controls_Group() ); + } + + public function add_controls_group_to_element( Element_Base $element ) { + $exclude = []; + + $selector = '{{WRAPPER}}'; + + if ( $element instanceof Element_Section ) { + $exclude[] = 'motion_fx_mouse'; + } elseif ( $element instanceof Element_Column ) { + $selector .= ' > .elementor-widget-wrap'; + } elseif ( $element instanceof Widget_Base ) { + if ( defined( get_class( $element ) . '::WRAPPER_SELECTOR' ) ) { + $selector = $element::WRAPPER_SELECTOR; + } else { + $selector .= ' > .elementor-widget-container'; + } + } + + $element->add_group_control( + Controls_Group::get_type(), + [ + 'name' => 'motion_fx', + 'selector' => $selector, + 'exclude' => $exclude, + ] + ); + + $this->add_asset_loading_control_to_element( $element, $exclude ); + } + + private function add_asset_loading_control_to_element( Element_Base $element, $exclude = [], $control_suffix = '' ) { + $element->add_control( + $control_suffix . 'handle_motion_fx_asset_loading', + [ + 'type' => Controls_Manager::HIDDEN, + 'assets' => [ + 'styles' => [ + [ + 'name' => 'e-motion-fx', + 'conditions' => $this->get_asset_loading_condition_conditions( $exclude, $control_suffix ), + ], + ], + ], + ] + ); + } + + private function get_asset_loading_condition_conditions( $exclude = [], $control_suffix = '' ) { + if ( '' === $control_suffix ) { + return [ + 'relation' => 'or', + 'terms' => $this->get_asset_loading_condition_terms( $exclude, $control_suffix ), + ]; + } + + return [ + 'terms' => [ + [ + 'name' => 'background_background', + 'operator' => '===', + 'value' => 'classic', + ], + [ + 'relation' => 'or', + 'terms' => $this->get_asset_loading_condition_terms( $exclude, $control_suffix ), + ], + ], + ]; + } + + private function get_asset_loading_condition_terms( $exclude = [], $control_suffix = '' ) { + $terms = [ + [ + 'name' => $control_suffix . 'motion_fx_motion_fx_scrolling', + 'operator' => '===', + 'value' => 'yes', + ], + ]; + + if ( in_array( 'motion_fx_mouse', $exclude, true ) ) { + return $terms; + } + + $terms[] = [ + 'name' => $control_suffix . 'motion_fx_motion_fx_mouse', + 'operator' => '===', + 'value' => 'yes', + ]; + + return $terms; + } + + public function add_controls_group_to_element_background( Element_Base $element ) { + $element->start_injection( [ + 'of' => 'background_bg_width_mobile', + ] ); + + $element->add_group_control( + Controls_Group::get_type(), + [ + 'name' => 'background_motion_fx', + 'exclude' => [ + 'rotateZ_effect', + 'tilt_effect', + 'transform_origin_x', + 'transform_origin_y', + ], + ] + ); + + $options = [ + 'separator' => 'before', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'background_background', + 'value' => 'classic', + ], + [ + 'terms' => [ + [ + 'name' => 'background_background', + 'value' => 'gradient', + ], + [ + 'name' => 'background_color', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'background_color_b', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ]; + + $element->update_control( 'background_motion_fx_motion_fx_scrolling', $options ); + + $element->update_control( 'background_motion_fx_motion_fx_mouse', $options ); + + $element->end_injection(); + + $this->add_asset_loading_control_to_element( $element, [], 'background_' ); + } + + public function register_frontend_styles() { + $suffix = Utils::is_script_debug() ? '' : '.min'; + + wp_register_style( + 'e-motion-fx', + ELEMENTOR_PRO_URL . 'assets/css/modules/motion-fx' . $suffix . '.css', + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function enqueue_preview_styles() { + wp_enqueue_style( 'e-motion-fx' ); + } + + private function add_actions() { + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_frontend_styles' ] ); + add_action( 'elementor/preview/enqueue_styles', [ $this, 'enqueue_preview_styles' ] ); + + add_action( 'elementor/controls/register', [ $this, 'register_controls_group' ] ); + + add_action( 'elementor/element/section/section_effects/after_section_start', [ $this, 'add_controls_group_to_element' ] ); + add_action( 'elementor/element/container/section_effects/after_section_start', [ $this, 'add_controls_group_to_element' ] ); + add_action( 'elementor/element/column/section_effects/after_section_start', [ $this, 'add_controls_group_to_element' ] ); + add_action( 'elementor/element/common/section_effects/after_section_start', [ $this, 'add_controls_group_to_element' ] ); + + add_action( 'elementor/element/section/section_background/before_section_end', [ $this, 'add_controls_group_to_element_background' ] ); + add_action( 'elementor/element/container/section_background/before_section_end', [ $this, 'add_controls_group_to_element_background' ] ); + add_action( 'elementor/element/column/section_style/before_section_end', [ $this, 'add_controls_group_to_element_background' ] ); + } +} diff --git a/modules/nav-menu/module.php b/modules/nav-menu/module.php new file mode 100644 index 00000000..1fc7b74d --- /dev/null +++ b/modules/nav-menu/module.php @@ -0,0 +1,57 @@ +breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-nav-menu', + Plugin::get_frontend_file_url( "widget-nav-menu{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/nav-menu/widgets/nav-menu.php b/modules/nav-menu/widgets/nav-menu.php new file mode 100644 index 00000000..56aae449 --- /dev/null +++ b/modules/nav-menu/widgets/nav-menu.php @@ -0,0 +1,1718 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-nav-menu' ]; + } + + protected function get_nav_menu_index() { + return $this->nav_menu_index++; + } + + private function get_available_menus() { + $menus = wp_get_nav_menus(); + + $options = []; + + foreach ( $menus as $menu ) { + $options[ $menu->slug ] = $menu->name; + } + + return $options; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'menu_name', + [ + 'label' => esc_html__( 'Menu Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Menu', 'elementor-pro' ), + ] + ); + + $menus = $this->get_available_menus(); + + if ( ! empty( $menus ) ) { + $this->add_control( + 'menu', + [ + 'label' => esc_html__( 'Menu', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $menus, + 'default' => array_keys( $menus )[0], + 'save_default' => true, + 'separator' => 'after', + 'description' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Go to the %1$sMenus screen%2$s to manage your menus.', 'elementor-pro' ), + sprintf( '', admin_url( 'nav-menus.php' ) ), + '' + ), + ] + ); + } else { + $this->add_control( + 'menu', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'heading' => esc_html__( 'There are no menus in your site.', 'elementor-pro' ), + 'content' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Go to the %1$sMenus screen%2$s to create one.', 'elementor-pro' ), + sprintf( '', admin_url( 'nav-menus.php?action=edit&menu=0' ) ), + '' + ), + 'separator' => 'after', + ] + ); + } + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'horizontal', + 'options' => [ + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'vertical' => esc_html__( 'Vertical', 'elementor-pro' ), + 'dropdown' => esc_html__( 'Dropdown', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $start = is_rtl() ? 'end' : 'start'; + $end = is_rtl() ? 'start' : 'end'; + + $this->add_control( + 'align_items', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-align-$start-h", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-align-$end-h", + ], + 'justify' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-align-stretch-h', + ], + ], + // For BC + 'classes_dictionary' => [ + 'left' => is_rtl() ? 'end' : 'start', + 'right' => is_rtl() ? 'start' : 'end', + ], + 'prefix_class' => 'elementor-nav-menu__align-', + 'condition' => [ + 'layout!' => 'dropdown', + ], + ] + ); + + $this->add_control( + 'pointer', + [ + 'label' => esc_html__( 'Pointer', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'underline', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'underline' => esc_html__( 'Underline', 'elementor-pro' ), + 'overline' => esc_html__( 'Overline', 'elementor-pro' ), + 'double-line' => esc_html__( 'Double Line', 'elementor-pro' ), + 'framed' => esc_html__( 'Framed', 'elementor-pro' ), + 'background' => esc_html__( 'Background', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + ], + 'style_transfer' => true, + 'condition' => [ + 'layout!' => 'dropdown', + ], + ] + ); + + $this->add_control( + 'animation_line', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'slide' => 'Slide', + 'grow' => 'Grow', + 'drop-in' => 'Drop In', + 'drop-out' => 'Drop Out', + 'none' => 'None', + ], + 'condition' => [ + 'layout!' => 'dropdown', + 'pointer' => [ 'underline', 'overline', 'double-line' ], + ], + ] + ); + + $this->add_control( + 'animation_framed', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'draw' => 'Draw', + 'corners' => 'Corners', + 'none' => 'None', + ], + 'condition' => [ + 'layout!' => 'dropdown', + 'pointer' => 'framed', + ], + ] + ); + + $this->add_control( + 'animation_background', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'fade', + 'options' => [ + 'fade' => 'Fade', + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'sweep-left' => 'Sweep Left', + 'sweep-right' => 'Sweep Right', + 'sweep-up' => 'Sweep Up', + 'sweep-down' => 'Sweep Down', + 'shutter-in-vertical' => 'Shutter In Vertical', + 'shutter-out-vertical' => 'Shutter Out Vertical', + 'shutter-in-horizontal' => 'Shutter In Horizontal', + 'shutter-out-horizontal' => 'Shutter Out Horizontal', + 'none' => 'None', + ], + 'condition' => [ + 'layout!' => 'dropdown', + 'pointer' => 'background', + ], + ] + ); + + $this->add_control( + 'animation_text', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'grow', + 'options' => [ + 'grow' => 'Grow', + 'shrink' => 'Shrink', + 'sink' => 'Sink', + 'float' => 'Float', + 'skew' => 'Skew', + 'rotate' => 'Rotate', + 'none' => 'None', + ], + 'condition' => [ + 'layout!' => 'dropdown', + 'pointer' => 'text', + ], + ] + ); + + $icon_prefix = Icons_Manager::is_migration_allowed() ? 'fas ' : 'fa '; + + $this->add_control( + 'submenu_icon', + [ + 'label' => esc_html__( 'Submenu Indicator', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'separator' => 'before', + 'default' => [ + 'value' => $icon_prefix . 'fa-caret-down', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-down', + 'angle-down', + 'caret-down', + 'plus', + ], + ], + 'label_block' => false, + 'skin' => 'inline', + 'exclude_inline_options' => [ 'svg' ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'heading_mobile_dropdown', + [ + 'label' => esc_html__( 'Mobile Dropdown', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'layout!' => 'dropdown', + ], + ] + ); + + // TODO: For Pro 3.6.0, convert this to the breakpoints utility method introduced in core 3.5.0. + $breakpoints = Plugin::elementor()->breakpoints->get_active_breakpoints(); + $dropdown_options = []; + $excluded_breakpoints = [ + 'laptop', + 'widescreen', + ]; + + foreach ( $breakpoints as $breakpoint_key => $breakpoint_instance ) { + // Do not include laptop and widscreen in the options since this feature is for mobile devices. + if ( in_array( $breakpoint_key, $excluded_breakpoints, true ) ) { + continue; + } + + $dropdown_options[ $breakpoint_key ] = sprintf( + /* translators: 1: Breakpoint label, 2: `>` character, 3: Breakpoint value. */ + esc_html__( '%1$s (%2$s %3$dpx)', 'elementor-pro' ), + $breakpoint_instance->get_label(), + '>', + $breakpoint_instance->get_value() + ); + } + + $dropdown_options['none'] = esc_html__( 'None', 'elementor-pro' ); + + $this->add_control( + 'dropdown', + [ + 'label' => esc_html__( 'Breakpoint', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'tablet', + 'options' => $dropdown_options, + 'prefix_class' => 'elementor-nav-menu--dropdown-', + 'condition' => [ + 'layout!' => 'dropdown', + ], + ] + ); + + $this->add_control( + 'full_width', + [ + 'label' => esc_html__( 'Full Width', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'description' => esc_html__( 'Stretch the dropdown of the menu to full width.', 'elementor-pro' ), + 'prefix_class' => 'elementor-nav-menu--', + 'return_value' => 'stretch', + 'frontend_available' => true, + 'condition' => [ + 'dropdown!' => 'none', + ], + ] + ); + + $this->add_control( + 'text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'aside', + 'options' => [ + 'aside' => esc_html__( 'Aside', 'elementor-pro' ), + 'center' => esc_html__( 'Center', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-nav-menu__text-align-', + 'condition' => [ + 'dropdown!' => 'none', + ], + ] + ); + + $this->add_control( + 'toggle', + [ + 'label' => esc_html__( 'Toggle Button', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'burger', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'burger' => esc_html__( 'Hamburger', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-nav-menu--toggle elementor-nav-menu--', + 'render_type' => 'template', + 'frontend_available' => true, + 'condition' => [ + 'dropdown!' => 'none', + ], + ] + ); + + $this->start_controls_tabs( 'nav_icon_options' ); + + $this->start_controls_tab( 'nav_icon_normal_options', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'toggle' => 'burger', + ], + ] ); + + $this->add_control( + 'toggle_icon_normal', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => esc_html__( 'Default', 'elementor-pro' ), + 'icon' => 'eicon-menu-bar', + ], + 'icon' => [ + 'icon' => 'eicon-star', + ], + ], + ], + 'recommended' => [ + 'fa-solid' => [ + 'plus-square', + 'plus', + 'plus-circle', + 'bars', + ], + 'fa-regular' => [ + 'plus-square', + ], + ], + 'condition' => [ + 'toggle' => 'burger', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'nav_icon_hover_options', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'toggle' => 'burger', + ], + ] ); + + $this->add_control( + 'toggle_icon_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + 'condition' => [ + 'toggle' => 'burger', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'nav_icon_active_options', [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + 'condition' => [ + 'toggle' => 'burger', + ], + ] ); + + $this->add_control( + 'toggle_icon_active', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => esc_html__( 'Default', 'elementor-pro' ), + 'icon' => 'eicon-close', + ], + 'icon' => [ + 'icon' => 'eicon-star', + ], + ], + ], + 'recommended' => [ + 'fa-solid' => [ + 'window-close', + 'times-circle', + 'times', + 'minus-square', + 'minus-circle', + 'minus', + ], + 'fa-regular' => [ + 'window-close', + 'times-circle', + 'minus-square', + ], + ], + 'condition' => [ + 'toggle' => 'burger', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'toggle_align', + [ + 'label' => esc_html__( 'Toggle Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors_dictionary' => [ + 'left' => 'margin-right: auto', + 'center' => 'margin: 0 auto', + 'right' => 'margin-left: auto', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-toggle' => '{{VALUE}}', + ], + 'condition' => [ + 'toggle!' => '', + 'dropdown!' => 'none', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_main-menu', + [ + 'label' => esc_html__( 'Main Menu', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'layout!' => 'dropdown', + ], + + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'menu_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-nav-menu .elementor-item', + ] + ); + + $this->start_controls_tabs( 'tabs_menu_item_style' ); + + $this->start_controls_tab( + 'tab_menu_item_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_menu_item', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_menu_item_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_menu_item_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item:hover, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item.elementor-item-active, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item.highlighted, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item:focus' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + 'condition' => [ + 'pointer!' => 'background', + ], + ] + ); + + $this->add_control( + 'color_menu_item_hover_pointer_bg', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#fff', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item:hover, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item.elementor-item-active, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item.highlighted, + {{WRAPPER}} .elementor-nav-menu--main .elementor-item:focus' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'pointer' => 'background', + ], + ] + ); + + $this->add_control( + 'pointer_color_menu_item_hover', + [ + 'label' => esc_html__( 'Pointer Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main:not(.e--pointer-framed) .elementor-item:before, + {{WRAPPER}} .elementor-nav-menu--main:not(.e--pointer-framed) .elementor-item:after' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .e--pointer-framed .elementor-item:before, + {{WRAPPER}} .e--pointer-framed .elementor-item:after' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'pointer!' => [ 'none', 'text' ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_menu_item_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_menu_item_active', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item.elementor-item-active' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'pointer_color_menu_item_active', + [ + 'label' => esc_html__( 'Pointer Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main:not(.e--pointer-framed) .elementor-item.elementor-item-active:before, + {{WRAPPER}} .elementor-nav-menu--main:not(.e--pointer-framed) .elementor-item.elementor-item-active:after' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .e--pointer-framed .elementor-item.elementor-item-active:before, + {{WRAPPER}} .e--pointer-framed .elementor-item.elementor-item-active:after' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'pointer!' => [ 'none', 'text' ], + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $divider_condition = [ + 'nav_menu_divider' => 'yes', + 'layout' => 'horizontal', + ]; + + $this->add_control( + 'nav_menu_divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'layout' => 'horizontal', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-divider-content: "";', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'nav_menu_divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + ], + 'default' => 'solid', + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-divider-style: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'nav_menu_divider_weight', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-divider-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'nav_menu_divider_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + '%' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-divider-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'nav_menu_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => $divider_condition, + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-divider-color: {{VALUE}}', + ], + ] + ); + + /* This control is required to handle with complicated conditions */ + $this->add_control( + 'hr', + [ + 'type' => Controls_Manager::DIVIDER, + ] + ); + + $this->add_responsive_control( + 'pointer_width', + [ + 'label' => esc_html__( 'Pointer Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 30, + ], + 'em' => [ + 'max' => 3, + ], + 'rem' => [ + 'max' => 3, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e--pointer-framed .elementor-item:before' => 'border-width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e--pointer-framed.e--animation-draw .elementor-item:before' => 'border-width: 0 0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e--pointer-framed.e--animation-draw .elementor-item:after' => 'border-width: {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0 0', + '{{WRAPPER}} .e--pointer-framed.e--animation-corners .elementor-item:before' => 'border-width: {{SIZE}}{{UNIT}} 0 0 {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e--pointer-framed.e--animation-corners .elementor-item:after' => 'border-width: 0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0', + '{{WRAPPER}} .e--pointer-underline .elementor-item:after, + {{WRAPPER}} .e--pointer-overline .elementor-item:before, + {{WRAPPER}} .e--pointer-double-line .elementor-item:before, + {{WRAPPER}} .e--pointer-double-line .elementor-item:after' => 'height: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'pointer' => [ 'underline', 'overline', 'double-line', 'framed' ], + ], + ] + ); + + $this->add_responsive_control( + 'padding_horizontal_menu_item', + [ + 'label' => esc_html__( 'Horizontal Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item' => 'padding-left: {{SIZE}}{{UNIT}}; padding-right: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'padding_vertical_menu_item', + [ + 'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main .elementor-item' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'menu_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-nav-menu-horizontal-menu-item-margin: calc( {{SIZE}}{{UNIT}} / 2 );', + '{{WRAPPER}} .elementor-nav-menu--main:not(.elementor-nav-menu--layout-horizontal) .elementor-nav-menu > li:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'border_radius_menu_item', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-item:before' => 'border-radius: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e--animation-shutter-in-horizontal .elementor-item:before' => 'border-radius: {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0 0', + '{{WRAPPER}} .e--animation-shutter-in-horizontal .elementor-item:after' => 'border-radius: 0 0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e--animation-shutter-in-vertical .elementor-item:before' => 'border-radius: 0 {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0', + '{{WRAPPER}} .e--animation-shutter-in-vertical .elementor-item:after' => 'border-radius: {{SIZE}}{{UNIT}} 0 0 {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'pointer' => 'background', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_dropdown', + [ + 'label' => esc_html__( 'Dropdown', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'dropdown_description', + [ + 'raw' => esc_html__( 'On desktop, this will affect the submenu. On mobile, this will affect the entire menu.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->start_controls_tabs( 'tabs_dropdown_item_style' ); + + $this->start_controls_tab( + 'tab_dropdown_item_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_dropdown_item', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a, {{WRAPPER}} .elementor-menu-toggle' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'background_color_dropdown_item', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_dropdown_item_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_dropdown_item_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a:hover, + {{WRAPPER}} .elementor-nav-menu--dropdown a:focus, + {{WRAPPER}} .elementor-nav-menu--dropdown a.elementor-item-active, + {{WRAPPER}} .elementor-nav-menu--dropdown a.highlighted, + {{WRAPPER}} .elementor-menu-toggle:hover, + {{WRAPPER}} .elementor-menu-toggle:focus' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'background_color_dropdown_item_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a:hover, + {{WRAPPER}} .elementor-nav-menu--dropdown a:focus, + {{WRAPPER}} .elementor-nav-menu--dropdown a.elementor-item-active, + {{WRAPPER}} .elementor-nav-menu--dropdown a.highlighted' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_dropdown_item_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'color_dropdown_item_active', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a.elementor-item-active' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'background_color_dropdown_item_active', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a.elementor-item-active' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'dropdown_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'exclude' => [ 'line_height' ], + 'selector' => '{{WRAPPER}} .elementor-nav-menu--dropdown .elementor-item, {{WRAPPER}} .elementor-nav-menu--dropdown .elementor-sub-item', + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'dropdown_border', + 'selector' => '{{WRAPPER}} .elementor-nav-menu--dropdown', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'dropdown_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .elementor-nav-menu--dropdown li:first-child a' => 'border-top-left-radius: {{TOP}}{{UNIT}}; border-top-right-radius: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .elementor-nav-menu--dropdown li:last-child a' => 'border-bottom-right-radius: {{BOTTOM}}{{UNIT}}; border-bottom-left-radius: {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'dropdown_box_shadow', + 'exclude' => [ + 'box_shadow_position', + ], + 'selector' => '{{WRAPPER}} .elementor-nav-menu--main .elementor-nav-menu--dropdown, {{WRAPPER}} .elementor-nav-menu__container.elementor-nav-menu--dropdown', + ] + ); + + $this->add_responsive_control( + 'padding_horizontal_dropdown_item', + [ + 'label' => esc_html__( 'Horizontal Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'vw' => [ + 'min' => 0, + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a' => 'padding-left: {{SIZE}}{{UNIT}}; padding-right: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + + ] + ); + + $this->add_responsive_control( + 'padding_vertical_dropdown_item', + [ + 'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vh' => [ + 'min' => 0, + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown a' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_dropdown_divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'dropdown_divider', + 'selector' => '{{WRAPPER}} .elementor-nav-menu--dropdown li:not(:last-child)', + 'exclude' => [ 'width' ], + ] + ); + + $this->add_control( + 'dropdown_divider_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--dropdown li:not(:last-child)' => 'border-bottom-width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'dropdown_divider_border!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'dropdown_top_distance', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => -100, + 'max' => 100, + ], + 'em' => [ + 'min' => -10, + 'max' => 10, + ], + 'rem' => [ + 'min' => -10, + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-nav-menu--main > .elementor-nav-menu > li > .elementor-nav-menu--dropdown, {{WRAPPER}} .elementor-nav-menu__container.elementor-nav-menu--dropdown' => 'margin-top: {{SIZE}}{{UNIT}} !important', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( 'style_toggle', + [ + 'label' => esc_html__( 'Toggle Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'toggle!' => '', + 'dropdown!' => 'none', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_toggle_style' ); + + $this->start_controls_tab( + 'tab_toggle_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'toggle_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} div.elementor-menu-toggle' => 'color: {{VALUE}}', // Harder selector to override text color control + '{{WRAPPER}} div.elementor-menu-toggle svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-toggle' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_toggle_style_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'toggle_color_hover', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} div.elementor-menu-toggle:hover, {{WRAPPER}} div.elementor-menu-toggle:focus' => 'color: {{VALUE}}', // Harder selector to override text color control + '{{WRAPPER}} div.elementor-menu-toggle:hover svg, {{WRAPPER}} div.elementor-menu-toggle:focus svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-toggle:hover, {{WRAPPER}} .elementor-menu-toggle:focus' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'toggle_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 15, + ], + 'em' => [ + 'max' => 1.5, + ], + 'rem' => [ + 'max' => 1.5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--nav-menu-icon-size: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'toggle_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-toggle' => 'border-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'toggle_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-toggle' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + public function get_frontend_settings() { + $frontend_settings = parent::get_frontend_settings(); + + // If the saved value is FA4, but the user has upgraded to FA5, the value needs to be converted to FA5. + if ( 'fa ' === substr( $frontend_settings['submenu_icon']['value'], 0, 3 ) && Icons_Manager::is_migration_allowed() ) { + $frontend_settings['submenu_icon']['value'] = str_replace( 'fa ', 'fas ', $frontend_settings['submenu_icon']['value'] ); + } + + // Determine the submenu icon markup. + if ( Plugin::elementor()->experiments->is_feature_active( 'e_font_icon_svg' ) ) { + $icon_classes = [ 'aria-hidden' => 'true' ]; + + if ( false !== strpos( $frontend_settings['submenu_icon']['value'], 'chevron-down' ) ) { + $icon_classes['class'] = 'fa-svg-chevron-down'; + } + + $icon_content = Icons_Manager::render_font_icon( $frontend_settings['submenu_icon'], $icon_classes ); + } else { + $icon_content = sprintf( '', esc_attr( $frontend_settings['submenu_icon']['value'] ) ); + } + + // Passing the entire icon markup to the frontend settings because it can be either or tag. + $frontend_settings['submenu_icon']['value'] = $icon_content; + + return $frontend_settings; + } + + protected function render() { + $available_menus = $this->get_available_menus(); + + if ( ! $available_menus ) { + return; + } + + $settings = $this->get_active_settings(); + + $args = [ + 'echo' => false, + 'menu' => $settings['menu'], + 'menu_class' => 'elementor-nav-menu', + 'menu_id' => 'menu-' . $this->get_nav_menu_index() . '-' . $this->get_id(), + 'fallback_cb' => '__return_empty_string', + 'container' => '', + ]; + + if ( 'vertical' === $settings['layout'] ) { + $args['menu_class'] .= ' sm-vertical'; + } + + // Add custom filter to handle Nav Menu HTML output. + add_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_classes' ], 10, 4 ); + add_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_tabindex' ], 10, 4 ); + add_filter( 'nav_menu_submenu_css_class', [ $this, 'handle_sub_menu_classes' ] ); + add_filter( 'nav_menu_item_id', '__return_empty_string' ); + + // General Menu. + $menu_html = wp_nav_menu( $args ); + + // Dropdown Menu. + $args['menu_id'] = 'menu-' . $this->get_nav_menu_index() . '-' . $this->get_id(); + $args['menu_type'] = 'dropdown'; + $dropdown_menu_html = wp_nav_menu( $args ); + + // Remove all our custom filters. + remove_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_classes' ] ); + remove_filter( 'nav_menu_link_attributes', [ $this, 'handle_link_tabindex' ] ); + remove_filter( 'nav_menu_submenu_css_class', [ $this, 'handle_sub_menu_classes' ] ); + remove_filter( 'nav_menu_item_id', '__return_empty_string' ); + + if ( empty( $menu_html ) ) { + return; + } + + if ( $settings['menu_name'] ) { + $this->add_render_attribute( 'main-menu', 'aria-label', $settings['menu_name'] ); + } + + $is_migrated = isset( $settings['__fa4_migrated']['submenu_icon'] ); + + if ( 'dropdown' !== $settings['layout'] ) : + $this->add_render_attribute( 'main-menu', 'class', [ + 'elementor-nav-menu--main', + 'elementor-nav-menu__container', + 'elementor-nav-menu--layout-' . $settings['layout'], + ] ); + + if ( $settings['pointer'] ) : + $this->add_render_attribute( 'main-menu', 'class', 'e--pointer-' . $settings['pointer'] ); + + foreach ( $settings as $key => $value ) : + if ( 0 === strpos( $key, 'animation' ) && $value ) : + $this->add_render_attribute( 'main-menu', 'class', 'e--animation-' . $value ); + + break; + endif; + endforeach; + endif; ?> + + render_menu_toggle( $settings ); + ?> + + classes ) ) { + $classes .= ' elementor-item-active'; + } + + if ( $is_anchor ) { + $classes .= ' elementor-item-anchor'; + } + + if ( empty( $atts['class'] ) ) { + $atts['class'] = $classes; + } else { + $atts['class'] .= ' ' . $classes; + } + + return $atts; + } + + public function handle_link_tabindex( $atts, $item, $args ) { + $settings = $this->get_active_settings(); + + // Add `tabindex = -1` to the links if it's a dropdown, for A11y. + $is_dropdown = 'dropdown' === $settings['layout']; + $is_dropdown = $is_dropdown || ( isset( $args->menu_type ) && 'dropdown' === $args->menu_type ); + + if ( $is_dropdown ) { + $atts['tabindex'] = '-1'; + } + + return $atts; + } + + public function handle_sub_menu_classes( $classes ) { + $classes[] = 'elementor-nav-menu--dropdown'; + + return $classes; + } + + private function render_menu_toggle( $settings ) { + if ( ! isset( $settings['toggle'] ) || 'burger' !== $settings['toggle'] ) { + return; + } + + $this->add_render_attribute( 'menu-toggle', [ + 'class' => 'elementor-menu-toggle', + 'role' => 'button', + 'tabindex' => '0', + 'aria-label' => esc_attr__( 'Menu Toggle', 'elementor-pro' ), + 'aria-expanded' => 'false', + ] ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + $this->add_render_attribute( 'menu-toggle', [ + 'class' => 'elementor-clickable', + ] ); + } + + ?> +
      print_render_attribute_string( 'menu-toggle' ); ?>> + 'eicons', + 'value' => 'eicon-menu-bar', + ]; + + $is_normal_icon_svg = 'svg' === $normal_icon['library']; + + if ( $is_normal_icon_svg ) { + echo ''; + } + + Icons_Manager::render_icon( + $normal_icon, + [ + 'aria-hidden' => 'true', + 'role' => 'presentation', + 'class' => $open_class, + ] + ); + + if ( $is_normal_icon_svg ) { + echo ''; + } + + $active_icon = ! empty( $settings['toggle_icon_active']['value'] ) + ? $settings['toggle_icon_active'] + : [ + 'library' => 'eicons', + 'value' => 'eicon-close', + ]; + + $is_active_icon_svg = 'svg' === $active_icon['library']; + + if ( $is_active_icon_svg ) { + echo ''; + } + + Icons_Manager::render_icon( + $active_icon, + [ + 'aria-hidden' => 'true', + 'role' => 'presentation', + 'class' => $close_class, + ] + ); + + if ( $is_active_icon_svg ) { + echo ''; + } + ?> +
      + term_id ?? 0; + + if ( ! empty( $menu_id ) ) { + $element['settings']['menu_id'] = $menu_id; + } + + return $element; + } + + /** + * When importing a menu, if the menu has a slug that already exists, we add "-duplicate" to the slug of the imported menu. + * Upon importing a menu widget, we replace the slug to the correct one by fetching it from the correct ID in the $data array. + * + * Please take note that this function overrides On_Import_Trait::on_import_update_dynamic_content(). + * + * @param array $element_config + * @param array $data + * @param $controls + * + * @return array + */ + public static function on_import_update_dynamic_content( array $element_config, array $data, $controls = null ) : array { + $old_menu_id = $element_config['settings']['menu_id'] ?? 0; + + if ( empty( $old_menu_id ) ) { + return $element_config; + } + + $new_menu_id = $data['term_ids'][ $old_menu_id ] ?? 0; + $new_slug = wp_get_nav_menu_object( $new_menu_id )->slug ?? ''; + + if ( ! empty( $new_slug ) ) { + $element_config['settings']['menu'] = $new_slug; + } + + unset( $element_config['settings']['menu_id'] ); + + return $element_config; + } +} diff --git a/modules/nested-carousel/module.php b/modules/nested-carousel/module.php new file mode 100644 index 00000000..f401e3b7 --- /dev/null +++ b/modules/nested-carousel/module.php @@ -0,0 +1,61 @@ +experiments->is_feature_active( 'nested-elements' ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/nested-carousel/assets/scss/frontend.scss` + * to `/assets/css/widget-nested-carousel.min.css`. + * + * @return void + */ + public function register_styles() { + wp_register_style( + 'widget-nested-carousel', + $this->get_css_assets_url( 'widget-nested-carousel', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/nested-carousel/widgets/nested-carousel.php b/modules/nested-carousel/widgets/nested-carousel.php new file mode 100644 index 00000000..05cde324 --- /dev/null +++ b/modules/nested-carousel/widgets/nested-carousel.php @@ -0,0 +1,511 @@ +experiments->is_feature_active( 'nested-elements', true ); + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'e-swiper', 'widget-nested-carousel' ]; + } + + /** + * Get script dependencies. + * + * Retrieve the list of script dependencies the widget requires. + * + * @since 3.27.0 + * @access public + * + * @return array Widget script dependencies. + */ + public function get_script_depends(): array { + return [ 'swiper' ]; + } + + protected function get_default_children_elements() { + return [ + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Slide #1', 'elementor-pro' ), + ], + ], + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Slide #2', 'elementor-pro' ), + ], + ], + [ + 'elType' => 'container', + 'settings' => [ + '_title' => __( 'Slide #3', 'elementor-pro' ), + ], + ], + ]; + } + + protected function get_default_repeater_title_setting_key() { + return 'slide_title'; + } + + protected function get_default_children_title() { + return esc_html__( 'Slide #%d', 'elementor-pro' ); + } + + protected function get_default_children_placeholder_selector() { + return '.swiper-wrapper'; + } + + protected function get_html_wrapper_class() { + return 'elementor-widget-n-carousel'; + } + + protected function register_controls() { + $low_specificity_slider_container_selector = ':where( {{WRAPPER}} .swiper-slide ) > .e-con'; + + $this->start_controls_section( + 'section_slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'slide_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Slide Title', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Slide Title', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + ] + ); + + $this->add_control( + 'carousel_name', + [ + 'label' => esc_html__( 'Carousel Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Carousel', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'carousel_items', + [ + 'label' => esc_html__( 'Carousel Items', 'elementor-pro' ), + 'type' => Control_Nested_Repeater::CONTROL_TYPE, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'slide_title' => esc_html__( 'Slide #1', 'elementor-pro' ), + ], + [ + 'slide_title' => esc_html__( 'Slide #2', 'elementor-pro' ), + ], + [ + 'slide_title' => esc_html__( 'Slide #3', 'elementor-pro' ), + ], + ], + 'frontend_available' => true, + 'title_field' => '{{{ slide_title }}}', + ] + ); + + $this->add_carousel_layout_controls( [ + 'css_prefix' => 'e-n-carousel-', + 'slides_to_show_custom_settings' => [ + 'separator' => 'before', + 'tablet_default' => '2', + 'mobile_default' => '1', + 'frontend_available' => true, + 'render_type' => 'template', + 'selectors' => [ + '{{WRAPPER}}' => '--e-n-carousel-swiper-slides-to-display: {{VALUE}}', + ], + ], + 'slides_to_scroll_custom_settings' => [], + 'equal_height_custom_settings' => [ + 'selectors' => [ + '{{WRAPPER}}' => '--e-n-carousel-slide-height: auto; --e-n-carousel-slide-container-height: 100%;', + ], + ], + 'slides_on_display' => 8, + ] ); + + $this->end_controls_section(); + + $this->add_carousel_settings_controls( [ + 'css_prefix' => 'e-n-carousel-', + 'autoplay_custom_settings' => [ + 'description' => esc_html__( 'The Autoplay is inactive while editing. Preview your page to see it in action.', 'elementor-pro' ), + ], + 'infinite_custom_settings' => [ + 'description' => esc_html__( 'Infinite scroll is inactive while editing. Preview your page to see it in action.', 'elementor-pro' ), + ], + 'offset_sides_custom_settings' => [ + 'description' => esc_html__( 'Offset is inactive while editing. Preview your page to see it in action.', 'elementor-pro' ), + ], + ] ); + + $this->add_carousel_navigation_controls( [ + 'css_prefix' => 'e-n-carousel-', + ] ); + + $this->add_carousel_pagination_controls( [ + 'css_prefix' => 'e-n-carousel-', + ] ); + + $this->start_controls_section( + 'section_slides_style', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'image_spacing_custom', + [ + 'label' => esc_html__( 'Gap between slides', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px' ], + 'range' => [ + 'px' => [ + 'max' => 400, + ], + ], + 'default' => [ + 'size' => 10, + ], + 'frontend_available' => true, + 'render_type' => 'none', + 'selectors' => [ + '{{WRAPPER}}' => '--e-n-carousel-swiper-slides-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'content_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => $low_specificity_slider_container_selector, + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'content_border', + 'selector' => $low_specificity_slider_container_selector, + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + ], + 'width' => [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + $low_specificity_slider_container_selector => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + // Todo: Remove in version 3.21.0: https://elementor.atlassian.net/browse/ED-11888. + // Remove together with support for physical properties inside the container widget. + $logical_dimensions_inline_start = is_rtl() ? '{{RIGHT}}{{UNIT}}' : '{{LEFT}}{{UNIT}}'; + $logical_dimensions_inline_end = is_rtl() ? '{{LEFT}}{{UNIT}}' : '{{RIGHT}}{{UNIT}}'; + + $this->add_responsive_control( + 'content_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + $low_specificity_slider_container_selector => '--padding-top: {{TOP}}{{UNIT}}; --padding-right: {{RIGHT}}{{UNIT}}; --padding-bottom: {{BOTTOM}}{{UNIT}}; --padding-left: {{LEFT}}{{UNIT}};', + // Todo: Remove in version 3.21.0: https://elementor.atlassian.net/browse/ED-11888. + // Remove together with support for physical properties inside the container widget. + ':where( [data-core-v316-plus="true"] .elementor-element.elementor-widget-n-carousel .swiper-slide ) > .e-con' => "--padding-block-start: {{TOP}}{{UNIT}}; --padding-inline-end: $logical_dimensions_inline_end; --padding-block-end: {{BOTTOM}}{{UNIT}}; --padding-inline-start: $logical_dimensions_inline_start;", + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->add_carousel_navigation_styling_controls( [ + 'css_prefix' => 'e-n-carousel-', + 'navigation_styling_custom_settings' => [ + 'condition' => [ + 'arrows' => 'yes', + ], + ], + ] ); + + $this->add_carousel_pagination_style_controls( [ + 'css_prefix' => 'e-n-carousel-', + ] ); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $this->num_of_carousel_items = count( $settings['carousel_items'] ?? [] ); + $slides = $settings['carousel_items']; + $direction = $settings['direction']; + $has_autoplay_enabled = 'yes' === $settings['autoplay']; + $outside_wrapper_classes = [ 'e-n-carousel', 'swiper' ]; + + $this->add_render_attribute( [ + 'carousel-outside-wrapper' => [ + 'class' => $outside_wrapper_classes, + 'role' => 'region', + 'aria-roledescription' => 'carousel', + 'aria-label' => $settings['carousel_name'], + ], + 'carousel-inside-wrapper' => [ + 'class' => 'swiper-wrapper', + 'aria-live' => $has_autoplay_enabled ? 'off' : 'polite', + ], + ] ); + + if ( ! empty( $direction ) ) { + $this->add_render_attribute( 'carousel-outside-wrapper', 'dir', $direction ); + } + ?> +
      print_render_attribute_string( 'carousel-outside-wrapper' ); ?>> +
      print_render_attribute_string( 'carousel-inside-wrapper' ); ?>> + $slide ) { + $slide_count = $index + 1; + $slide_setting_key = $this->get_repeater_setting_key( 'slide_wrapper', 'slide', $index ); + + $this->add_render_attribute( $slide_setting_key, [ + 'class' => 'swiper-slide', + 'data-slide' => $slide_count, + 'role' => 'group', + 'aria-roledescription' => 'slide', + 'aria-label' => sprintf( + /* translators: 1: Slide number. 2: Total amount of slides. */ + esc_attr__( '%1$s of %2$s', 'elementor-pro' ), + $slide_count, + count( $slides ) + ), + ] ); + ?> +
      print_render_attribute_string( $slide_setting_key ); ?>> + print_child( $index ); ?> +
      + +
      +
      + render_carousel_footer( $settings ); + } + + protected function get_initial_config(): array { + return array_merge( parent::get_initial_config(), [ + 'support_improved_repeaters' => true, + 'target_container' => [ '.e-n-carousel > .swiper-wrapper' ], + 'node' => 'div', + 'is_interlaced' => true, + ] ); + } + + protected function get_default_children_container_placeholder_selector() { + return '.swiper-slide'; + } + + protected function content_template_single_repeater_item() { + ?> + <# + const elementUid = view.getIDInt().toString().substr( 0, 3 ), + numOfSlides = view.collection.length + 1; + + const slideCount = numOfSlides, + slideUid = elementUid + slideCount, + slideWrapperKey = slideUid; + + const slideWrapperKeyItem = { + 'class': 'swiper-slide', + 'data-slide': slideCount, + 'role': 'group', + 'aria-roledescription': 'slide', + 'aria-label': slideCount + ' ' + numOfSlides, + }; + + view.addRenderAttribute( 'single-slide', slideWrapperKeyItem, null, true ); + #> +
      + + <# if ( settings['carousel_items'] ) { + const elementUid = view.getIDInt().toString().substr( 0, 3 ), + carouselOutsideWrapperKey = 'carousel-' + elementUid, + carouselInsideWrapperKey = 'carousel-inside-' + elementUid, + swiperWrapperClass = elementorFrontend.config.swiperClass, + hasAutoplayEnabled = 'yes' === settings['autoplay'], + outsideWrapperClasses = ['e-n-carousel',swiperWrapperClass] + shouldRenderPaginationAndArrows = 1 < settings['carousel_items'].length; + + view.addRenderAttribute( carouselOutsideWrapperKey, { + 'class': outsideWrapperClasses, + 'role': 'region', + 'aria-roledescription': 'carousel', + 'aria-label': settings['carousel_name'], + } ); + + view.addRenderAttribute( carouselInsideWrapperKey, { + 'class': 'swiper-wrapper', + 'aria-live': hasAutoplayEnabled ? 'off' : 'polite', + } ); + + if ( !! settings['direction'] ) { + view.addRenderAttribute( carouselOutsideWrapperKey, 'dir', settings['direction'] ); + } + #> +
      +
      + <# _.each( settings['carousel_items'], function( slide, index ) { + const slideCount = index + 1, + slideUid = elementUid + slideCount, + slideWrapperKey = slideUid; + + view.addRenderAttribute( slideWrapperKey, { + 'class': 'swiper-slide', + 'data-slide': slideCount, + 'role': 'group', + 'aria-roledescription': 'slide', + 'aria-label': slideCount + ' ' + settings['carousel_items'].length, + } ); + #> +
      + <# } ); #> +
      +
      + <# if ( 'yes' === settings['arrows'] && shouldRenderPaginationAndArrows ) { #> + content_template_navigation_arrows(); ?> + <# } #> + <# if ( settings['pagination'] && shouldRenderPaginationAndArrows ) { #> +
      + <# } #> + <# } #> + +
      + <# + const iconSettingsPrevious = settings['navigation_previous_icon'], + iconPreviousHTML = elementor.helpers.renderIcon( view, iconSettingsPrevious, { 'aria-hidden': true }, 'i' , 'object' ); + + if ( 'eicon-chevron-left' === iconSettingsPrevious['value'] ) { #> + 'eicons', + 'value' => 'eicon-chevron-left', + ] + ); ?> + <# } else if ( !! iconSettingsPrevious['value'] ) { #> + {{{ iconPreviousHTML.value }}} + <# } #> +
      +
      + <# + const iconSettingsNext = settings['navigation_next_icon'], + iconNextHTML = elementor.helpers.renderIcon( view, iconSettingsNext, { 'aria-hidden': true }, 'i' , 'object' ); + + if ( 'eicon-chevron-right' === iconSettingsNext['value'] ) { #> + 'eicons', + 'value' => 'eicon-chevron-right', + ] + ); ?> + <# } else if ( !! iconSettingsNext['value'] ) { #> + {{{ iconNextHTML.value }}} + <# } #> +
      + add_node( [ + 'id' => 'elementor_notes', + 'title' => esc_html__( 'Notes', 'elementor-pro' ), + 'href' => '#', // Click event is handled by JS. + ] ); + }, 200 ); // Before "Elementor Debugger". + } +} diff --git a/modules/notes/admin-page.php b/modules/notes/admin-page.php new file mode 100644 index 00000000..901bb33a --- /dev/null +++ b/modules/notes/admin-page.php @@ -0,0 +1,146 @@ +register_admin_menu(); + }, 206 ); // After Elementor. + + add_action( 'admin_head', function () { + $this->hide_menu_item(); + } ); + } + + /** + * Register the admin page (will be removed later from the menu). + * + * @return void + */ + protected function register_admin_menu() { + add_submenu_page( + Settings::PAGE_ID, + esc_html__( 'Notes Proxy', 'elementor-pro' ), + esc_html__( 'Notes Proxy', 'elementor-pro' ), + 'read', + static::PAGE_ID + ); + + add_action( 'current_screen', function ( \WP_Screen $current_screen ) { + if ( static::PAGE_ID !== $current_screen->id ) { + return; + } + + $this->on_page_load(); + } ); + } + + /** + * Hide the menu item, since it shouldn't be visible to users in the UI. + * + * @return void + */ + protected function hide_menu_item() { + remove_submenu_page( Settings::PAGE_ID, static::PAGE_ID ); + } + + /** + * Run the actual proxy page. + * + * @return void + */ + public function on_page_load() { + // No need for nonce check since it's not a user action, and it's safe. + if ( empty( $_GET['note-id'] ) || ! is_numeric( $_GET['note-id'] ) ) { // phpcs:ignore: WordPress.Security.NonceVerification.Recommended + $this->safe_redirect( get_site_url() ); + return; + } + + $note = Note::query()->find( (int) $_GET['note-id'] ); // phpcs:ignore: WordPress.Security.NonceVerification.Recommended + + if ( ! $note ) { + $message = esc_html__( 'The note you are looking for was not found.', 'elementor-pro' ); + + $go_to_dashboard = '' . esc_html__( 'Go to WP Dashboard', 'elementor-pro' ) . ''; + $view_site = '' . esc_html__( 'View Site', 'elementor-pro' ) . ''; + + $this->message_and_die( " + {$message} +

      + {$go_to_dashboard} +  |  + {$view_site} + " ); + + return; + } + + if ( ! current_user_can( Capabilities::READ_NOTES, $note ) ) { + $this->message_and_die( esc_html__( 'You are not autorized to view this Note. Please contact your admin.', 'elementor-pro' ) ); + return; + } + + $this->redirect_to_note( $note ); + } + + /** + * Redirect to a note - Used for testing. + * + * @param Note $note + * + * @return void + */ + protected function redirect_to_note( Note $note ) { + $url = $note->get_url( false ); + + // Note: The URL is safe. + // `header()` is used since `wp_safe_redirect()` filters chars like `{}` which are required in this case. + header( 'Location:' . $url, true, 302 ); + die; + } + + /** + * Safe redirect to a page - Used for testing. + * + * @param string $url + * + * @return void + */ + protected function safe_redirect( $url ) { + wp_safe_redirect( $url ); + die; + } + + /** + * Show a message to the user and die - Used for testing. + * + * @param string $message + * + * @return void + */ + protected function message_and_die( $message ) { + wp_die( $message ); // phpcs:ignore WordPress.Security.EscapeOutput + } +} diff --git a/modules/notes/data/controller.php b/modules/notes/data/controller.php new file mode 100644 index 00000000..1c646540 --- /dev/null +++ b/modules/notes/data/controller.php @@ -0,0 +1,768 @@ +user_transformer = new User_Transformer(); + } + + public function register_endpoints() { + $this->register_endpoint( new Read_Status_Endpoint( $this ) ); + $this->register_endpoint( new Summary_Endpoint( $this ) ); + $this->register_endpoint( new Users_Endpoint( $this ) ); + + $this->index_endpoint->register_item_route( \WP_REST_Server::READABLE, [ + 'id' => [ + 'type' => 'integer', + 'description' => 'Note ID to find.', + 'required' => true, + ], + ] ); + + $this->index_endpoint->register_items_route( \WP_REST_Server::CREATABLE, [ + 'post_id' => [ + 'type' => 'integer', + 'description' => 'The id of the post where the note was created at (can be template, post, page, etc.).', + 'required' => true, + 'validate_callback' => function ( $value ) { + return Plugin::elementor()->documents->get( $value ); + }, + ], + 'element_id' => [ + 'type' => 'string', + 'description' => 'Each note must be attached to an PRO Elements element.', + 'required' => true, + 'sanitize_callback' => function( $value ) { + return trim( $value ); + }, + 'validate_callback' => function ( $value ) { + return (bool) preg_match( '/^[a-z0-9]{7,9}$/', $value ); + }, + ], + 'content' => [ + 'type' => 'string', + 'description' => 'The content of the note.', + 'required' => true, + 'sanitize_callback' => function ( $value ) { + return $this->sanitize_content( $value ); + }, + 'validate_callback' => function ( $value ) { + return ! empty( $value ); + }, + ], + 'position' => [ + 'type' => 'object', + 'properties' => [ + 'x' => [ + 'required' => true, + 'type' => 'number', + ], + 'y' => [ + 'required' => true, + 'type' => 'number', + ], + ], + 'required' => true, + 'description' => 'The position of the note.', + ], + 'mentioned_usernames' => [ + 'type' => 'array', + 'description' => 'List of user names that have been mentioned in the note\'s content.', + 'default' => [], + 'items' => [ + 'type' => 'string', + 'sanitize_callback' => function ( $value ) { + return wp_strip_all_tags( $value, true ); + }, + ], + 'required' => false, + ], + 'route_post_id' => [ + 'description' => 'The ID of the post that\'s associated with the route (doesn\'t always exist, e.g: home page, archive)', + 'required' => false, + 'validate_callback' => function ( $value ) { + if ( ! $value ) { + return true; + } + + return is_numeric( $value ) && Plugin::elementor()->documents->get( $value ); + }, + 'sanitize_callback' => function ( $value ) { + if ( ! $value ) { + return null; + } + + return intval( $value ); + }, + ], + 'route_url' => [ + 'type' => 'string', + 'description' => 'The URL of the route where the note was created at.', + 'required' => false, + 'validate_callback' => function ( $value ) { + return Utils::validate_url_or_relative_url( $value ); + }, + 'sanitize_callback' => function ( $value ) { + return Utils::clean_url( $value ); + }, + ], + 'route_title' => [ + 'type' => 'string', + 'description' => 'The title of the route where the note was created at.', + 'required' => false, + 'sanitize_callback' => function ( $value ) { + return wp_strip_all_tags( $value, true ); + }, + ], + 'parent_id' => [ + 'type' => 'integer', + 'description' => 'If the new note is a reply to another note, the parent_id should be the thread\'s id.', + 'required' => false, + 'default' => 0, + ], + 'is_public' => [ + 'type' => 'boolean', + 'description' => 'Should this note be visible for everyone or just for its author.', + 'required' => false, + ], + ] ); + + $this->index_endpoint->register_item_route( \WP_REST_Server::EDITABLE, [ + 'id' => [ + 'type' => 'integer', + 'description' => 'The id the note.', + 'required' => true, + ], + 'content' => [ + 'type' => 'string', + 'description' => 'The content of the note.', + 'required' => false, + 'sanitize_callback' => function ( $value ) { + return $this->sanitize_content( $value ); + }, + ], + 'mentioned_usernames' => [ + 'type' => 'array', + 'description' => 'List of user names that have been mentioned in the note\'s content.', + 'items' => [ + 'type' => 'string', + 'sanitize_callback' => function ( $value ) { + return wp_strip_all_tags( $value, true ); + }, + ], + 'required' => false, + ], + 'status' => [ + 'type' => 'string', + 'description' => 'Note status can be draft or publish.', + 'required' => false, + 'enum' => [ + Note::STATUS_PUBLISH, + Note::STATUS_DRAFT, + ], + ], + 'is_public' => [ + 'type' => 'boolean', + 'description' => 'Should this note be visible for everyone or just for its author.', + 'required' => false, + ], + 'is_resolved' => [ + 'type' => 'boolean', + 'description' => 'Is this note resolved and should be hidden.', + 'required' => false, + ], + ] ); + + $this->index_endpoint->register_item_route( \WP_REST_Server::DELETABLE, [ + 'id' => [ + 'type' => 'integer', + 'description' => 'The id of the note.', + 'required' => true, + ], + 'force' => [ + 'type' => 'boolean', + 'description' => 'Determine if it should be deleted permanently or change the status to trash.', + 'default' => false, + 'required' => false, + ], + ] ); + } + + /** + * Notes index route params. + * + * @return array[] + */ + public function get_collection_params() { + return [ + 'route_url' => [ + 'type' => 'string', + 'description' => 'The URL of the route where the note was created at.', + 'required' => false, + 'validate_callback' => function ( $value ) { + return Utils::validate_url_or_relative_url( $value ); + }, + 'sanitize_callback' => function ( $value ) { + return Utils::clean_url( $value ); + }, + ], + 'status' => [ + 'type' => 'string', + 'description' => 'The note status (e.g. "publish", "draft").', + 'required' => false, + 'enum' => [ + Note::STATUS_PUBLISH, + Note::STATUS_DRAFT, + ], + 'default' => Note::STATUS_PUBLISH, + ], + 'is_resolved' => [ + 'type' => 'boolean', + 'description' => 'Whether the note is resolved or not.', + 'required' => false, + ], + 'parent_id' => [ + 'type' => 'integer', + 'description' => 'The note\'s parent id (use 0 for top-level).', + 'required' => false, + ], + 'post_id' => [ + 'type' => 'integer', + 'description' => 'The ID of the post that the note is attached to.', + 'required' => false, + 'validate_callback' => function ( $value ) { + return Plugin::elementor()->documents->get( $value ); + }, + ], + 'only_unread' => [ + 'type' => 'boolean', + 'description' => 'Show only unread notes (represents an unread thread if one of its replies is unread).', + 'required' => false, + ], + 'only_relevant' => [ + 'type' => 'boolean', + 'description' => 'Show only notes that are relevant to the current user.', + 'required' => false, + ], + 'order_by' => [ + 'type' => 'string', + 'description' => 'A column to order the results by.', + 'required' => false, + 'default' => 'last_activity_at', + 'enum' => [ + 'last_activity_at', + 'created_at', + ], + ], + 'order' => [ + 'type' => 'string', + 'description' => 'Results order direction.', + 'required' => false, + 'default' => 'desc', + 'enum' => [ + 'asc', + 'desc', + ], + ], + ]; + } + + /** + * Get all Notes by filters. + * + * GET `/notes` + * + * @param \WP_REST_Request $request + * + * @return array + */ + public function get_items( $request ) { + $user_id = get_current_user_id(); + + $notes_query = Note::query() + ->with_replies_count() + ->with_unread_replies_count( $user_id ) + ->with_is_read( $user_id ) + ->with_author() + ->only_visible( $user_id ) + ->order_by( + $request->get_param( 'order_by' ), + $request->get_param( 'order' ) + ); + + foreach ( $this->get_filters() as $param => $callback ) { + if ( $request->has_param( $param ) ) { + call_user_func( $callback, $notes_query, $request->get_param( $param ) ); + } + } + + $notes = $notes_query->get()->filter( function ( Note $note ) { + return current_user_can( Capabilities::READ_NOTES, $note ); + } )->map( function ( Note $note ) { + return $this->transform_users( $note ); + } ); + + return [ + 'data' => $notes, + 'meta' => [], + ]; + } + + /** + * Get a single note. + * + * GET `/notes/{id}` + * + * @param \WP_REST_Request $request + * + * @return array + */ + public function get_item( $request ) { + $user_id = get_current_user_id(); + + /** + * @var $note Note|null + */ + $note = Note::query() + ->where( 'id', '=', $request->get_param( 'id' ) ) + ->with_replies( function ( Note_Query_Builder $q ) use ( $user_id ) { + $q->with_author()->with_is_read( $user_id )->with_readers(); + } ) + ->with_replies_count() + ->with_unread_replies_count( $user_id ) + ->with_is_read( $user_id ) + ->with_author() + ->with_readers() + ->with_document() + ->first(); + + if ( ! $note ) { + throw new Error_404(); + } + + $note = $this->transform_users( $note ); + $note->attach_user_capabilities( $user_id ); + + return [ + 'data' => $note, + 'meta' => [], + ]; + } + + /** + * Run all user models in the note through user transformer. + * + * @param Note $note + * + * @return Note + */ + protected function transform_users( Note $note ) { + if ( ! empty( $note->author ) ) { + $note->author = $this->user_transformer->transform( $note->author ); + } + + if ( ! $note->readers->is_empty() ) { + $note->readers = $note->readers->map( function ( User $user ) { + return $this->user_transformer->transform( $user ); + } ); + } + + // If the note has replies, recursively run the function for each reply note. + if ( ! $note->replies->is_empty() ) { + $note->replies = $note->replies->map( function ( Note $reply ) { + return $this->transform_users( $reply ); + } ); + } + + return $note; + } + + /** + * Create a note. + * + * POST `/notes` + * + * @param \WP_REST_Request $request + * + * @return array + * @throws \Exception + */ + public function create_items( $request ) { + $this->validate_create_items( $request ); + + $now = gmdate( 'Y-m-d H:i:s' ); + + $values = ( new Collection( $request->get_body_params() ) ) + ->only( [ + 'post_id', + 'element_id', + 'content', + 'route_post_id', + 'route_url', + 'route_title', + 'status', + 'parent_id', + 'is_public', + ] ) + ->merge( [ + 'author_id' => get_current_user_id(), + 'created_at' => $now, + 'updated_at' => $now, + 'last_activity_at' => $now, + 'position' => wp_json_encode( $request->get_param( 'position' ) ), + ] ) + ->all(); + + $id = Note::query()->insert( $values ); + + /** @var Note $note */ + $note = Note::query()->with_author()->find( $id ); + + $note = $this->transform_users( $note ); + + $mentioned = $note->sync_mentions( + $request->get_param( 'mentioned_usernames' ), + 'user_nicename' + ); + + // Set the note as read by its author. + $note->add_readers( [ get_current_user_id() ] ); + + // If it's a reply, the thread's `last_activity_at` should be updated as well. + if ( $note->is_reply() ) { + Note::query() + ->where( 'id', '=', $note->parent_id ) + ->update( [ 'last_activity_at' => $now ] ); + } + + // TODO: Use events system. + $this->on_note_created( [ + 'note' => $note, + 'mentioned' => $mentioned, + 'actor' => User::from_wp_user( wp_get_current_user() ), + ] ); + + return [ + 'data' => $note, + 'meta' => [], + ]; + } + + /** + * Update a note. + * + * PATCH `/notes/{id}` + * + * @param \WP_REST_Request $request + * + * @return array + */ + public function update_item( $request ) { + $this->validate_update_items( $request ); + + $now = gmdate( 'Y-m-d H:i:s' ); + + $values = ( new Collection( $request->get_params() ) ) + ->only( [ + 'content', + 'status', + 'is_public', + 'is_resolved', + ] ) + ->merge( [ + 'updated_at' => $now, + ] ) + ->merge( $request->has_param( 'is_resolved' ) ? [ + 'last_activity_at' => $now, + ] : [] ) + ->all(); + + Note::query() + ->where( 'id', '=', $request->get_param( 'id' ) ) + ->update( $values ); + + // Need to refetch the note after update + /** @var Note $note */ + $note = Note::query()->with_author()->find( $request->get_param( 'id' ) ); + + if ( $request->has_param( 'mentioned_usernames' ) ) { + $mentioned = $note->sync_mentions( + $request->get_param( 'mentioned_usernames' ), + 'user_nicename' + ); + } + + // TODO: Use events system. + $this->on_note_updated( [ + 'note' => $note, + 'actor' => User::from_wp_user( wp_get_current_user() ), + 'mentioned' => isset( $mentioned ) ? $mentioned : null, + 'resolved' => ! ! $request->get_param( 'is_resolved' ), + ] ); + + return [ + 'data' => $note, + 'meta' => [], + ]; + } + + /** + * Delete a note. + * + * DELETE `/notes/{id}` + * + * @param \WP_REST_Request $request + * + * @return \WP_REST_Response + * @throws \Elementor\Data\V2\Base\Exceptions\Error_404 + */ + public function delete_item( $request ) { + /** @var Note $note */ + $note = Note::query()->find( $request->get_param( 'id' ) ); + + if ( ! $note ) { + throw new Error_404(); + } + + Note::query() + ->where( 'id', '=', $note->id ) + ->when( + $request->get_param( 'force' ), + function ( Note_Query_Builder $query ) { + $query->delete( true ); + }, + function ( Note_Query_Builder $query ) { + $query->trash(); + } + ); + + // TODO: Should return status 204 when the $e.data will support it + return new \WP_REST_Response( [], Http_Status::OK ); + } + + /** + * @inheritDoc + */ + public function get_permission_callback( $request ) { + $capability = null; + $id = $request->get_param( 'id' ); + + switch ( $request->get_method() ) { + case 'GET': + $capability = Capabilities::READ_NOTES; + break; + case 'POST': + // When creating a note it checks if the user can create note for the parent note if 'parent_id' is provided. + $id = $request->get_param( 'parent_id' ); + $capability = Capabilities::CREATE_NOTES; + break; + case 'PUT': + case 'PATCH': + $capability = Capabilities::EDIT_NOTES; + break; + case 'DELETE': + $capability = Capabilities::DELETE_NOTES; + break; + } + + return $capability && current_user_can( $capability, $id ); + } + + /** + * Get the Notes filters. + * + * @return array + */ + public function get_filters() { + return [ + 'route_url' => function ( Note_Query_Builder $q, $url ) { + $q->where( 'route_url', '=', $url ); + }, + 'is_resolved' => function ( Note_Query_Builder $q, $is_resolved ) { + $q->where( 'is_resolved', '=', $is_resolved ); + }, + 'parent_id' => function ( Note_Query_Builder $q, $parent_id ) { + $q->where( 'parent_id', '=', $parent_id ); + }, + 'post_id' => function ( Note_Query_Builder $q, $post_id ) { + $q->where( 'post_id', '=', $post_id ); + }, + 'only_unread' => function ( Note_Query_Builder $q ) { + $q->only_unread( get_current_user_id() ); + }, + 'only_relevant' => function ( Note_Query_Builder $q ) { + $q->only_relevant( get_current_user_id() ); + }, + ]; + } + + /** + * Validates the create items endpoint. + * + * @param \WP_REST_Request $request + * + * @throws Data_Exception + * @throws Error_404 + */ + private function validate_create_items( \WP_REST_Request $request ) { + $parent_id = $request->get_param( 'parent_id' ); + + if ( ! $parent_id ) { + // The validation is related only if the new note should be reply. + return; + } + + /** @var Note $parent */ + $parent = Note::query()->find( $parent_id ); + + if ( ! $parent ) { + throw new Error_404(); + } + + if ( $parent->is_reply() ) { + throw new Data_Exception( + 'Cannot create reply on reply.', + 'rest_invalid_param', + [ 'status' => Http_Status::BAD_REQUEST ] + ); + } + + if ( $request->has_param( 'is_public' ) ) { + throw new Data_Exception( + "Cannot update 'is_public' on reply.", + 'rest_invalid_param', + [ 'status' => Http_Status::BAD_REQUEST ] + ); + } + } + + /** + * Validates the update item endpoint. + * + * @param \WP_REST_Request $request + * + * @throws Data_Exception + * @throws Error_404 + */ + private function validate_update_items( \WP_REST_Request $request ) { + /** @var Note $note */ + $note = Note::query()->find( $request->get_param( 'id' ) ); + + if ( ! $note ) { + throw new Error_404(); + } + + $has_invalid_reply_attributes = $request->has_param( 'is_resolved' ) || $request->has_param( 'is_public' ); + + if ( $note->is_reply() && $has_invalid_reply_attributes ) { + throw new Data_Exception( + "Cannot update 'is_resolved' or 'is_public' on reply.", + 'rest_invalid_param', + [ 'status' => Http_Status::BAD_REQUEST ] + ); + } + + // For notifications - To make sure that there are no redundant resolve notifications. + if ( $note->is_resolved === $request->get_param( 'is_resolved' ) ) { + throw new Data_Exception( + "'is_resolved' was already set on '{$note->is_resolved}'.", + 'rest_invalid_param', + [ 'status' => Http_Status::BAD_REQUEST ] + ); + } + } + + /** + * Handle note creation side-effects. + * + * @param array $event + * + * @return void + */ + protected function on_note_created( array $event ) { + foreach ( $event['mentioned'] as $user ) { + $user->notify( new User_Mentioned_Notification( $event['note'], $event['actor'] ) ); + } + + if ( $event['note']->is_reply() ) { + $relevant = User::query()->only_relevant_to_note( $event['note'] )->get(); + + foreach ( $relevant as $user ) { + $user->notify( new User_Replied_Notification( + $event['note'], + $event['actor'], + $event['mentioned']->pluck( 'ID' )->all() + ) ); + } + } + } + + /** + * Handle note update side-effects. + * + * @param array $event + * + * @return void + */ + protected function on_note_updated( array $event ) { + if ( ! empty( $event['mentioned'] ) ) { + foreach ( $event['mentioned'] as $user ) { + $user->notify( new User_Mentioned_Notification( $event['note'], $event['actor'] ) ); + } + } + + if ( ! empty( $event['resolved'] ) ) { + $relevant = User::query()->only_relevant_to_note( $event['note'] )->get(); + + foreach ( $relevant as $user ) { + $user->notify( new User_Resolved_Notification( + $event['note'], + $event['actor'] + ) ); + } + } + } + + /** + * Sanitize note content. + * + * - Trims empty lines & spaces from start/end of the string. + * - Encodes HTML entities. + * + * @param string $raw_content + * + * @return string + */ + private function sanitize_content( $raw_content ) { + return htmlentities( preg_replace( '/(^[\n\s]+|[\n\s]+$)/', '', $raw_content ) ); + } +} diff --git a/modules/notes/data/endpoints/read-status-endpoint.php b/modules/notes/data/endpoints/read-status-endpoint.php new file mode 100644 index 00000000..40207e13 --- /dev/null +++ b/modules/notes/data/endpoints/read-status-endpoint.php @@ -0,0 +1,131 @@ + [ + 'type' => 'array', + 'description' => 'The id\'s of the notes.', + 'items' => [ + 'type' => 'integer', + ], + 'required' => true, + ], + ]; + + $this->register_items_route( \WP_REST_Server::CREATABLE, $args ); + $this->register_items_route( \WP_REST_Server::DELETABLE, $args ); + } + + /** + * Mark notes as read by the current user. + * + * @param \WP_REST_Request $request + * + * @return \WP_REST_Response + */ + protected function create_items( $request ) { + $user_id = get_current_user_id(); + $notes = $this->get_notes( + $request->get_param( 'ids' ), + true + ); + + /** @var Note $note */ + foreach ( $notes as $note ) { + $reader = $note->readers->find( function ( User $user ) use ( $user_id ) { + return $user->ID === $user_id; + } ); + + if ( ! $reader ) { + $note->add_readers( [ $user_id ] ); + } + } + + return new \WP_REST_Response( [], Http_Status::CREATED ); + } + + /** + * Mark notes as unread by the current user. + * + * @param \WP_REST_Request $request + * + * @return \WP_REST_Response + */ + protected function delete_items( $request ) { + $user_id = get_current_user_id(); + $notes = $this->get_notes( $request->get_param( 'ids' ) ); + + /** @var Note $note */ + foreach ( $notes as $note ) { + $note->remove_readers( [ $user_id ] ); + } + + // TODO: Should return status 204 when the $e.data will support it + return new \WP_REST_Response( [], Http_Status::OK ); + } + + /** + * @inheritDoc + */ + public function get_permission_callback( $request ) { + $can_read_notes = false; + + foreach ( $this->get_notes( $request->get_param( 'ids' ) ) as $note ) { + $can_read_notes = current_user_can( Capabilities::READ_NOTES, $note ); + + if ( false === $can_read_notes ) { + break; + } + } + + return $can_read_notes; + } + + /** + * Get notes by their ids. + * + * @param array $ids + * @param bool $with_readers + * + * @return Collection + */ + private function get_notes( array $ids, $with_readers = false ) { + return Note::query() + ->where_in( 'id', $ids ) + ->when( $with_readers, function ( Note_Query_Builder $builder ) { + return $builder->with_readers(); + } ) + ->get(); + } +} diff --git a/modules/notes/data/endpoints/summary-endpoint.php b/modules/notes/data/endpoints/summary-endpoint.php new file mode 100644 index 00000000..c6088771 --- /dev/null +++ b/modules/notes/data/endpoints/summary-endpoint.php @@ -0,0 +1,67 @@ +register_items_route( + \WP_REST_Server::READABLE, + $this->get_controller()->get_collection_params() + ); + } + + /** + * Index route. + * + * GET `/notes/summary` + * + * @param \WP_REST_Request $request + * + * @return array + */ + protected function get_items( $request ) { + $user_id = get_current_user_id(); + + $query = Note_Summary::query() + ->only_visible( $user_id ) + ->only_visible_posts( $user_id ); + + foreach ( $this->get_controller()->get_filters() as $param => $callback ) { + if ( $request->has_param( $param ) ) { + call_user_func( $callback, $query, $request->get_param( $param ) ); + } + } + + return [ + 'data' => $query->get(), + 'meta' => [], + ]; + } + + /** + * @inheritDoc + */ + public function get_permission_callback( $request ) { + return current_user_can( Capabilities::READ_NOTES ); + } +} diff --git a/modules/notes/data/endpoints/users-endpoint.php b/modules/notes/data/endpoints/users-endpoint.php new file mode 100644 index 00000000..0b8c7f13 --- /dev/null +++ b/modules/notes/data/endpoints/users-endpoint.php @@ -0,0 +1,131 @@ +register_items_route( + \WP_REST_Server::READABLE, + [ + 'limit' => [ + 'type' => 'integer', + 'description' => 'Limit the results.', + 'required' => false, + ], + 'order_by' => [ + 'type' => 'string', + 'description' => 'A column to order the results by.', + 'required' => false, + 'default' => 'display_name', + 'enum' => [ + 'user_nicename', + 'display_name', + 'user_registered', + ], + ], + 'order' => [ + 'type' => 'string', + 'description' => 'Results order direction.', + 'required' => false, + 'default' => 'asc', + 'enum' => [ + 'asc', + 'desc', + ], + ], + 'search' => [ + 'type' => 'string', + 'description' => 'Filter users by a search term.', + 'required' => false, + 'sanitize_callback' => function ( $value ) { + return wp_strip_all_tags( $value, true ); + }, + ], + ] + ); + } + + /** + * Index route. + * + * GET `/notes/users` + * + * @param \WP_REST_Request $request + * + * @return array + */ + protected function get_items( $request ) { + $users = User::query() + ->order_by( + $request->get_param( 'order_by' ), + $request->get_param( 'order' ) + ); + + foreach ( $this->get_filters() as $param => $callback ) { + if ( $request->has_param( $param ) ) { + call_user_func( $callback, $users, $request->get_param( $param ) ); + } + } + + $transformer = new User_Transformer(); + $transform_dependencies = []; + + if ( ! empty( $_GET['post_id'] ) ) { + $transform_dependencies['post_id'] = (int) $_GET['post_id']; + } + + return [ + 'data' => $users->get()->map( function ( User $user ) use ( $transformer, $transform_dependencies ) { + return $transformer->transform( $user, $transform_dependencies ); + } ), + 'meta' => [], + ]; + } + + /** + * @inheritDoc + */ + public function get_permission_callback( $request ) { + return current_user_can( Capabilities::CREATE_NOTES ); + } + + /** + * Get the Users filters. + * + * @return array + */ + protected function get_filters() { + return [ + 'limit' => function ( User_Query_Builder $q, $limit ) { + $q->limit( $limit ); + }, + 'search' => function ( User_Query_Builder $q, $search ) { + $q->where( 'user_nicename', 'LIKE', '%' . $search . '%' ) + ->or_where( 'user_email', 'LIKE', '%' . $search . '%' ) + ->or_where( 'display_name', 'LIKE', '%' . $search . '%' ); + }, + ]; + } +} diff --git a/modules/notes/database/migrations/add-author-display-name.php b/modules/notes/database/migrations/add-author-display-name.php new file mode 100644 index 00000000..8c3e350b --- /dev/null +++ b/modules/notes/database/migrations/add-author-display-name.php @@ -0,0 +1,27 @@ +add_columns( Module::TABLE_NOTES, [ + 'author_display_name' => 'varchar(250) null comment "Save the author name when the author was deleted." AFTER `author_id`', + ] ); + } + + /** + * @inheritDoc + */ + public function down() { + $this->drop_columns( Module::TABLE_NOTES, [ 'author_display_name' ] ); + } +} diff --git a/modules/notes/database/migrations/add-capabilities.php b/modules/notes/database/migrations/add-capabilities.php new file mode 100644 index 00000000..43dc2826 --- /dev/null +++ b/modules/notes/database/migrations/add-capabilities.php @@ -0,0 +1,41 @@ +add_cap( $capability ); + } + } + } + + /** + * @inheritDoc + */ + public function down() { + $roles = array_values( wp_roles()->role_objects ); + + foreach ( $roles as $role ) { + if ( ! ( $role instanceof \WP_Role ) ) { + continue; + } + + foreach ( Capabilities::all() as $cap ) { + $role->remove_cap( $cap ); + } + } + } +} diff --git a/modules/notes/database/migrations/add-note-position.php b/modules/notes/database/migrations/add-note-position.php new file mode 100644 index 00000000..4d526236 --- /dev/null +++ b/modules/notes/database/migrations/add-note-position.php @@ -0,0 +1,27 @@ +add_columns( Module::TABLE_NOTES, [ + 'position' => 'text null comment "A JSON string that represents the position of the note inside the element in percentages. e.g. {x:10, y:15}" AFTER `status`', + ] ); + } + + /** + * @inheritDoc + */ + public function down() { + $this->drop_columns( Module::TABLE_NOTES, [ 'position' ] ); + } +} diff --git a/modules/notes/database/migrations/add-route-post-id.php b/modules/notes/database/migrations/add-route-post-id.php new file mode 100644 index 00000000..946ee3c2 --- /dev/null +++ b/modules/notes/database/migrations/add-route-post-id.php @@ -0,0 +1,27 @@ +add_columns( Module::TABLE_NOTES, [ + 'route_post_id' => 'bigint(20) unsigned null comment "The post id of the route that the note was created on." AFTER `route_title`', + ] ); + } + + /** + * @inheritDoc + */ + public function down() { + $this->drop_columns( Module::TABLE_NOTES, [ 'route_post_id' ] ); + } +} diff --git a/modules/notes/database/migrations/initial.php b/modules/notes/database/migrations/initial.php new file mode 100644 index 00000000..a261191c --- /dev/null +++ b/modules/notes/database/migrations/initial.php @@ -0,0 +1,72 @@ +create_table( Module::TABLE_NOTES, [ + 'id' => 'bigint(20) unsigned auto_increment primary key', + 'route_url' => 'text null comment "Clean url where the note was created."', + 'route_title' => 'varchar(255) null', + 'post_id' => 'bigint(20) unsigned null', + 'element_id' => 'varchar(60) null comment "The Elementor element ID the note is attached to."', + 'parent_id' => 'bigint(20) unsigned default 0 not null', + 'author_id' => 'bigint(20) unsigned null', + 'status' => 'varchar(20) default "publish" not null', + 'content' => 'longtext null', + 'is_resolved' => 'tinyint(1) default 0 not null', + 'is_public' => 'tinyint(1) default 1 not null', + 'last_activity_at' => 'datetime null', + 'created_at' => 'datetime not null', + 'updated_at' => 'datetime not null', + ] ); + + $this->create_indexes( + Module::TABLE_NOTES, + [ + 'route_url', + 'post_id', + 'element_id', + 'parent_id', + 'author_id', + 'status', + 'is_resolved', + 'is_public', + 'created_at', + 'updated_at', + 'last_activity_at', + ] + ); + + $this->create_table( Module::TABLE_NOTES_USERS_RELATIONS, [ + 'id' => 'bigint(20) unsigned auto_increment primary key', + 'type' => 'varchar(60) not null comment "The relation type between user and note (e.g mention, watch, read)."', + 'note_id' => 'bigint(20) unsigned not null', + 'user_id' => 'bigint(20) unsigned not null', + 'created_at' => 'datetime not null', + 'updated_at' => 'datetime not null', + ] ); + + $this->create_indexes( + Module::TABLE_NOTES_USERS_RELATIONS, + [ 'type', 'note_id', 'user_id' ] + ); + } + + /** + * @inheritDoc + */ + public function down() { + $this->drop_table( Module::TABLE_NOTES ); + $this->drop_table( Module::TABLE_NOTES_USERS_RELATIONS ); + } +} diff --git a/modules/notes/database/models/document.php b/modules/notes/database/models/document.php new file mode 100644 index 00000000..cf1bef45 --- /dev/null +++ b/modules/notes/database/models/document.php @@ -0,0 +1,97 @@ + self::TYPE_INTEGER, + ]; + + /** + * Override the default Query Builder. + * + * @param \wpdb|null $connection + * + * @return Query_Builder + */ + public static function query( \wpdb $connection = null ) { + // PHPCS has an error without any reason, the method 'query' is not related to the `wpdb` object. + return parent::query( $connection ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ->select( [ + 'ID', + 'type' => 'postmeta.meta_value', + ] ) + ->left_join( function ( Join_Clause $j ) { + return $j->table( 'postmeta' ) + ->on_column( 'posts.ID', '=', 'postmeta.post_id' ) + ->on( 'postmeta.meta_key', '=', OriginalDocument::TYPE_META_KEY ); + } ); + } + + /** + * Get the posts table name. + * + * @return string + */ + public static function get_table() { + return 'posts'; + } + + /** + * Get the label of a document. + * + * @return string|null + */ + public function get_type_title() { + if ( ! $this->type ) { + return null; + } + + $type_classname = Plugin::elementor()->documents->get_document_type( $this->type ); + + return $type_classname ? $type_classname::get_title() : null; + } + + /** + * Return a JSON serialized representation of the User. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() { + return [ + 'id' => $this->ID, + 'type' => $this->type, + 'type_title' => $this->get_type_title(), + ]; + } +} diff --git a/modules/notes/database/models/note-summary.php b/modules/notes/database/models/note-summary.php new file mode 100644 index 00000000..20ed439b --- /dev/null +++ b/modules/notes/database/models/note-summary.php @@ -0,0 +1,81 @@ + self::TYPE_INTEGER, + ]; + + /** + * @inheritDoc + */ + public function __construct( array $fields ) { + // Make sure each model comes with the full url alongside with the relative url. + $fields['full_url'] = get_site_url( null, $fields['url'] ); + + parent::__construct( $fields ); + } + + /** + * Override the default Query Builder. + * + * @param \wpdb|null $connection + * + * @return Note_Query_Builder + */ + public static function query( \wpdb $connection = null ) { + $table_name = static::get_table(); + + return ( new Note_Query_Builder( $connection ) ) + ->set_model( static::class ) + ->from( $table_name ) + ->select( [ + 'title' => 'route_title', + 'url' => 'route_url', + ] ) + ->add_count_select( "{$table_name}.id", 'notes_count' ) + ->group_by( 'route_url' ); + } + + /** + * Get the notes table name. + * + * @return string + */ + public static function get_table() { + return Module::TABLE_NOTES; + } +} diff --git a/modules/notes/database/models/note.php b/modules/notes/database/models/note.php new file mode 100644 index 00000000..b10e1cc0 --- /dev/null +++ b/modules/notes/database/models/note.php @@ -0,0 +1,471 @@ + 0, + 'y' => 0, + ]; + + /** + * Note's content. + * + * @var null|string + */ + public $content = null; + + /** + * Note's resolve status. + * + * @var bool + */ + public $is_resolved = false; + + /** + * Note's public status. + * + * @var bool + */ + public $is_public = true; + + /** + * Is the note read by the user. + * + * @var boolean + */ + public $is_read = false; + + /** + * Note's replies. + * + * @var Collection + */ + public $replies; + + /** + * Note's mentions. + * + * @var Collection + */ + public $mentions; + + /** + * Note's author. + * + * @var User + */ + public $author; + + /** + * Note's document + * + * @var Document + */ + public $document; + + /** + * Note's replies count. + * + * @var int + */ + public $replies_count = 0; + + /** + * Note's unread replies count. + * + * @var int + */ + public $unread_replies_count = 0; + + /** + * Note's readers. + * + * @var Collection + */ + public $readers; + + /** + * Note's creation time. + * + * @var \DateTime + */ + public $created_at; + + /** + * Note's last update time. + * + * @var \DateTime + */ + public $updated_at; + + /** + * Note's last activity time. + * + * @var \DateTime + */ + public $last_activity_at; + + /** + * User's capabilities for the current note. + * [ + * 'edit' => boolean, + * 'delete' => boolean, + * ] + * + * @var array + */ + public $user_can = []; + + /** + * Casts array. + * + * @var array + */ + protected static $casts = [ + 'id' => self::TYPE_INTEGER, + 'post_id' => self::TYPE_INTEGER, + 'route_post_id' => self::TYPE_INTEGER, + 'parent_id' => self::TYPE_INTEGER, + 'author_id' => self::TYPE_INTEGER, + 'position' => self::TYPE_JSON, + 'is_resolved' => self::TYPE_BOOLEAN, + 'is_public' => self::TYPE_BOOLEAN, + 'is_read' => self::TYPE_BOOLEAN, + 'replies' => self::TYPE_COLLECTION, + 'mentions' => self::TYPE_COLLECTION, + 'readers' => self::TYPE_COLLECTION, + 'replies_count' => self::TYPE_INTEGER, + 'unread_replies_count' => self::TYPE_INTEGER, + 'created_at' => self::TYPE_DATETIME_GMT, + 'updated_at' => self::TYPE_DATETIME_GMT, + 'last_activity_at' => self::TYPE_DATETIME_GMT, + ]; + + public function __construct( array $fields ) { + // Defaults must be empty collection, when there is no replies or mentions it should remain empty. + $this->replies = new Collection( [] ); + $this->mentions = new Collection( [] ); + $this->readers = new Collection( [] ); + + parent::__construct( $fields ); + } + + /** + * Override the default Query Builder. + * + * @param \wpdb|null $connection + * + * @return Note_Query_Builder + */ + public static function query( \wpdb $connection = null ) { + return ( new Note_Query_Builder( $connection ) )->from( static::get_table() ); + } + + /** + * Get the notes table name. + * + * @return string + */ + public static function get_table() { + return Module::TABLE_NOTES; + } + + /** + * Is the current note is top level note. + * + * @return bool + */ + public function is_thread() { + return 0 === $this->parent_id; + } + + /** + * Determine if the current note is a reply. + * + * @return bool + */ + public function is_reply() { + return ! $this->is_thread(); + } + + /** + * Get the thread ID of the current note. + * + * @return int + */ + public function get_thread_id() { + return $this->is_thread() ? $this->id : $this->parent_id; + } + + /** + * Get the note deep link. + * + * @param bool $force_auth - Whether to force authentication. Defaults to `true`. + * + * @return string + */ + public function get_url( $force_auth = true ) { + // NOTICE: Make sure that the returned URL is not dynamic! + return static::generate_url( + $this->get_thread_id(), + $this->route_url, + $force_auth + ); + } + + /** + * Generate a note deep link URL. + * + * @param string|int $id - Note ID. + * @param string $route_url - Note route URL. Required if `$force_auth = false`. + * @param bool $force_auth - Whether to force authentication. Defaults to `true`. Used in cases where the user + * should be passed through the proxy in order to force their authentication (since the + * "Notes" feature and the Web-CLI are available only for logged-in users). + * + * @return string + */ + public static function generate_url( $id = null, $route_url = '', $force_auth = true ) { + // Add a placeholder if ID doesn't exist (used for passing the note URL as a pattern). + $id = ( null === $id ) ? '{{NOTE_ID}}' : (int) $id; + + if ( $force_auth ) { + $page = sprintf( 'admin.php?page=%s¬e-id=%s', Admin_Page::PAGE_ID, $id ); + + return admin_url( $page ); + } + + $command = sprintf( '#e:run:notes/open?{"id":%s}', $id ); + $base_url = get_site_url( null, Utils::clean_url( $route_url ) ); + + return $base_url . $command; + } + + /** + * @shortcut `$this->add_user_relation()` + */ + public function add_readers( $user_ids = [] ) { + $this->add_user_relation( static::USER_RELATION_READ, $user_ids ); + } + + /** + * @shortcut `$this->remove_user_relation()` + */ + public function remove_readers( $user_ids = [] ) { + $this->remove_user_relation( static::USER_RELATION_READ, $user_ids ); + } + + /** + * @shortcut `$this->sync_user_relation()` + */ + public function sync_mentions( $user_keys = [], $key = 'ID' ) { + return $this->sync_user_relation( static::USER_RELATION_MENTION, $user_keys, $key ); + } + + /** + * @shortcut `$this->add_user_relation()` + */ + public function add_mentions( $user_ids = [] ) { + $this->add_user_relation( static::USER_RELATION_MENTION, $user_ids ); + } + + /** + * Remove old relations and add new ones. + * + * @param $type + * @param array $user_keys + * @param string $key + * + * @return Collection Only users with a newly created relation (excluding the existing ones). + */ + public function sync_user_relation( $type, array $user_keys, $key = 'ID' ) { + $users = User::query() + ->where_in( $key, $user_keys ) + ->get(); + + $already_has_relation = ( new Query_Builder() ) + ->select( [ 'user_id' ] ) + ->from( Module::TABLE_NOTES_USERS_RELATIONS ) + ->where( 'type', '=', $type ) + ->where( 'note_id', '=', $this->id ) + ->get() + ->pluck( 'user_id' ); + + $should_have_relation = $users + ->pluck( 'ID' ) + ->unique(); + + $should_remove = $already_has_relation->diff( $should_have_relation )->values(); + $should_insert = $should_have_relation->diff( $already_has_relation )->values(); + + // Delete all the previous relations. + $this->remove_user_relation( $type, $should_remove ); + + // Only the users that not already in relation. + $this->add_user_relation( $type, $should_insert ); + + // Return only the users that were inserted in the users_relations DB table. + return $users->filter( function ( User $user ) use ( $should_insert ) { + return in_array( $user->ID, $should_insert, true ); + } ); + } + + /** + * Remove user relation. + * + * @param $type + * @param array $user_ids + */ + public function remove_user_relation( $type, array $user_ids ) { + ( new Query_Builder() ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS ) + ->where( 'note_id', '=', $this->id ) + ->where( 'type', '=', $type ) + ->where_in( 'user_id', $user_ids ) + ->delete(); + } + + /** + * Add user relation. + * + * @param $type + * @param array $user_ids + * + * @throws \Exception + */ + public function add_user_relation( $type, array $user_ids ) { + $now = gmdate( 'Y-m-d H:i:s' ); + + foreach ( $user_ids as $user_id ) { + ( new Query_Builder() ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS ) + ->insert( [ + 'note_id' => $this->id, + 'user_id' => $user_id, + 'type' => $type, + 'created_at' => $now, + 'updated_at' => $now, + ] ); + } + } + + /** + * Add user capabilities to the Note and its replies. + * + * @param integer $user_id - User ID to use. + * @param bool $recursive - Whether to add the capabilities also to the replies. + * + * @return Note + */ + public function attach_user_capabilities( $user_id, $recursive = true ) { + $this->user_can = [ + 'edit' => user_can( $user_id, Capabilities::EDIT_NOTES, $this ), + 'delete' => user_can( $user_id, Capabilities::DELETE_NOTES, $this ), + ]; + + // Add the capabilities also to the replies. + if ( $recursive ) { + $this->replies = $this->replies->map( function ( Note $reply ) use ( $user_id ) { + $reply->user_can = [ + 'edit' => user_can( $user_id, Capabilities::EDIT_NOTES, $reply ), + 'delete' => user_can( $user_id, Capabilities::DELETE_NOTES, $reply ), + ]; + + return $reply; + } ); + } + + return $this; + } +} diff --git a/modules/notes/database/models/user.php b/modules/notes/database/models/user.php new file mode 100644 index 00000000..68768e08 --- /dev/null +++ b/modules/notes/database/models/user.php @@ -0,0 +1,130 @@ + self::TYPE_INTEGER, + ]; + + /** + * Initialize a new `User` object from a `WP_User` object. + * + * @param \WP_User $user - WP_User object. + * + * @return static + */ + public static function from_wp_user( \WP_User $user ) { + return new static( (array) $user->data ); + } + + /** + * Override the default Query Builder. + * + * @param \wpdb|null $connection + * + * @return \ElementorPro\Modules\Notes\Database\Query\User_Query_Builder() + */ + public static function query( \wpdb $connection = null ) { + return ( new User_Query_Builder( $connection ) )->from( static::get_table() ); + } + + /** + * Get the model's table name. + * + * @return string + */ + public static function get_table() { + return 'users'; + } + + /** + * Generate avatars urls based on user id. + * + * @param $id + * + * @return Collection + */ + public static function generate_avatars_urls( $id ) { + return ( new Collection( [ 24, 48, 96 ] ) )->map_with_keys( function ( $size ) use ( $id ) { + return [ $size => get_avatar_url( $id, [ 'size' => $size ] ) ]; + } ); + } + + /** + * Get the user's avatars. + * + * @return Collection + */ + public function get_avatars() { + return static::generate_avatars_urls( $this->ID ); + } +} diff --git a/modules/notes/database/notes-database-updater.php b/modules/notes/database/notes-database-updater.php new file mode 100644 index 00000000..11d337e3 --- /dev/null +++ b/modules/notes/database/notes-database-updater.php @@ -0,0 +1,45 @@ + new Initial(), + 2 => new Add_Capabilities(), + 3 => new Add_Author_Display_Name(), + 4 => new Add_Route_Post_Id(), + 5 => new Add_Note_Position(), + ]; + } + + /** + * @inheritDoc + */ + protected function get_db_version() { + return static::DB_VERSION; + } + + /** + * @inheritDoc + */ + protected function get_db_version_option_name() { + return static::OPTION_NAME; + } +} diff --git a/modules/notes/database/query/note-query-builder.php b/modules/notes/database/query/note-query-builder.php new file mode 100644 index 00000000..3a816bd3 --- /dev/null +++ b/modules/notes/database/query/note-query-builder.php @@ -0,0 +1,542 @@ +with_trashed ) { + $this->where( 'status', '!=', Note::STATUS_TRASH ); + } + + return parent::compile_wheres(); + } + + /** + * Set the `with_trashed` flag to `true`. + * + * @return $this + */ + public function with_trashed() { + $this->with_trashed = true; + + return $this; + } + + /** + * Eager load the Note's replies. + * + * @param callable|null $callback - Callback that gets a `Note_Query_Builder` to customize the replies query. + * + * @return $this + */ + public function with_replies( callable $callback = null ) { + $key = 'replies'; + $foreign_key = 'parent_id'; + $local_key = 'id'; + $builder = Note::query(); + + return $this->add_with( $key, function ( Collection $notes ) use ( $callback, $key, $foreign_key, $local_key, $builder ) { + // Get all the replies. + $replies = $builder + ->where_in( + $foreign_key, + $notes->pluck( $local_key )->all() + ) + ->when( $callback, function ( Note_Query_Builder $q, callable $callback ) { + // Execute any user-defined callback. + // Used to extend the query (e.g. add another `where` or eager load relations). + call_user_func( $callback, $q ); + } ) + ->get() + ->group_by( $foreign_key ); // Group the replies by their thread. + + // Add the replies to each Note object. + return $notes->map( function ( $note ) use ( $replies, $key, $local_key ) { + $note[ $key ] = $replies->get( $note[ $local_key ], [] ); + + return $note; + } ); + } ); + } + + /** + * Eager load the Note's replies count. + * + * @return $this + */ + public function with_replies_count() { + return $this->add_sub_select( function ( Query_Builder $q ) { + $q->from( Module::TABLE_NOTES, 'replies' ) + ->select( [ 'replies.id' ], static::COLUMN_COUNT ) + ->where_column( 'replies.parent_id', '=', Module::TABLE_NOTES . '.id' ); + }, 'replies_count' ); + } + + /** + * Eager load the Note's readers. + * + * @return $this + */ + public function with_readers() { + return $this->add_with( 'readers', function ( Collection $notes ) { + $ids = $notes->pluck( 'id' )->all(); + + // Get all relations. + $pivot = ( new Query_Builder() ) + ->from( Module::TABLE_NOTES_USERS_RELATIONS ) + ->select( [ 'note_id', 'user_id' ] ) + ->where( 'type', '=', Note::USER_RELATION_READ ) + ->where_in( 'note_id', $ids ) + ->get(); + + $ids = $pivot->pluck( 'user_id' )->all(); + + // Exit if there are no readers. + if ( empty( $ids ) ) { + return $notes; + } + + // Get all users that are associated with the relations, and map them into `$user_id => User`. + $readers = User::query() + ->where_in( 'ID', $ids ) + ->get() + ->key_by( 'ID' ); + + // Attach a user to each pivot row & group by note id. + $pivot = $pivot->map( function ( $item ) use ( $readers ) { + $item['user'] = $readers->get( $item['user_id'], [] ); + + return $item; + } )->filter( function ( $item ) { + // Make sure that relations with non-existing users won't be returned. + return ! empty( $item['user'] ); + } )->group_by( 'note_id' ); + + // Add the readers to the note. + return $notes->map( function ( $note ) use ( $pivot ) { + $users = $pivot->get( $note['id'], [] ); + + $readers = ( new Collection( $users ) ) + ->unique( 'user_id' ) + ->pluck( 'user' ) + ->all(); + + $note['readers'] = $readers; + + return $note; + } ); + } ); + } + + /** + * Eager load the Note's author. + * + * @return $this + */ + public function with_author() { + return $this->add_with( 'author', function ( Collection $notes ) { + $ids = $notes + ->pluck( 'author_id' ) + ->unique() + ->values(); + + $authors = User::query() + ->where_in( 'ID', $ids ) + ->get() + ->key_by( 'ID' ); + + return $notes->map( function ( $note ) use ( $authors ) { + $note['author'] = $authors->get( $note['author_id'] ); + + return $note; + } ); + } ); + } + + /** + * Eager load the Note's document. + * + * @return $this + */ + public function with_document() { + return $this->add_with( 'document', function ( Collection $notes ) { + $ids = $notes + ->pluck( 'post_id' ) + ->unique() + ->values(); + + $documents = Document::query() + ->where_in( 'ID', $ids ) + ->get() + ->key_by( 'ID' ); + + return $notes->map( function ( $note ) use ( $documents ) { + $note['document'] = $documents->get( $note['post_id'] ); + + return $note; + } ); + } ); + } + + /** + * Eager load the Note's read state by a user ID. + * + * @param int $user_id - User ID to check. + * + * @return $this + */ + public function with_is_read( $user_id ) { + $alias = 'is_read'; + + if ( $this->is_column_selected( $alias ) ) { + return $this; + } + + // TODO: Maybe use JOIN. + return $this->add_sub_select( function ( Query_Builder $q ) use ( $user_id ) { + $q->from( Module::TABLE_NOTES_USERS_RELATIONS, 'users_relations' ) + ->select( [ 'users_relations.id' ], static::COLUMN_COUNT ) + ->where( 'type', '=', Note::USER_RELATION_READ ) + ->where_column( Module::TABLE_NOTES . '.id', '=', 'users_relations.note_id' ) + ->where( 'user_id', '=', $user_id ); + }, $alias ); + } + + /** + * Make sure that users without permissions to read private notes won't get them. + * + * @param integer $user_id - User ID to check. + * + * @return Note_Query_Builder + */ + public function only_visible( $user_id ) { + // User can read private notes - do nothing. + if ( user_can( $user_id, Capabilities::READ_OTHERS_PRIVATE_NOTES ) ) { + return $this; + } + + // User can read only public or their note. + return $this->where( function ( Query_Builder $q ) use ( $user_id ) { + $q->where( 'is_public', '=', true ) + ->or_where( 'author_id', '=', $user_id ); + } ); + } + + /** + * Filter only notes that their post is visible to the user. + * + * @param $user_id + * + * @return $this + */ + public function only_visible_posts( $user_id ) { + $post_types = ( new Collection( get_post_types() ) ) + ->map( function ( $post_type_value ) { + return get_post_type_object( $post_type_value ); + } ); + + $can_read_unpublished_post_types = $post_types + ->filter( function ( $post_type ) use ( $user_id ) { + return $post_type && user_can( $user_id, $post_type->cap->edit_posts ); + } ) + ->keys() + ->all(); + + $can_read_private_post_types = $post_types + ->filter( function ( $post_type ) use ( $user_id ) { + return $post_type && user_can( $user_id, $post_type->cap->read_private_posts ); + } ) + ->keys() + ->all(); + + foreach ( [ 'route_post_id', 'post_id' ] as $column ) { + $table_alias = "posts_{$column}_visible"; + + $this + ->left_join( + function ( Join_Clause $join ) use ( $table_alias, $column ) { + return $join->table( 'posts', $table_alias ) + ->on_column( "{$table_alias}.ID", '=', $column ); + } + ) + ->where( + function ( Query_Builder $query ) use ( $can_read_unpublished_post_types, $table_alias ) { + // If there is no post ID, there is nothing to check, + // OR if the post is published the user can view the post, + // OR if the user is allowed to view unpublished post (for the current `post_type`). + $query->where_null( "{$table_alias}.ID" ) + ->or_where( "{$table_alias}.post_status", '=', BaseDocument::STATUS_PUBLISH ) + ->or_where_in( "{$table_alias}.post_type", $can_read_unpublished_post_types ); + } + ) + ->where( + function ( Query_Builder $query ) use ( $user_id, $can_read_private_post_types, $table_alias ) { + // If there is no post ID, there is nothing to check, + // OR if the post is not private the user can see view post, + // OR if the current user is the author of the private post, so he can view the post, + // OR if the user is allowed to view private posts (for the current `post_type`). + $query->where_null( "{$table_alias}.ID" ) + ->or_where( "{$table_alias}.post_status", '!=', BaseDocument::STATUS_PRIVATE ) + ->or_where( "{$table_alias}.post_author", '=', $user_id ) + ->or_where_in( "{$table_alias}.post_type", $can_read_private_post_types ); + } + ); + } + + return $this; + } + + /** + * Filter only the notes that are relevant to the user. + * + * @param int $user_id - User ID to check. + * + * @return Note_Query_Builder + */ + public function only_relevant( $user_id ) { + // User replied to the thread. + $replied_to_thread = function ( Query_Builder $q ) use ( $user_id ) { + $q->select_raw( [ 1 ] ) + ->from( Module::TABLE_NOTES, 'e_notes_relevant_replies' ) + ->where_column( 'e_notes_relevant_replies.parent_id', '=', Module::TABLE_NOTES . '.id' ) + ->where( 'e_notes_relevant_replies.author_id', '=', $user_id ) + ->where( 'e_notes_relevant_replies.status', '!=', Note::STATUS_TRASH ); + }; + + // User is mentioned in the thread. + $mentioned_in_thread = function ( Query_Builder $q ) use ( $user_id ) { + $q->select_raw( [ 1 ] ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS, 'e_notes_relevant_relation' ) + ->where_column( 'e_notes_relevant_relation.note_id', '=', Module::TABLE_NOTES . '.id' ) + ->where( 'e_notes_relevant_relation.user_id', '=', $user_id ) + ->where( 'e_notes_relevant_relation.type', '=', Note::USER_RELATION_MENTION ); + }; + + // User is mentioned in one of the replies. + $mentioned_in_replies = function ( Query_Builder $q ) use ( $user_id ) { + $q->select_raw( [ 1 ] ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS, 'e_notes_relevant_relation_replies' ) + ->where_in( 'e_notes_relevant_relation_replies.note_id', function ( Query_Builder $q ) use ( $user_id ) { + $q->select( [ 'e_notes_relevant_replies_ids.id' ] ) + ->from( Module::TABLE_NOTES, 'e_notes_relevant_replies_ids' ) + ->where_column( 'e_notes_relevant_replies_ids.parent_id', '=', Module::TABLE_NOTES . '.id' ) + ->where( 'e_notes_relevant_replies_ids.status', '!=', Note::STATUS_TRASH ); + } ) + ->where( 'e_notes_relevant_relation_replies.user_id', '=', $user_id ) + ->where( 'e_notes_relevant_relation_replies.type', '=', Note::USER_RELATION_MENTION ); + }; + + return $this->where( function ( Query_Builder $q ) use ( $user_id, $replied_to_thread, $mentioned_in_thread, $mentioned_in_replies ) { + $q->where( 'author_id', '=', $user_id ) // User created the thread. + ->or_where_exists( $replied_to_thread ) + ->or_where_exists( $mentioned_in_thread ) + ->or_where_exists( $mentioned_in_replies ); + } ); + } + + /** + * Filter only unread notes. + * + * @param integer $user_id - User id that the notes are unread by. + * + * @return Note_Query_Builder + */ + public function only_unread( $user_id ) { + return $this + ->with_unread_replies_count( $user_id ) + ->with_is_read( $user_id ) + ->having_raw( '`unread_replies_count` > 0 OR `is_read` = 0' ); + } + + /** + * Filter only threads. + * + * @return Note_Query_Builder + */ + public function only_threads() { + return $this->where( 'parent_id', '=', 0 ); + } + + /** + * Filter only replies. + * + * @return Note_Query_Builder + */ + public function only_replies() { + return $this->where( 'parent_id', '!=', 0 ); + } + + /** + * Filter only trashed notes. + * + * @return Note_Query_Builder + */ + public function only_trashed() { + return $this->with_trashed() + ->where( 'status', '=', Note::STATUS_TRASH ); + } + + /** + * Eager load the Note's unread replies count by a user ID. + * + * @param int $user_id - User ID to check. + * + * @return Note_Query_Builder + */ + public function with_unread_replies_count( $user_id ) { + $alias = 'unread_replies_count'; + + if ( $this->is_column_selected( $alias ) ) { + return $this; + } + + return $this->add_sub_select( function ( Query_Builder $q ) use ( $user_id ) { + $q->select( [ 'e_replies_count.id' ], static::COLUMN_COUNT ) + ->from( Module::TABLE_NOTES, 'e_replies_count' ) + ->left_join( function ( Join_Clause $j ) use ( $user_id ) { + $j->table( + Module::TABLE_NOTES_USERS_RELATIONS, + 'e_replies_count_user_relations' + ) + ->on_column( + 'e_replies_count_user_relations.note_id', + '=', + 'e_replies_count.id' + ) + ->on( + 'e_replies_count_user_relations.type', + '=', + Note::USER_RELATION_READ + ) + ->on( + 'e_replies_count_user_relations.user_id', + '=', + $user_id + ); + } ) + ->where_column( 'e_replies_count.parent_id', '=', Module::TABLE_NOTES . '.id' ) + ->where_null( 'e_replies_count_user_relations.id' ); + }, $alias ); + } + + /** + * Extends base delete method to allow deleting all the related entities + * of the notes, including 'user relations' and 'replies'. + * + * @param false $include_related_entities + * + * @return bool|int + */ + public function delete( $include_related_entities = false ) { + if ( ! $include_related_entities ) { + return parent::delete(); + } + + // Get all the ids of the notes it wishes to delete. + $notes_ids = $this->select( [ 'id' ] ) + ->with_trashed() + ->get() + ->pluck( 'id' ); + + if ( $notes_ids->is_empty() ) { + return 0; + } + + // Get all the replies ids. + $replies_ids = Note::query() + ->with_trashed() + ->select( [ 'id' ] ) + ->where_in( 'parent_id', $notes_ids->values() ) + ->get() + ->pluck( 'id' ); + + // Merge the thread ids with the replies. + $all_relevant_notes_ids = $notes_ids->merge( $replies_ids ); + + // Delete all the users relations of the notes. + ( new Query_Builder() ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS ) + ->where_in( 'note_id', $all_relevant_notes_ids->values() ) + ->delete(); + + // Delete all the notes. + return Note::query() + ->with_trashed() + ->where_in( 'id', $all_relevant_notes_ids->values() ) + ->delete(); + } + + /** + * Move notes to trash. + * + * @return bool|int + */ + public function trash() { + $now = gmdate( 'Y-m-d H:i:s' ); + + return $this->update( [ + 'status' => Note::STATUS_TRASH, + 'updated_at' => $now, + ] ); + } + + /** + * Restore notes from trash. + * + * @return bool|int + */ + public function restore() { + $now = gmdate( 'Y-m-d H:i:s' ); + + return $this + ->with_trashed() + ->where( 'status', '=', Note::STATUS_TRASH ) + ->update( [ + 'status' => Note::STATUS_PUBLISH, // TODO: It should be the last status + 'updated_at' => $now, + ] ); + } +} diff --git a/modules/notes/database/query/user-query-builder.php b/modules/notes/database/query/user-query-builder.php new file mode 100644 index 00000000..297ad982 --- /dev/null +++ b/modules/notes/database/query/user-query-builder.php @@ -0,0 +1,61 @@ +select( [ 'id', 'author_id' ] ) + ->where( 'id', '=', $note->id ) + ->when( $note->is_thread(), function ( Note_Query_Builder $q ) use ( $note ) { + $q->or_where( 'parent_id', '=', $note->id ); + } ) + ->when( $note->is_reply(), function ( Note_Query_Builder $q ) use ( $note ) { + $q->or_where( 'parent_id', '=', $note->parent_id ) + ->or_where( 'id', '=', $note->parent_id ); + } ) + ->get(); + + return $this->where_exists( function ( Query_Builder $q ) use ( $notes ) { + // User is mentioned in thread or in one of the replies. + $q->select_raw( [ 1 ] ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS, 'relations' ) + ->where_in( 'relations.note_id', $notes->pluck( 'id' )->all() ) + ->where_column( 'relations.user_id', '=', 'users.id' ) + ->where( 'relations.type', '=', Note::USER_RELATION_MENTION ); + } ) + // User created the thread or one of the replies. + ->or_where_in( 'users.id', $notes->pluck( 'author_id' )->all() ); + } +} diff --git a/modules/notes/database/transformers/user-transformer.php b/modules/notes/database/transformers/user-transformer.php new file mode 100644 index 00000000..0e140abd --- /dev/null +++ b/modules/notes/database/transformers/user-transformer.php @@ -0,0 +1,61 @@ +add_capabilities( $this->map_properties( $user ), $dependencies ); + } + + /** + * Maps the user properties to new keys. + * + * @param User $user + * + * @return array + */ + protected function map_properties( User $user ) { + // TODO: This response might be visible to unauthorized users. + // DON'T INCLUDE ANY SENSITIVE DATA. + return [ + 'id' => $user->ID, + 'name' => $user->display_name, + 'url' => $user->user_url, + 'slug' => $user->user_nicename, + 'avatar_urls' => $user->get_avatars()->all(), + ]; + } + + /** + * Add user capabilities to the user object. + * + * @param array $user + * @param array $dependencies + * + * @return array + */ + protected function add_capabilities( array $user, $dependencies ) { + $user['capabilities']['notes']['can_read'] = Capabilities::can_read_notes( $user['id'] ); + + if ( ! empty( $dependencies['post_id'] ) ) { + $user['capabilities']['post']['can_edit'] = Capabilities::can_edit_post( $user['id'], $dependencies['post_id'] ); + } + + return $user; + } +} diff --git a/modules/notes/document-events.php b/modules/notes/document-events.php new file mode 100644 index 00000000..cd95ff62 --- /dev/null +++ b/modules/notes/document-events.php @@ -0,0 +1,122 @@ +clear_after_post_meta_update( $post_id, $meta_key ); + }, 10, 3 ); + + add_action( 'deleted_post_meta', function ( $_, $post_id, $meta_key ) { + $this->clear_after_post_meta_update( $post_id, $meta_key ); + }, 10, 3 ); + + add_action( 'deleted_post', function ( $post_id ) { + $this->clear_after_post_deleted( $post_id ); + } ); + + add_action( 'trashed_post', function ( $post_id ) { + $this->move_to_trash_after_post_trashed( $post_id ); + } ); + + add_action( 'untrashed_post', function ( $post_id ) { + $this->restore_from_trash_after_post_untrashed( $post_id ); + } ); + } + + /** + * Remove all the notes that their elements is not exist in the document anymore. + * + * @param $post_id + * @param $meta_key + */ + private function clear_after_post_meta_update( $post_id, $meta_key ) { + if ( '_elementor_data' !== $meta_key ) { + return; + } + + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( ! $document || $document->is_revision() ) { + return; + } + + $elements_ids = $this->get_elements_ids( + $document->get_elements_data() + ); + + Note::query() + ->where( 'post_id', '=', $document->get_id() ) + ->where_not_in( 'element_id', $elements_ids ) + ->delete( true ); + } + + /** + * Remove all the notes that related to the post that was deleted. + * + * @param $post_id + */ + private function clear_after_post_deleted( $post_id ) { + Note::query() + ->where( 'post_id', '=', $post_id ) + ->delete( true ); + } + + /** + * Move notes to trash when their post trashed. + * + * @param $post_id + */ + private function move_to_trash_after_post_trashed( $post_id ) { + Note::query() + ->where( 'post_id', '=', $post_id ) + ->trash(); + } + + /** + * Restore notes when their post untrashed. + * + * @param $post_id + */ + private function restore_from_trash_after_post_untrashed( $post_id ) { + Note::query() + ->where( 'post_id', '=', $post_id ) + ->restore(); + } + + /** + * Get recursively all the ids of the elements. + * + * @param $elements + * + * @return array + */ + private function get_elements_ids( $elements ) { + if ( empty( $elements ) ) { + return []; + } + + return array_reduce( $elements, function ( $ids, $element ) { + if ( empty( $element['id'] ) ) { + return $ids; + } + + return array_merge( + $ids, + [ $element['id'] ], + empty( $element['elements'] ) ? [] : $this->get_elements_ids( $element['elements'] ) + ); + }, [] ); + } +} diff --git a/modules/notes/module.php b/modules/notes/module.php new file mode 100644 index 00000000..f16b22e7 --- /dev/null +++ b/modules/notes/module.php @@ -0,0 +1,234 @@ +get_css_assets_url( 'modules/notes' ), + [ 'elementor-icons' ], + ELEMENTOR_PRO_VERSION + ); + } + + /** + * Enqueue panel scripts. + */ + private function enqueue_main_scripts() { + wp_enqueue_script( + 'elementor-pro-notes', + $this->get_js_assets_url( 'notes/notes' ), + [ + // Change `$e` dependency based on the `Web-CLI` module. + Plugin::elementor()->modules_manager->get_modules( 'web-cli' ) + ? 'elementor-web-cli' + : 'elementor-common', + 'react', + 'react-dom', + ], + ELEMENTOR_PRO_VERSION, + true + ); + + wp_set_script_translations( 'elementor-pro-notes', 'elementor-pro' ); + } + + /** + * Enqueue marks scripts. + * + * @param bool $is_preview + */ + private function enqueue_app_initiator( $is_preview = false ) { + $dependencies = [ + 'react', + 'react-dom', + ]; + + if ( ! $is_preview ) { + // When loading in frontend, the app should be loaded after notes main script. + // There are some listeners that should be initialized before the app script loaded. + $dependencies[] = 'elementor-pro-notes'; + } + + wp_enqueue_script( + 'elementor-pro-notes-app-initiator', + $this->get_js_assets_url( 'notes/notes-app-initiator' ), + $dependencies, + ELEMENTOR_PRO_VERSION, + true + ); + + $this->print_config( 'elementor-pro-notes-app-initiator' ); + } + + /** + * Expose settings to the frontend under 'window.elementorNotesConfig'. + * + * @return void + */ + protected function add_config() { + $queried_object = get_queried_object(); + + $route = [ + 'title' => Utils::get_clean_document_title(), + // PHPCS - The url cleaned inside the clear_url method. + 'url' => Utils::clean_url( $_SERVER['REQUEST_URI'] ?? '' ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + 'note_url_pattern' => Note::generate_url(), + 'post_id' => null, + 'is_elementor_library' => false, + ]; + + if ( $queried_object instanceof \WP_Post ) { + $route['url'] = Utils::clean_url( home_url( "?p={$queried_object->ID}" ) ); + $route['post_id'] = $queried_object->ID; + $route['is_elementor_library'] = Source_Local::CPT === $queried_object->post_type; + } + + $this->set_settings( 'route', $route ); + $this->set_settings( 'direction', is_rtl() ? 'rtl' : 'ltr' ); + $this->set_settings( 'is_debug', ( defined( 'ELEMENTOR_DEBUG' ) && ELEMENTOR_DEBUG ) ); + + $this->set_settings( 'current_user_can', [ + 'create' => current_user_can( Capabilities::CREATE_NOTES ), + 'create_users' => current_user_can( 'create_users' ), + 'edit_users' => current_user_can( 'edit_users' ), + ] ); + + $this->set_settings( 'urls', [ + 'admin_url_create_user' => get_admin_url( null, 'user-new.php' ), + 'admin_url_edit_user' => get_admin_url( null, 'user-edit.php' ), + 'avatar_defaults' => User::generate_avatars_urls( 0 ), + 'help_notes_features' => 'https://go.elementor.com/app-notes', + ] ); + } + + /** + * Define the module tables in `wpdb`. + * + * @return void + */ + private function define_tables() { + global $wpdb; + + $tables = [ + self::TABLE_NOTES, + self::TABLE_NOTES_USERS_RELATIONS, + ]; + + foreach ( $tables as $table ) { + $wpdb->$table = $wpdb->prefix . $table; + $wpdb->tables[] = $table; + } + } + + private function on_elementor_pro_init() { + $has_license = API::is_license_active() && API::is_licence_has_feature( static::LICENSE_FEATURE_NAME ); + + if ( ! $has_license ) { + return; + } + + // Things that should be happened if the feature is active (not depends on the current user) + $this->define_tables(); + + add_action( 'switch_blog', function () { + // Reinitialize the Notes tables when switching between sites on a multisite, since each site has its own tables prefix. + $this->define_tables(); + } ); + + ( new Capabilities() )->register(); + ( new Preferences() )->register(); + ( new Delete_User() )->register(); + ( new Personal_Data() )->register(); + ( new Notes_Database_Updater() )->register(); + ( new Admin_Bar() )->register(); + ( new Admin_Page() )->register(); + ( new Document_Events() )->register(); + ( new Usage() )->register(); + + Plugin::elementor()->data_manager_v2->register_controller( new Controller() ); + + // Things that should be happened if the current user can read notes. + if ( is_user_logged_in() && current_user_can( Capabilities::READ_NOTES ) ) { + add_action( 'template_redirect', function () { + // Only now the 'queried_object' is available for the config. + $this->add_config(); + } ); + + add_action( 'elementor/frontend/before_enqueue_styles', [ $this, 'enqueue_styles' ] ); + + add_action( 'elementor/frontend/after_register_scripts', function () { + $is_preview = Plugin::elementor()->preview->is_preview(); + + if ( ! $is_preview ) { + $this->enqueue_main_scripts(); + } + + $this->enqueue_app_initiator( $is_preview ); + } ); + + add_action( 'elementor/editor/before_enqueue_scripts', function () { + $this->enqueue_main_scripts(); + } ); + + add_filter( 'elementor-pro/editor/v2/packages', function ( $packages ) { + $packages[] = 'editor-notes'; + + return $packages; + } ); + } + } + + public function __construct() { + parent::__construct(); + + add_action( 'elementor_pro/init', function() { + $this->on_elementor_pro_init(); + } ); + } +} diff --git a/modules/notes/notifications/base-notes-notification.php b/modules/notes/notifications/base-notes-notification.php new file mode 100644 index 00000000..c748e7ed --- /dev/null +++ b/modules/notes/notifications/base-notes-notification.php @@ -0,0 +1,94 @@ +note = $note; + $this->exclude = $exclude; + $this->actor = $actor; + } + + /** + * Get the notification payloads. + * + * @param User $notifiable + * + * @return array + */ + public function get_payloads( $notifiable ) { + $exclude = $this->exclude; + $exclude[] = $this->actor->ID; + + if ( in_array( $notifiable->ID, $exclude, true ) ) { + return []; + } + + if ( ! user_can( $notifiable->ID, Capabilities::READ_NOTES, $this->note ) ) { + return []; + } + + if ( ! Preferences::are_notifications_enabled( $notifiable->ID ) ) { + return []; + } + + return [ + $this->create_email_message( $notifiable ), + ]; + } + + /** + * Get the sender email & name. + * + * @return string[] + */ + protected function get_sender() { + return [ + get_bloginfo( 'admin_email' ), + $this->actor->display_name . ' (' . esc_html__( 'via PRO Elements', 'elementor-pro' ) . ')', + ]; + } + + /** + * Initialize an `Email_Message` for the current notification. + * + * @param $notifiable + * + * @return \ElementorPro\Core\Integrations\Actions\Email\Email_Message + */ + abstract protected function create_email_message( $notifiable ); +} diff --git a/modules/notes/notifications/user-mentioned-notification.php b/modules/notes/notifications/user-mentioned-notification.php new file mode 100644 index 00000000..bb7ebd9f --- /dev/null +++ b/modules/notes/notifications/user-mentioned-notification.php @@ -0,0 +1,35 @@ +note->get_thread_id(), + get_bloginfo( 'name' ), + $this->note->route_title + ); + + return ( new Email_Message() ) + ->from( ...$this->get_sender() ) + ->to( $notifiable->user_email, $notifiable->display_name ) + ->subject( $subject ) + ->view( __DIR__ . '/views/email.php', [ + 'actor' => $this->actor->display_name, + /* translators: 1: User display name, 2: Page name, 3: Site name. */ + 'heading' => __( '%1$s mentioned you on %2$s at %3$s', 'elementor-pro' ), + 'page' => $this->note->route_title, + 'site_name' => get_bloginfo( 'name' ), + 'note_content' => $this->note->content, + 'note_url' => $this->note->get_url(), + ] ); + } +} diff --git a/modules/notes/notifications/user-replied-notification.php b/modules/notes/notifications/user-replied-notification.php new file mode 100644 index 00000000..93c48c48 --- /dev/null +++ b/modules/notes/notifications/user-replied-notification.php @@ -0,0 +1,35 @@ +note->get_thread_id(), + get_bloginfo( 'name' ), + $this->note->route_title + ); + + return ( new Email_Message() ) + ->from( ...$this->get_sender() ) + ->to( $notifiable->user_email, $notifiable->display_name ) + ->subject( $subject ) + ->view( __DIR__ . '/views/email.php', [ + 'actor' => $this->actor->display_name, + /* translators: 1: User display name, 2: Page name, 3: Site name. */ + 'heading' => __( '%1$s replied to a note on %2$s at %3$s', 'elementor-pro' ), + 'page' => $this->note->route_title, + 'site_name' => get_bloginfo( 'name' ), + 'note_content' => $this->note->content, + 'note_url' => $this->note->get_url(), + ] ); + } +} diff --git a/modules/notes/notifications/user-resolved-notification.php b/modules/notes/notifications/user-resolved-notification.php new file mode 100644 index 00000000..3139b873 --- /dev/null +++ b/modules/notes/notifications/user-resolved-notification.php @@ -0,0 +1,35 @@ +note->get_thread_id(), + get_bloginfo( 'name' ), + $this->note->route_title + ); + + return ( new Email_Message() ) + ->from( ...$this->get_sender() ) + ->to( $notifiable->user_email, $notifiable->display_name ) + ->subject( $subject ) + ->view( __DIR__ . '/views/email.php', [ + 'actor' => $this->actor->display_name, + /* translators: 1: User display name, 2: Page name, 3: Site name. */ + 'heading' => __( '%1$s resolved a note on %2$s at %3$s', 'elementor-pro' ), + 'page' => $this->note->route_title, + 'site_name' => get_bloginfo( 'name' ), + 'note_content' => $this->note->content, + 'note_url' => $this->note->get_url(), + ] ); + } +} diff --git a/modules/notes/notifications/views/email.php b/modules/notes/notifications/views/email.php new file mode 100644 index 00000000..082f8ee2 --- /dev/null +++ b/modules/notes/notifications/views/email.php @@ -0,0 +1,90 @@ + + +
      +
      +

      + %s
      ', + esc_html( $actor ) + ), + sprintf( + '"%s"
      ', + esc_html( $page ) + ), + esc_html( $site_name ) + ); + + // The above resolves to "UserName mentioned you on "*PageName*" at SiteName" + ?> +

      + +

      + "" +

      + + + + +
      + +
      +

      + + +
      + + ', esc_url( admin_url( 'profile.php' ) ) ), + '' + ); + ?> +

      +
      +
      diff --git a/modules/notes/usage.php b/modules/notes/usage.php new file mode 100644 index 00000000..0d790ce6 --- /dev/null +++ b/modules/notes/usage.php @@ -0,0 +1,317 @@ +get_usage_data(); + + return $params; + } ); + } + + /** + * Get the Notes feature usage data. + * + * @return array + */ + private function get_usage_data() { + return [ + 'threads' => $this->get_threads_usage(), + 'replies' => $this->get_replies_usage(), + 'mentions' => $this->get_mentions_usage(), + 'first_interaction' => $this->get_first_interaction(), + 'last_interaction' => $this->get_last_interaction(), + ]; + } + + /** + * Get the Threads' usage data. + * + * @return array + */ + private function get_threads_usage() { + return [ + 'total' => Note::query() + ->only_threads() + ->count(), + + 'resolved' => Note::query() + ->only_threads() + ->where( 'is_resolved', '=', true ) + ->count(), + + 'trashed' => Note::query() + ->only_threads() + ->only_trashed() + ->count(), + + 'users_used' => $this->get_notes_users_used( static::THREADS ), + + 'document_type' => $this->get_notes_document_types( static::THREADS ), + ]; + } + + /** + * Get the replies' usage data. + * + * @return array + */ + private function get_replies_usage() { + return [ + 'total' => Note::query() + ->only_replies() + ->count(), + + 'trashed' => Note::query() + ->only_replies() + ->only_trashed() + ->count(), + + 'replied_threads' => (int) Note::query() + ->disable_model_initiation() + ->only_replies() + ->select_raw( [ 'COUNT(DISTINCT `parent_id`) AS `count`' ] ) + ->first()['count'], + + 'users_used' => $this->get_notes_users_used( static::REPLIES ), + + 'document_type' => $this->get_notes_document_types( static::REPLIES ), + ]; + } + + /** + * Get the mentions' usage data. + * + * @return array + */ + private function get_mentions_usage() { + return [ + 'total' => ( new Query_Builder() ) + ->table( Module::TABLE_NOTES_USERS_RELATIONS, 'e_notes_relations' ) + ->join( function ( Join_Clause $j ) { + $j->table( Module::TABLE_NOTES, 'e_notes' ) + ->on_column( 'e_notes.id', '=', 'e_notes_relations.note_id' ); + } ) + ->where( 'type', '=', Note::USER_RELATION_MENTION ) + ->where( 'e_notes.status', '!=', Note::STATUS_TRASH ) + ->count(), + + 'users_used' => $this->get_mentions_users_used(), + + 'document_type' => ( new Query_Builder() ) + ->select( [ 'type' => 'postmeta.meta_value' ] ) + ->add_count_select( '*', 'count' ) + ->from( Module::TABLE_NOTES_USERS_RELATIONS, 'e_notes_relations' ) + ->join( function ( Join_Clause $j ) { + $j->table( Module::TABLE_NOTES, 'e_notes' ) + ->on_column( 'e_notes.id', '=', 'e_notes_relations.note_id' ); + } ) + ->join( function ( Join_Clause $j ) { + $j->table( 'posts' ) + ->on_column( 'posts.ID', '=', 'e_notes.post_id' ); + } ) + ->join( function ( Join_Clause $j ) { + $j->table( 'postmeta' ) + ->on_column( 'posts.ID', '=', 'postmeta.post_id' ) + ->on( 'postmeta.meta_key', '=', Document::TYPE_META_KEY ); + } ) + ->where( 'e_notes.status', '!=', Note::STATUS_TRASH ) + ->group_by( 'postmeta.meta_value' ) + ->get() + ->map_with_keys( function ( $row ) { + return [ $row['type'] => (int) $row['count'] ]; + } ) + ->all(), + ]; + } + + /** + * Get the first user interaction with the Notes feature. + * + * @return string|null + */ + private function get_first_interaction() { + $note = Note::query() + ->with_trashed() + ->select( [ 'created_at' ] ) + ->order_by( 'created_at' ) + ->first(); + + return $note && $note->created_at + ? $note->created_at->format( 'Y-m-d\TH:i:sO' ) + : null; + } + + /** + * Get the last user interaction with the Notes feature. + * + * @return string|null + */ + private function get_last_interaction() { + $note = Note::query() + ->with_trashed() + ->select( [ 'last_activity_at' ] ) + ->order_by( 'last_activity_at', 'desc' ) + ->first(); + + return $note && $note->last_activity_at + ? $note->last_activity_at->format( 'Y-m-d\TH:i:sO' ) + : null; + } + + /** + * Get the count of `$type` usages grouped by user role. + * + * e.g. for 10 replies it can be something like: `{ admin: 7, subscriber: 3 }` + * + * @param string $type - Threads or replies. + * + * @return array + */ + private function get_notes_users_used( $type ) { + $query = Note::query() + ->disable_model_initiation() + ->select( [ 'user_used_id' => Module::TABLE_NOTES . '.author_id' ] ) + ->add_count_select( Module::TABLE_NOTES . '.id', 'count' ) + ->group_by( 'user_used_id' ); + + switch ( $type ) { + case static::THREADS: + $query->only_threads(); + break; + + case static::REPLIES: + $query->only_replies(); + break; + } + + return $this->normalize_users_used( $query->get() ); + } + + /** + * Get the count of mentions usages grouped by user role. + * + * e.g. for 10 mentions it can be something like: `{ admin: 7, subscriber: 3 }` + * + * @return array + */ + private function get_mentions_users_used() { + $query = ( new Query_Builder() ) + ->from( Module::TABLE_NOTES_USERS_RELATIONS, 'e_notes_relations' ) + ->select( [ 'user_used_id' => 'e_notes.author_id' ] ) + ->add_count_select( 'e_notes_relations.id', 'count' ) + ->join( function ( Join_Clause $j ) { + $j->table( Module::TABLE_NOTES, 'e_notes' ) + ->on_column( 'e_notes_relations.note_id', '=', 'e_notes.id' ); + } ) + ->where( 'e_notes_relations.type', '=', Note::USER_RELATION_MENTION ) + ->where( 'e_notes.status', '!=', Note::STATUS_TRASH ) + ->group_by( 'e_notes.author_id' ); + + return $this->normalize_users_used( $query->get() ); + } + + /** + * Normalize `users_used` query results into counts array grouped by user role. + * + * @param Collection $query_results + * + * @return array + */ + private function normalize_users_used( Collection $query_results ) { + if ( $query_results->is_empty() ) { + return []; + } + + $results = $query_results->map_with_keys( function ( $row ) { + return [ $row['user_used_id'] => (int) $row['count'] ]; + } ); + + /** + * @type \WP_User[] $users + */ + $users = get_users( [ + 'include' => $results->keys()->all(), + ] ); + + $counts = []; + + foreach ( $users as $user ) { + /** + * WordPress also uses the first role. + * + * @see https://github.com/WordPress/WordPress/blob/57039311720709d55e96e1a074414ebadba64e00/wp-admin/user-edit.php#L419-L435 + */ + $role = reset( $user->roles ); + + if ( ! isset( $counts[ $role ] ) ) { + $counts[ $role ] = 0; + } + + $counts[ $role ] += $results->get( $user->ID ); + } + + return $counts; + } + + /** + * Get the count of `$type` usages grouped by document type. + * + * @param string $type - Threads or replies. + * + * @return array + */ + private function get_notes_document_types( $type ) { + $query = Note::query() + ->disable_model_initiation() + ->select( [ 'type' => 'postmeta.meta_value' ] ) + ->add_count_select( '*', 'count' ) + ->join( function ( Join_Clause $j ) { + $j->table( 'posts' ) + ->on_column( 'posts.ID', '=', Module::TABLE_NOTES . '.post_id' ); + } ) + ->join( function ( Join_Clause $j ) { + $j->table( 'postmeta' ) + ->on_column( 'posts.ID', '=', 'postmeta.post_id' ) + ->on( 'postmeta.meta_key', '=', Document::TYPE_META_KEY ); + } ) + ->group_by( 'postmeta.meta_value' ); + + switch ( $type ) { + case static::THREADS: + $query->only_threads(); + break; + + case static::REPLIES: + $query->only_replies(); + break; + } + + return $query->get() + ->map_with_keys( function ( $row ) { + return [ $row['type'] => (int) $row['count'] ]; + } ) + ->all(); + } +} diff --git a/modules/notes/user/capabilities.php b/modules/notes/user/capabilities.php new file mode 100644 index 00000000..197fe887 --- /dev/null +++ b/modules/notes/user/capabilities.php @@ -0,0 +1,282 @@ +filter( function ( $cap ) use ( $user ) { + return ! user_can( $user, $cap ); + } ) + ->is_empty(); + } + + /** + * Register actions and hooks + */ + public function register() { + add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) { + return $this->map_meta_cap( $caps, $cap, $user_id, $args ); + }, 10, 4 ); + + add_action( 'edit_user_profile', function ( \WP_User $user ) { + $this->render_edit_user_profile_options( $user ); + } ); + + add_action( 'edit_user_profile_update', function ( $user_id ) { + $this->update_user_capabilities( $user_id ); + } ); + } + + /** + * Add or remove notes capabilities based on the permission checkbox. + * + * @param $user_id + */ + public function update_user_capabilities( $user_id ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce is verified in `wp_verify_nonce` + $wpnonce = Utils::_unstable_get_super_global_value( $_POST, '_wpnonce' ); + $verified_nonce = wp_verify_nonce( $wpnonce, 'update-user_' . $user_id ); + + if ( ! $verified_nonce ) { + return; + } + + $user = get_user_by( 'id', $user_id ); + + if ( ! $this->can_edit_capabilities_of( $user ) ) { + return; + } + + $should_add_cap = ! empty( $_POST[ static::ENABLE_PERMISSIONS_OPTION ] ); + + foreach ( static::basic() as $cap ) { + if ( $should_add_cap ) { + $user->add_cap( $cap ); + } else { + $user->remove_cap( $cap ); + } + } + } + + /** + * Render the permission checkbox in the user edit page. + * + * @param \WP_User $user + */ + public function render_edit_user_profile_options( \WP_User $user ) { + if ( ! $this->can_edit_capabilities_of( $user ) ) { + return; + } + + $option_name = static::ENABLE_PERMISSIONS_OPTION; + + ?> +
      +

      + + + + + + + modules_manager->get_modules( 'web-cli' ) && // Check if the web-cli is exists (BC support) + $user && + ! in_array( 'administrator', $user->roles, true ); // Admin permissions cannot be changed. + } + + /** + * Handle the capabilities of the notes + * + * @param string[] $caps + * @param string $cap + * @param int $user_id + * @param array $args + * + * @return array + */ + private function map_meta_cap( array $caps, $cap, $user_id, array $args ) { + if ( + ! in_array( $cap, static::all(), true ) || // Handle only elementor notes capabilities. + empty( $args[0] ) // Checking for capability without provide a specific note id. + ) { + return $caps; + } + + $note = $args[0] instanceof Note + ? $args[0] + : Note::query()->find( $args[0] ); + + // When note not found don't let the user do nothing. + if ( ! $note ) { + $caps[] = 'do_not_allow'; + + return $caps; + } + + // When the user doesn't have read access to one of the post_ids (post_id, route_post_id), + // any other permission is not allowed. + $can_read_related_posts = ( new Collection( [ $note->route_post_id, $note->post_id ] ) ) + ->unique() + ->filter( function ( $post_id ) use ( $user_id ) { + if ( ! $post_id ) { + return false; + } + + $post_type = get_post_type_object( + get_post_type( $post_id ) + ); + + return ! $post_type || ! user_can( $user_id, $post_type->cap->read_post, $post_id ); + } ) + ->is_empty(); + + if ( ! $can_read_related_posts ) { + $caps[] = 'do_not_allow'; + + return $caps; + } + + // If the current user is the author of the notes there are + // no extra caps to add. + if ( $note->author_id === $user_id ) { + return $caps; + } + + // If the note is private and the current user is not the author of the note + // It adds "read others private notes" capability. + // Note: when $args[0] is provided on "create note" it refers to the "parent_id" and not + // to the actual new note. + if ( + ! $note->is_public + && in_array( $cap, [ static::READ_NOTES, static::CREATE_NOTES ], true ) + ) { + $caps[] = static::READ_OTHERS_PRIVATE_NOTES; + } + + // When trying to edit a note, and the current user is not the author of the note. + if ( static::EDIT_NOTES === $cap ) { + $caps[] = static::EDIT_OTHERS_NOTES; + } + + // When trying to delete a note, and the current user is not the author of the note. + if ( static::DELETE_NOTES === $cap ) { + $caps[] = static::DELETE_OTHERS_NOTES; + } + + return $caps; + } + + /** + * Check whether a user has access to Notes. + * + * @param int $user_id + * + * @return bool + */ + public static function can_read_notes( $user_id ) { + return user_can( $user_id, static::READ_NOTES ); + } + + /** + * Check whether a user has edit access to specific post. + * + * @param int $user_id + * @param int $post_id + * + * @return bool + */ + public static function can_edit_post( $user_id, $post_id ) { + if ( empty( $user_id ) || empty( $post_id ) ) { + return false; + } + + return user_can( $user_id, static::EDIT_POST, $post_id ); + } +} diff --git a/modules/notes/user/delete-user.php b/modules/notes/user/delete-user.php new file mode 100644 index 00000000..054554a9 --- /dev/null +++ b/modules/notes/user/delete-user.php @@ -0,0 +1,76 @@ +on_user_delete_form( $users_to_delete ); + }, 10, 2 ); + + add_action( 'delete_user', function ( $id, $reassign, $user ) { + $this->on_delete_user( $user ); + }, 10, 3 ); + } + + /** + * Update `author_display_name` on the note before deleting the author, in order + * to allow showing the author display name in the UI even when the user has been deleted. + * + * @param \WP_User $user + */ + private function on_delete_user( \WP_User $user ) { + Note::query() + ->with_trashed() + ->where( 'author_id', '=', $user->ID ) + ->update( [ 'author_display_name' => $user->display_name ] ); + } + + /** + * Add a note on user deletion form. + * + * @param $users_to_delete + */ + private function on_user_delete_form( $users_to_delete ) { + $notes_count = Note::query() + ->where_in( 'author_id', $users_to_delete ) + ->count(); + + if ( 0 === $notes_count ) { + return; + } + + ?> +

      + +

      +

      + +

      +

      + +

      + add_exporter( $exporters ); + } ); + } + + /** + * Get the data key for the exporter. + * + * @return string + */ + public function get_key() { + return static::WP_KEY; + } + + /** + * Get the exporter friendly name. + * + * @return string + */ + public function get_title() { + return esc_html__( 'Elementor Notes', 'elementor-pro' ); + } + + /** + * Add the Notes' exporter to the list of exporters. + * + * @param array $exporters + * + * @return array + */ + private function add_exporter( array $exporters ) { + $exporters[ $this->get_key() ] = [ + 'exporter_friendly_name' => $this->get_title(), + 'callback' => function ( $email ) { + return $this->export_data( $email ); + }, + ]; + + return $exporters; + } + + /** + * Export all the notes related to specific email. + * + * @param string $email + * + * @return array + */ + private function export_data( $email ) { + $user_id = User::query() + ->where( 'user_email', '=', $email ) + ->pluck( 'ID' ) + ->first(); + + if ( ! $user_id ) { + return [ + 'data' => [], + 'done' => true, + ]; + } + + $data = Note::query() + ->with_trashed() + ->where( 'author_id', '=', $user_id ) + ->get() + ->map( function ( Note $note ) { + return [ + 'group_id' => $this->get_key(), + 'group_label' => $this->get_title(), + 'item_id' => "{$this->get_key()}-{$note->id}", + 'data' => [ + [ + 'name' => esc_html__( 'ID', 'elementor-pro' ), + 'value' => $note->id, + ], + [ + 'name' => esc_html__( 'Parent ID', 'elementor-pro' ), + 'value' => $note->parent_id, + ], + [ + 'name' => esc_html__( 'Status', 'elementor-pro' ), + 'value' => $note->status, + ], + [ + 'name' => esc_html__( 'Content', 'elementor-pro' ), + 'value' => $note->content, + ], + [ + 'name' => esc_html__( 'Created At', 'elementor-pro' ), + 'value' => $note->created_at->format( 'Y-m-d H:i:s' ), + ], + ], + ]; + } ) + ->all(); + + return [ + 'data' => $data, + 'done' => true, + ]; + } +} diff --git a/modules/notes/user/preferences.php b/modules/notes/user/preferences.php new file mode 100644 index 00000000..171e1c35 --- /dev/null +++ b/modules/notes/user/preferences.php @@ -0,0 +1,113 @@ +add_personal_options_settings( $user ); + } ); + + add_action( 'personal_options_update', function ( $user_id ) { + $this->update_personal_options_settings( $user_id ); + } ); + } + + /** + * Determine if notifications are enabled for a user. + * + * @param int $user_id - User ID. + * + * @return bool + */ + public static function are_notifications_enabled( $user_id ) { + return ! ! Utils::get_user_option_with_default( static::ENABLE_NOTIFICATIONS, $user_id, true ); + } + + /** + * Add settings to the "Personal Options". + * + * @param \WP_User $user - User object. + * + * @return void + */ + protected function add_personal_options_settings( \WP_User $user ) { + if ( ! $this->has_permissions_to_edit_user( $user->ID ) ) { + return; + } + + $option_name = static::ENABLE_NOTIFICATIONS; + $value = Utils::get_user_option_with_default( $option_name, $user->ID, '1' ); + + ?> +

      + + + + + + + has_permissions_to_edit_user( $user_id ) ) { + return; + } + + $option_name = static::ENABLE_NOTIFICATIONS; + $value = empty( $_POST[ $option_name ] ) ? '0' : '1'; + + update_user_option( $user_id, $option_name, sanitize_text_field( $value ) ); + } + + /** + * Determine if the current user has permission to view/change notes preferences of a user. + * + * @param int $user_id + * + * @return bool + */ + protected function has_permissions_to_edit_user( $user_id ) { + return ( + current_user_can( Capabilities::READ_NOTES ) && + current_user_can( 'edit_user', $user_id ) + ); + } +} diff --git a/modules/notes/utils.php b/modules/notes/utils.php new file mode 100644 index 00000000..3d0a62dc --- /dev/null +++ b/modules/notes/utils.php @@ -0,0 +1,114 @@ +filter( function ( $value, $key ) use ( $remove_if_start_with, $remove_if_end_with, $remove_if_is ) { + foreach ( $remove_if_start_with as $term ) { + if ( 0 === strpos( $key, $term ) ) { + return false; + }; + } + + foreach ( $remove_if_end_with as $term ) { + if ( 1 === preg_match( "/{$term}$/", $key ) ) { + return false; + }; + } + + foreach ( $remove_if_is as $term ) { + if ( $key === $term ) { + return false; + } + } + + return true; + } ); + + if ( ! $query->is_empty() ) { + $url = implode( '?', [ + $url, + build_query( $query->all() ), + ] ); + } + } + + return esc_url_raw( rtrim( $url, '/' ) ); + } + + /** + * @param $value + * + * @return bool + */ + public static function validate_url_or_relative_url( $value ) { + $is_valid_url = filter_var( $value, FILTER_VALIDATE_URL ); + + if ( $is_valid_url ) { + return (bool) $is_valid_url; + } + + // Check if the $value is relative url. + return (bool) filter_var( 'https://localhost/' . ltrim( $value, '/' ), FILTER_VALIDATE_URL ); + } + + /** + * Clean the WP document title and return it. + * + * @return string + */ + public static function get_clean_document_title() { + $filter = function ( $title ) { + if ( is_home() || is_front_page() ) { + return [ esc_html__( 'Home page', 'elementor-pro' ) ]; + } + + unset( $title['site'] ); + + return $title; + }; + + add_filter( 'document_title_parts', $filter ); + + $title = wp_get_document_title(); + + remove_filter( 'document_title_parts', $filter ); + + return $title; + } +} diff --git a/modules/off-canvas/module.php b/modules/off-canvas/module.php new file mode 100644 index 00000000..e1320f35 --- /dev/null +++ b/modules/off-canvas/module.php @@ -0,0 +1,67 @@ +experiments->is_feature_active( 'nested-elements' ); + } + + public function register_tag( DynamicTagsManager $dynamic_tags ) { + $tag = __NAMESPACE__ . '\Tag'; + + $dynamic_tags->register( new $tag() ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/off-canvas/assets/scss/frontend.scss` + * to `/assets/css/widget-off-canvas.min.css`. + * + * @return void + */ + public function register_styles() { + wp_register_style( + 'widget-off-canvas', + $this->get_css_assets_url( 'widget-off-canvas', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/off-canvas/tag.php b/modules/off-canvas/tag.php new file mode 100644 index 00000000..1862aa47 --- /dev/null +++ b/modules/off-canvas/tag.php @@ -0,0 +1,89 @@ +add_control( + 'action', + [ + 'label' => esc_html__( 'Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'open', + 'options' => [ + 'open' => esc_html__( 'Open Off-Canvas', 'elementor-pro' ), + 'close' => esc_html__( 'Close Off-Canvas', 'elementor-pro' ), + 'toggle' => esc_html__( 'Toggle Off-Canvas', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'off_canvas', + [ + 'label' => esc_html__( 'Choose Off-Canvas widget', 'elementor-pro' ), + 'atomic_label' => esc_html__( 'Off-canvas widget', 'elementor-pro' ), + 'placeholder' => '', + 'type' => Controls_Manager::SELECT, + 'label_block' => true, + 'options' => [ + '' => esc_html__( 'Select Off-canvas', 'elementor-pro' ), + ], + 'default' => '', + 'collection_id' => $this->get_name(), + ] + ); + } + + public function render() { + $settings = $this->get_active_settings(); + + if ( ! $settings['off_canvas'] ) { + return; + } + + $link_action_url = Plugin::elementor()->frontend->create_action_hash( 'off_canvas:' . $settings['action'], [ + 'id' => apply_filters( 'elementor-pro/off-canvas/id', $settings['off_canvas'] ), + 'displayMode' => $settings['action'], + ] ); + + // PHPCS - `create_action_hash` is safe. + echo $link_action_url; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + // Keep Empty to avoid default advanced section + protected function register_advanced_section() {} +} diff --git a/modules/off-canvas/widgets/off-canvas.php b/modules/off-canvas/widgets/off-canvas.php new file mode 100644 index 00000000..6d14a4d4 --- /dev/null +++ b/modules/off-canvas/widgets/off-canvas.php @@ -0,0 +1,608 @@ +experiments->is_feature_active( 'nested-elements', true ); + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-off-canvas' ]; + } + + protected function get_default_children_elements() { + return [ + [ + 'elType' => 'container', + 'settings' => [ + 'content_width' => 'full', + ], + ], + ]; + } + + protected function get_default_repeater_title_setting_key() { + return ''; + } + + protected function register_controls() { + $this->register_content_tab(); + $this->register_style_tab(); + } + + protected function register_content_tab() { + $this->register_layout_section(); + $this->register_settings_section(); + } + + protected function register_style_tab() { + $this->register_background_controls(); + $this->register_overlay_controls(); + } + + protected function get_default_children_placeholder_selector() { + return '.e-off-canvas__content'; + } + + protected function register_layout_section() { + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'learn_more_alert', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + '%1$s %2$s', + esc_html__( 'To open your Off-Canvas, add a link or button to your page, and set its dynamic tag to \'Off-Canvas\'.', 'elementor-pro' ), + esc_html__( 'Show me how', 'elementor-pro' ), + ), + ] + ); + + $this->add_control( + 'editing_mode', + [ + 'label' => esc_html__( 'Editing Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'editor_available' => true, + 'render_type' => 'ui', + 'separator' => 'after', + ] + ); + + $this->add_control( + 'off_canvas_name', + [ + 'label' => esc_html__( 'Off-Canvas Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Off-Canvas', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'horizontal_position', + [ + 'label' => esc_html__( 'Horizontal Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'flex-start' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-justify-content: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'flex-end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-align-items: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 500, + ], + '%' => [ + 'max' => 50, + ], + 'em' => [ + 'min' => 0, + 'max' => 5, + ], + 'rem' => [ + 'min' => 0, + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'fit-content' => esc_html__( 'Fit To Content', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'selectors_dictionary' => [ + 'fit-content' => '--e-off-canvas-height: fit-content; --e-off-canvas-content-overflow: initial;', + 'custom' => '--e-off-canvas-height: 100vh; --e-off-canvas-content-overflow: auto;', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'default' => 'custom', + ] + ); + + $this->add_responsive_control( + 'custom_height', + [ + 'label' => esc_html__( 'Custom Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'min' => 0, + ], + 'rem' => [ + 'min' => 0, + ], + ], + 'condition' => [ + 'height' => 'custom', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-height: {{SIZE}}{{UNIT}};', + ], + 'default' => [ + 'unit' => 'vh', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_settings_section() { + $this->start_controls_section( + 'section_settings', + [ + 'label' => esc_html__( 'Settings', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_responsive_control( + 'entrance_animation', + [ + 'label' => esc_html__( 'Entrance', 'elementor-pro' ), + 'type' => Controls_Manager::ANIMATION, + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'exit_animation', + [ + 'label' => esc_html__( 'Exit', 'elementor-pro' ), + 'type' => Controls_Manager::EXIT_ANIMATION, + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'offcanvas_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + 'size' => 1.5, + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-animation-duration: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'entrance_animation', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'exit_animation', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'interactions', + [ + 'label' => esc_html__( 'Interactions', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'is_not_close_on_overlay', + [ + 'label' => esc_html__( 'Prevent Closing on Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'is_not_close_on_esc_overlay', + [ + 'label' => esc_html__( 'Prevent Closing on ESC Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'prevent_scroll', + [ + 'label' => esc_html__( 'Disable Page Scrolling', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'wrapper_html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'div', + 'options' => [ + 'div' => 'div', + 'main' => 'main', + 'article' => 'article', + 'header' => 'header', + 'footer' => 'footer', + 'section' => 'section', + 'aside' => 'aside', + 'nav' => 'nav', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + } + + protected function register_background_controls() { + $this->start_controls_section( + 'section_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .e-off-canvas__content', + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'border', + 'selector' => '{{WRAPPER}} .e-off-canvas__content', + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-off-canvas__content' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .e-off-canvas__content', + ] + ); + + $this->end_controls_section(); + } + + protected function register_overlay_controls() { + $this->start_controls_section( + 'section_overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'has_overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'selectors_dictionary' => [ + 'yes' => '1', + '' => '0', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-off-canvas-overlay-opacity: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'overlay_background', + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}} .e-off-canvas__overlay', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'default' => 'rgba(0,0,0,.8)', + ], + ], + 'condition' => [ + 'has_overlay' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $this->add_wrapper_attributes(); + $tag = $this->get_settings_for_display( 'wrapper_html_tag' ); + ?> + < print_render_attribute_string( 'off-canvas__wrapper' ); ?>> +
      print_render_attribute_string( 'off-canvas__overlay' ); ?>>
      +
      +
      + get_children() ?? []; + + foreach ( $children as $child ) { + $child->print_element(); + } + ?> +
      +
      + > + + <# + const tag = elementor.helpers.validateHTMLTag( settings.wrapper_html_tag ), + isClosed = elementor.previewView.isBuffering || 'yes' !== settings.editing_mode; + + view.addRenderAttribute( 'offCanvasWrapper', { + 'class': [ 'e-off-canvas' ], + 'id': 'off-canvas-' + view.getID(), + 'role': 'dialog', + 'aria-hidden': isClosed, + 'aria-label': settings.off_canvas_name, + 'aria-modal': 'true', + } ); + + if ( isClosed ) { + view.addRenderAttribute( 'offCanvasWrapper', { + 'inert': '', + 'data-delay-child-handlers': 'true', + } ); + } + + view.addRenderAttribute( 'offCanvasOverlay', { + 'class': [ 'e-off-canvas__overlay' ], + } ); + #> + +
      + +
      + + <{{{ tag }}} {{{ view.getRenderAttributeString( 'offCanvasWrapper' ) }}}> +
      +
      +
      +
      + + add_render_attribute( 'off-canvas__wrapper', [ + 'id' => 'off-canvas-' . apply_filters( 'elementor-pro/off-canvas/id', $this->get_id() ), + 'class' => 'e-off-canvas', + 'role' => 'dialog', + 'aria-hidden' => 'true', + 'aria-label' => $this->get_settings_for_display( 'off_canvas_name' ), + 'aria-modal' => 'true', + 'inert' => '', + 'data-delay-child-handlers' => 'true', + ] ); + + $this->add_render_attribute( 'off-canvas__overlay', [ + 'class' => 'e-off-canvas__overlay', + ] ); + } + + protected function is_dynamic_content(): bool { + global $wp_query; + + if ( ! isset( $wp_query->is_loop_widget ) ) { + return false; + } + + return true; + } +} diff --git a/modules/page-transitions/module.php b/modules/page-transitions/module.php new file mode 100644 index 00000000..11e38c06 --- /dev/null +++ b/modules/page-transitions/module.php @@ -0,0 +1,877 @@ +add_actions(); + } + + /** + * Get the module name. + * + * @return string + */ + public function get_name() { + return self::NAME; + } + + /** + * Register the Page Transitions controls. + * + * @param $element Controls_Stack + * @param $section_id string + * + * @return void + */ + public function register_controls( Controls_Stack $element, $section_id ) { + // Remove Page Transitions Banner (from Core version). + if ( 'section_page_transitions_teaser' !== $section_id ) { + return; + } + + // Delete the Teaser message. + Plugin::elementor()->controls_manager->remove_control_from_stack( + $element->get_unique_name(), + [ + 'section_page_transitions_teaser', + 'page_transitions_teaser', + ] + ); + + // Replace the teaser message with actual controls. + $this->register_page_transitions_controls( $element ); + } + + /** + * Retrieve a control ID prefixed with the tab ID. + * + * @param string $id - Control id. + * + * @return string + */ + private function get_control_id( $id ) { + $tab_id = Settings_Page_Transitions::TAB_ID; + $tab_id = str_replace( '-', '_', $tab_id ); + + return $tab_id . '_' . $id; + } + + /** + * Add a Page Transitions preview button. + * + * @param Controls_Stack $controls_stack - Controls Stack context to add the button to. + * @param string $prefix - Button ID prefix. + * + * @return void + */ + private function add_preview_button( $controls_stack, $prefix ) { + $controls_stack->add_control( + $this->get_control_id( $prefix . '_play_button' ), + [ + 'type' => Controls_Manager::BUTTON, + 'label_block' => true, + 'text' => esc_html__( 'Preview Page Transition', 'elementor-pro' ), + 'button_type' => 'default e-page-transition-preview', + 'separator' => 'before', + 'event' => 'elementorPageTransitions:animate', + 'condition' => [ + $this->get_control_id( 'entrance_animation' ) . '!' => '', + ], + ] + ); + } + + /** + * Replace the Page Transition teaser with actual controls. + * + * @param Controls_Stack $controls_stack + * + * @return void + */ + public function register_page_transitions_controls( $controls_stack ) { + /** + * Page Transitions + */ + $controls_stack->start_controls_section( + 'section_page_transitions', + [ + 'label' => esc_html__( 'Page Transitions', 'elementor-pro' ), + 'tab' => Settings_Page_Transitions::TAB_ID, + ] + ); + + $controls_stack->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => $this->get_control_id( 'background' ), + 'exclude' => [ 'image', 'video' ], + 'fields_options' => [ + 'background' => [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'default' => 'classic', + 'description' => esc_html__( 'This is the page color behind your loading animation', 'elementor-pro' ), + ], + 'color' => [ + 'default' => '#FFBC7D', + ], + ], + 'selector' => '{{WRAPPER}} e-page-transition', + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'entrance_animation' ), + [ + 'label' => esc_html__( 'Entrance Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => true, + // The animations are the opposite of what the user sees because the user thinks in the context + // of a page transition, while we actually animate the overlay. + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'fade-out' => esc_html__( 'Fade In', 'elementor-pro' ), + 'fade-out-down' => esc_html__( 'Fade In Down', 'elementor-pro' ), + 'fade-out-right' => esc_html__( 'Fade In Right', 'elementor-pro' ), + 'fade-out-up' => esc_html__( 'Fade In Up', 'elementor-pro' ), + 'fade-out-left' => esc_html__( 'Fade In Left', 'elementor-pro' ), + 'zoom-out' => esc_html__( 'Zoom In', 'elementor-pro' ), + 'slide-out-down' => esc_html__( 'Slide In Down', 'elementor-pro' ), + 'slide-out-right' => esc_html__( 'Slide In Right', 'elementor-pro' ), + 'slide-out-up' => esc_html__( 'Slide In Up', 'elementor-pro' ), + 'slide-out-left' => esc_html__( 'Slide In Left', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-page-transition-entrance-animation: e-page-transition-{{VALUE}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'exit_animation' ), + [ + 'label' => esc_html__( 'Exit Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => true, + // The animations are the opposite of what the user sees because the user thinks in the context + // of a page transition, while we actually animate the overlay. + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'fade-in' => esc_html__( 'Fade Out', 'elementor-pro' ), + 'fade-in-down' => esc_html__( 'Fade Out Down', 'elementor-pro' ), + 'fade-in-right' => esc_html__( 'Fade Out Right', 'elementor-pro' ), + 'fade-in-up' => esc_html__( 'Fade Out Up', 'elementor-pro' ), + 'fade-in-left' => esc_html__( 'Fade Out Left', 'elementor-pro' ), + 'zoom-in' => esc_html__( 'Zoom Out', 'elementor-pro' ), + 'slide-in-down' => esc_html__( 'Slide Out Down', 'elementor-pro' ), + 'slide-in-right' => esc_html__( 'Slide Out Right', 'elementor-pro' ), + 'slide-in-up' => esc_html__( 'Slide Out Up', 'elementor-pro' ), + 'slide-in-left' => esc_html__( 'Slide Out Left', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-page-transition-exit-animation: e-page-transition-{{VALUE}}', + ], + 'condition' => [ + $this->get_control_id( 'entrance_animation' ) . '!' => '', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'animation_duration' ), + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + 'size' => 1500, + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'condition' => [ + $this->get_control_id( 'entrance_animation' ) . '!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-page-transition-animation-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_preview_button( $controls_stack, 'page_transition' ); + + $controls_stack->end_controls_section(); + + /** + * Preloader + */ + $controls_stack->start_controls_section( + 'section_preloader', + [ + 'label' => esc_html__( 'Preloader', 'elementor-pro' ), + 'tab' => Settings_Page_Transitions::TAB_ID, + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_type' ), + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + self::TYPE_ANIMATION => esc_html__( 'Animation', 'elementor-pro' ), + self::TYPE_ICON => esc_html__( 'Icon', 'elementor-pro' ), + self::TYPE_IMAGE => esc_html__( 'Image', 'elementor-pro' ), + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_icon' ), + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-spinner', + 'library' => 'fa-solid', + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'icon', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_image' ), + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'image', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_animation_type' ), + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => self::LOADER_CIRCLE, + 'options' => [ + self::LOADER_CIRCLE => esc_html__( 'Circle', 'elementor-pro' ), + self::LOADER_CIRCLE_DASHED => esc_html__( 'Circle Dashed', 'elementor-pro' ), + self::LOADER_BOUNCING_DOTS => esc_html__( 'Bouncing Dots', 'elementor-pro' ), + self::LOADER_PULSING_DOTS => esc_html__( 'Pulsing Dots', 'elementor-pro' ), + self::LOADER_PULSE => esc_html__( 'Pulse', 'elementor-pro' ), + self::LOADER_OVERLAP => esc_html__( 'Overlap', 'elementor-pro' ), + self::LOADER_SPINNERS => esc_html__( 'Spinners', 'elementor-pro' ), + self::LOADER_NESTED_SPINNERS => esc_html__( 'Nested Spinners', 'elementor-pro' ), + self::LOADER_OPPOSING_NESTED_SPINNERS => esc_html__( 'Opposing Nested Spinners', 'elementor-pro' ), + self::LOADER_OPPOSING_NESTED_RINGS => esc_html__( 'Opposing Nested Rings', 'elementor-pro' ), + self::LOADER_PROGRESS_BAR => esc_html__( 'Progress Bar', 'elementor-pro' ), + self::LOADER_TWO_WAY_PROGRESS_BAR => esc_html__( 'Two Way Progress Bar', 'elementor-pro' ), + self::LOADER_REPEATING_BAR => esc_html__( 'Repeating Bar', 'elementor-pro' ), + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'animation', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_animation' ), + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'eicon-spin' => esc_html__( 'Spinning', 'elementor-pro' ), + 'bounce' => esc_html__( 'Bounce', 'elementor-pro' ), + 'flash' => esc_html__( 'Flash', 'elementor-pro' ), + 'pulse' => esc_html__( 'Pulse', 'elementor-pro' ), + 'rubberBand' => esc_html__( 'Rubber Band', 'elementor-pro' ), + 'shake' => esc_html__( 'Shake', 'elementor-pro' ), + 'headShake' => esc_html__( 'Head Shake', 'elementor-pro' ), + 'swing' => esc_html__( 'Swing', 'elementor-pro' ), + 'tada' => esc_html__( 'Tada', 'elementor-pro' ), + 'wobble' => esc_html__( 'Wobble', 'elementor-pro' ), + 'jello' => esc_html__( 'Jello', 'elementor-pro' ), + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => [ 'icon', 'image' ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-animation: {{VALUE}}', + ], + ] + ); + + // Include animation speed control only for specific pre-loaders which support that. + $included_preloaders = [ + self::LOADER_CIRCLE, + self::LOADER_CIRCLE_DASHED, + self::LOADER_BOUNCING_DOTS, + self::LOADER_PULSING_DOTS, + self::LOADER_SPINNERS, + self::LOADER_NESTED_SPINNERS, + self::LOADER_OPPOSING_NESTED_SPINNERS, + self::LOADER_OPPOSING_NESTED_RINGS, + self::LOADER_PROGRESS_BAR, + self::LOADER_TWO_WAY_PROGRESS_BAR, + self::LOADER_REPEATING_BAR, + ]; + + $controls_stack->add_control( + $this->get_control_id( 'preloader_animation_duration' ), + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + 'size' => 1500, + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + // Show the control only for images, icons & specific custom pre-loaders. + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => $this->get_control_id( 'preloader_type' ), + 'operator' => 'in', + 'value' => [ + self::TYPE_IMAGE, + self::TYPE_ICON, + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => $this->get_control_id( 'preloader_type' ), + 'operator' => '=', + 'value' => self::TYPE_ANIMATION, + ], + [ + 'name' => $this->get_control_id( 'preloader_animation_type' ), + 'operator' => 'in', + 'value' => $included_preloaders, + ], + ], + ], + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-animation-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_delay' ), + [ + 'label' => esc_html__( 'Preloader Delay', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + 'size' => 0, + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) . '!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-delay: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'text_heading' ), + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + $this->get_control_id( 'preloader_type' ) . '!' => '', + ], + ] + ); + + $controls_stack->add_control( + $this->get_control_id( 'preloader_color' ), + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#FFF', + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => [ 'icon', 'animation' ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-color: {{VALUE}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'preloader_size' ), + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 300, + ], + 'em' => [ + 'max' => 30, + ], + 'rem' => [ + 'max' => 30, + ], + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => [ 'icon', 'animation' ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + // Animation to exclude in rotation. + $excluded_animations = [ + 'eicon-spin', + 'bounce', + 'pulse', + 'rubberBand', + 'shake', + 'headShake', + 'swing', + 'tada', + 'wobble', + 'jello', + ]; + + $controls_stack->add_responsive_control( + $this->get_control_id( 'preloader_rotate' ), + [ + 'label' => esc_html__( 'Rotate', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'deg', 'grad', 'rad', 'turn' ], + 'default' => [ + 'unit' => 'deg', + 'size' => 0, + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'icon', + $this->get_control_id( 'preloader_animation' ) . '!' => $excluded_animations, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-rotate: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'preloader_width' ), + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 1, + 'max' => 100, + ], + 'px' => [ + 'min' => 1, + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + 'vw' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'image', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'preloader_max_width' ), + [ + 'label' => esc_html__( 'Max Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'range' => [ + '%' => [ + 'min' => 1, + 'max' => 100, + ], + 'px' => [ + 'min' => 1, + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + 'vw' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'image', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-max-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + $this->get_control_id( 'preloader_opacity' ), + [ + 'label' => esc_html__( 'Opacity', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 1, + 'step' => 0.1, + ], + ], + 'condition' => [ + $this->get_control_id( 'preloader_type' ) => 'image', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-preloader-opacity: {{SIZE}}', + ], + ] + ); + + $this->add_preview_button( $controls_stack, 'preloader' ); + + $controls_stack->end_controls_section(); + } + + /** + * Get a control value from the settings. + * + * @param string $control - Non prefixed control name. + * + * @return mixed + */ + private function get_setting( $control ) { + $document = Plugin::elementor()->kits_manager->get_active_kit_for_frontend(); + $control = $this->get_control_id( $control ); + + return $document->get_settings_for_display( $control ); + } + + /** + * Get the Page Transitions element CSS class. + * + * @return string + */ + private function get_page_transition_class() { + $is_preview_mode = Plugin::elementor()->preview->is_preview_mode(); + return $is_preview_mode ? 'e-page-transition--entered' : 'e-page-transition--entering'; + } + + /** + * Get the Page Transitions links Regex filter. + * + * @return string + */ + private function get_page_transition_filter() { + // Prepare the admin URL to be "regex-ready" (escape special characters). + $admin_url = preg_quote( get_admin_url(), '/' ); + + // A regex pattern for URLs under `wp-admin`. + return '^' . $admin_url; + } + + /** + * Print the Page Transition element attributes. + * + * @return void + */ + private function print_render_attribute_string() { + $kit = Plugin::elementor()->kits_manager->get_active_kit(); + + $settings = [ + 'preloader_type', + 'preloader_icon', + 'preloader_image', + 'preloader_animation_type', + ]; + + foreach ( $settings as $setting ) { + $key = str_replace( '_', '-', $setting ); + $value = $this->get_setting( $setting ); + + if ( empty( $value ) ) { + continue; + } + + // Change the key & value specifically for the image control, since the returned value + // is an array while the Page Transition element expects a URL as a string. + if ( 'preloader-image' === $key ) { + $key = 'preloader-image-url'; + $value = $value['url']; + } + + $kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, $key, $value ); + } + + $class = $this->get_page_transition_class(); + + if ( $class ) { + $kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, 'class', $class ); + } + + // Add URL regex filter to filter only URLs without `wp-admin`. + $kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, 'exclude', $this->get_page_transition_filter() ); + + $kit->print_render_attribute_string( Settings_Page_Transitions::TAB_ID ); + } + + /** + * Determine if the Page Transition element should be rendered. + * + * @return bool + */ + private function should_render() { + // Don't render the Page Transition if the page is a non-interactive (static-rendered) page (e.g. template-preview). + if ( Plugin::elementor()->frontend->is_static_render_mode() ) { + return false; + } + + $has_entrance_animation = ! ! $this->get_setting( 'entrance_animation' ); + $has_preloader = ! ! $this->get_setting( 'preloader_type' ); + $is_page = ( is_singular() || is_archive() ) && ! is_paged(); + + return $is_page && ( $has_entrance_animation || $has_preloader ); + } + + /** + * Whether the Page Transitions scripts should be enqueued. + * When in preview mode, the scripts should be loaded since the user might not have a Page Transition + * set on initial load but he will need them when changing the settings. + * + * @return bool + */ + private function should_enqueue_scripts() { + return $this->should_render() || Plugin::elementor()->preview->is_preview_mode(); + } + + /** + * Render the Page Transition markup. + * + * @return void + */ + private function render() { + $is_inline_font_icon_active = Plugin::elementor()->experiments->is_feature_active( 'e_font_icon_svg' ); + + ?> + print_render_attribute_string(); ?>> + get_setting( 'preloader_icon' ); + + // Render inline SVG icon when the experiment is active, since the component itself + // shouldn't know about the Editor or the experiments. + if ( $is_inline_font_icon_active && ! empty( $icon ) ) { + Icons_Manager::render_icon( $icon, [ 'class' => 'e-page-transition--preloader' ] ); + } + ?> + + enqueue_instant_page_script(); + + wp_enqueue_script( + 'page-transitions', + $this->get_js_assets_url( 'page-transitions' ), + null, + ELEMENTOR_PRO_VERSION, + false + ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url() { + return ELEMENTOR_PRO_URL; + } + + /** + * Add actions & filters. + * + * @return void + */ + private function add_actions() { + add_action( 'elementor/element/after_section_end', [ $this, 'register_controls' ], 10, 2 ); + + add_action( 'wp_enqueue_scripts', function () { + if ( $this->should_enqueue_scripts() ) { + $this->enqueue_scripts(); + } + } ); + + // Render the Page Transition element after the body open tag. + add_action( 'wp_body_open', function () { + if ( $this->should_render() ) { + $this->render(); + } + }, 10, 2 ); + } +} diff --git a/modules/payments/classes/payment-button.php b/modules/payments/classes/payment-button.php new file mode 100644 index 00000000..04771c5a --- /dev/null +++ b/modules/payments/classes/payment-button.php @@ -0,0 +1,612 @@ + _x( 'AUD', 'Currency', 'elementor-pro' ), + 'CAD' => _x( 'CAD', 'Currency', 'elementor-pro' ), + 'CZK' => _x( 'CZK', 'Currency', 'elementor-pro' ), + 'DKK' => _x( 'DKK', 'Currency', 'elementor-pro' ), + 'EUR' => _x( 'EUR', 'Currency', 'elementor-pro' ), + 'HKD' => _x( 'HKD', 'Currency', 'elementor-pro' ), + 'HUF' => _x( 'HUF', 'Currency', 'elementor-pro' ), + 'ILS' => _x( 'ILS', 'Currency', 'elementor-pro' ), + 'JPY' => _x( 'JPY', 'Currency', 'elementor-pro' ), + 'MXN' => _x( 'MXN', 'Currency', 'elementor-pro' ), + 'NOK' => _x( 'NOK', 'Currency', 'elementor-pro' ), + 'NZD' => _x( 'NZD', 'Currency', 'elementor-pro' ), + 'PHP' => _x( 'PHP', 'Currency', 'elementor-pro' ), + 'PLN' => _x( 'PLN', 'Currency', 'elementor-pro' ), + 'GBP' => _x( 'GBP', 'Currency', 'elementor-pro' ), + 'RUB' => _x( 'RUB', 'Currency', 'elementor-pro' ), + 'SGD' => _x( 'SGD', 'Currency', 'elementor-pro' ), + 'SEK' => _x( 'SEK', 'Currency', 'elementor-pro' ), + 'CHF' => _x( 'CHF', 'Currency', 'elementor-pro' ), + 'TWD' => _x( 'TWD', 'Currency', 'elementor-pro' ), + 'THB' => _x( 'THB', 'Currency', 'elementor-pro' ), + 'TRY' => _x( 'TRY', 'Currency', 'elementor-pro' ), + 'USD' => _x( 'USD', 'Currency', 'elementor-pro' ), + ]; + } + + // Return an array of default error messages. + protected function get_default_error_messages() { + return [ + self::ERROR_MESSAGE_GLOBAL => esc_html__( 'An error occurred.', 'elementor-pro' ), + self::ERROR_MESSAGE_PAYMENT_METHOD => esc_html__( 'No payment method connected. Contact seller.', 'elementor-pro' ), + ]; + } + + // Get message text by id (`error_message_$id`). + protected function get_custom_message( $id ) { + $message = $this->get_settings_for_display( 'error_message_' . $id ); + + // Return the user-defined message. + if ( ! empty( $message ) ) { + return $message; + } + + // Return the default message. + $error_messages = $this->get_default_error_messages(); + + return ( ! empty( $error_messages[ $id ] ) ) ? $error_messages[ $id ] : esc_html__( 'Unknown error.', 'elementor-pro' ); + } + + // Product details section. + protected function register_product_controls() { + + $this->add_control( + 'type', + [ + 'label' => esc_html__( 'Transaction Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'checkout', + 'options' => [ + self::PAYMENT_TYPE_CHECKOUT => esc_html__( 'Checkout', 'elementor-pro' ), + self::PAYMENT_TYPE_DONATION => esc_html__( 'Donation', 'elementor-pro' ), + self::PAYMENT_TYPE_SUBSCRIPTION => esc_html__( 'Subscription', 'elementor-pro' ), + ], + 'separator' => 'before', + ] + ); + + $this->after_product_type(); + + $this->add_control( + 'product_name', + [ + 'label' => esc_html__( 'Item Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + ] + ); + + $this->add_control( + 'product_sku', + [ + 'label' => esc_html__( 'SKU', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'product_price', + [ + 'label' => esc_html__( 'Price', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '0.00', + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'type!' => self::PAYMENT_TYPE_DONATION, + ], + ] + ); + + $this->add_control( + 'donation_type', + [ + 'label' => esc_html__( 'Donation Amount', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => self::DONATION_TYPE_FIXED, + 'options' => [ + self::DONATION_TYPE_ANY => esc_html__( 'Any Amount', 'elementor-pro' ), + self::DONATION_TYPE_FIXED => esc_html__( 'Fixed', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_DONATION, + ], + ] + ); + + $this->add_control( + 'donation_amount', + [ + 'label' => esc_html__( 'Amount', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '1', + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_DONATION, + 'donation_type' => self::DONATION_TYPE_FIXED, + ], + ] + ); + + $this->add_control( + 'currency', + [ + 'label' => esc_html__( 'Currency', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'USD', + 'options' => $this->get_currencies(), + ] + ); + + $this->add_control( + 'billing_cycle', + [ + 'label' => esc_html__( 'Billing Cycle', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => self::BILLING_CYCLE_MONTHS, + 'options' => [ + self::BILLING_CYCLE_DAYS => esc_html__( 'Daily', 'elementor-pro' ), + self::BILLING_CYCLE_WEEKS => esc_html__( 'Weekly', 'elementor-pro' ), + self::BILLING_CYCLE_MONTHS => esc_html__( 'Monthly', 'elementor-pro' ), + self::BILLING_CYCLE_YEARS => esc_html__( 'Yearly', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_SUBSCRIPTION, + ], + ] + ); + + $this->add_control( + 'auto_renewal', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Auto Renewal', 'elementor-pro' ), + 'default' => 'yes', + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'type' => self::PAYMENT_TYPE_SUBSCRIPTION, + ], + ] + ); + + $this->add_control( + 'quantity', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 1, + 'condition' => [ + 'type' => self::PAYMENT_TYPE_CHECKOUT, + ], + ] + ); + + $this->add_control( + 'shipping_price', + [ + 'label' => esc_html__( 'Shipping Price', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_CHECKOUT, + ], + ] + ); + + $this->add_control( + 'tax_type', + [ + 'label' => esc_html__( 'Tax', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'percentage' => esc_html__( 'Percentage', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_CHECKOUT, + ], + ] + ); + + $this->add_control( + 'tax_rate', + [ + 'label' => esc_html__( 'Tax Percentage', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '0', + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'type' => self::PAYMENT_TYPE_CHECKOUT, + 'tax_type' => 'percentage', + ], + ] + ); + } + + // Submission settings section. + protected function register_settings_section() { + $this->start_controls_section( + 'section_settings', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'redirect_after_success', + [ + 'label' => esc_html__( 'Redirect After Success', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'options' => false, + 'placeholder' => esc_html__( 'Choose a page or add a URL', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'render_type' => 'none', + ] + ); + + $this->add_control( + 'sandbox_mode', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Sandbox', 'elementor-pro' ), + 'default' => 'no', + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->register_sandbox_controls(); + + $this->add_control( + 'open_in_new_window', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => sprintf( + /* translators: %s: Merchant name. */ + esc_html__( 'Open %s In New Tab', 'elementor-pro' ), + $this->get_merchant_name() + ), + 'default' => 'yes', + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'custom_messages', + [ + 'label' => esc_html__( 'Custom Messages', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ] + ); + + $this->after_custom_messages_toggle(); + + $error_messages = $this->get_default_error_messages(); + + $this->add_control( + 'error_message_' . self::ERROR_MESSAGE_GLOBAL, + [ + 'label' => esc_html__( 'Error Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => $error_messages[ self::ERROR_MESSAGE_GLOBAL ], + 'placeholder' => $error_messages[ self::ERROR_MESSAGE_GLOBAL ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'error_message_' . self::ERROR_MESSAGE_PAYMENT_METHOD, + [ + 'label' => sprintf( + /* translators: %s: Merchant name. */ + esc_html__( '%s Not Connected', 'elementor-pro' ), + $this->get_merchant_name() + ), + 'type' => Controls_Manager::TEXT, + 'default' => $error_messages[ self::ERROR_MESSAGE_PAYMENT_METHOD ], + 'placeholder' => $error_messages[ self::ERROR_MESSAGE_PAYMENT_METHOD ], + 'label_block' => true, + 'condition' => [ + 'custom_messages!' => '', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->update_error_massages(); + + $this->end_controls_section(); + } + + // Customize the default button controls. + protected function register_button_controls() { + parent::register_controls(); + + $this->remove_control( 'button_type' ); + + $this->remove_control( 'link' ); + + $this->remove_control( 'size' ); + + $this->update_control( 'text', [ + 'default' => 'Buy Now', + ] ); + + $this->update_control( 'button_text_color', [ + 'default' => '#FFF', + ] ); + + $this->update_control( 'border_border', [ + 'default' => 'none', + ] ); + } + + // Add typography settings for custom messages. + protected function register_messages_style_section() { + $this->start_controls_section( + 'section_messages_style', + [ + 'label' => esc_html__( 'Messages', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'message_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-message', + ] + ); + + $this->add_control( + 'message_color_' . self::ERROR_MESSAGE_GLOBAL, + [ + 'label' => esc_html__( 'Error Message Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-message.elementor-error-message-' . self::ERROR_MESSAGE_GLOBAL => 'color: {{COLOR}};', + ], + ] + ); + + $this->add_control( + 'message_color_' . self::ERROR_MESSAGE_PAYMENT_METHOD, + [ + 'label' => sprintf( + /* translators: %s: Merchant name. */ + esc_html__( '%s Not Connected Color', 'elementor-pro' ), + $this->get_merchant_name() + ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-message.elementor-error-message-' . self::ERROR_MESSAGE_PAYMENT_METHOD => 'color: {{COLOR}};', + ], + ] + ); + + $this->end_controls_section(); + } + + // Register widget controls. + protected function register_controls() { + $this->register_account_section(); + $this->register_button_controls(); + $this->register_settings_section(); + $this->register_messages_style_section(); + } + + // Render the checkout button. + protected function render_button( ?Widget_Base $instance = null, $tag = 'a' ) { + $this->add_render_attribute( 'button', 'class', 'elementor-payment-button' ); + + ?> + < print_render_attribute_string( 'button' ); ?>> + render_text(); ?> + > + get_settings_for_display(); + + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + + if ( ! $optimized_markup ) { + $this->add_render_attribute( 'wrapper', 'class', 'elementor-button-wrapper' ); + } + + $this->add_render_attribute( 'button', 'class', 'elementor-button' ); + $this->add_render_attribute( 'button', 'role', 'button' ); + + if ( ! empty( $settings['button_css_id'] ) ) { + $this->add_render_attribute( 'button', 'id', $settings['button_css_id'] ); + } + + if ( ! empty( $settings['size'] ) ) { + $this->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['size'] ); + } else { + $this->add_render_attribute( 'button', 'class', 'elementor-size-sm' ); // BC, to make sure the class is always present + } + + if ( $settings['hover_animation'] ) { + $this->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['hover_animation'] ); + } + ?> + +
      print_render_attribute_string( 'wrapper' ); ?>> + + render_button(); ?> + +
      + + + <# + const optimized_markup = elementorCommon.config.experimentalFeatures.e_optimized_markup; + + if ( ! optimized_markup ) { + view.addRenderAttribute( 'wrapper', 'class', 'elementor-button-wrapper' ); + } + + view.addRenderAttribute( 'button', 'class', 'elementor-button' ); + view.addRenderAttribute( 'content-wrapper', 'class', 'elementor-button-content-wrapper' ); + view.addRenderAttribute( 'icon', 'class', 'elementor-button-icon' ); + view.addRenderAttribute( 'text', 'class', 'elementor-button-text' ); + + if ( '' !== settings.link?.url ) { + view.addRenderAttribute( 'button', 'class', 'elementor-button-link' ); + view.addRenderAttribute( 'button', 'href', elementor.helpers.sanitizeUrl( settings.link?.url ) ); + } else { + view.addRenderAttribute( 'button', 'role', 'button' ); + } + + if ( '' !== settings.button_css_id ) { + view.addRenderAttribute( 'button', 'id', settings.button_css_id ); + } + + if ( '' !== settings.size ) { + view.addRenderAttribute( 'button', 'class', 'elementor-size-' + settings.size ); + } + + if ( '' !== settings.hover_animation ) { + view.addRenderAttribute( 'button', 'class', 'elementor-animation-' + settings.hover_animation ); + } + + view.addInlineEditingAttributes( 'text', 'none' ); + + const iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, { 'aria-hidden': true }, 'i' , 'object' ); + const migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ); + #> + <# if ( ! optimized_markup ) { #> + + <# } #> + get_settings_for_display( 'sandbox_mode' ); + } +} diff --git a/modules/payments/classes/stripe-handler.php b/modules/payments/classes/stripe-handler.php new file mode 100644 index 00000000..1ffa869d --- /dev/null +++ b/modules/payments/classes/stripe-handler.php @@ -0,0 +1,41 @@ + 'Bearer ' . $secret_key ]; + return wp_remote_get( self::STRIPE_ENDPOINT_URL . $endpoint, [ + 'headers' => $headers, + 'body' => $body, + ] ); + } + + /** + * @param $headers + * @param $body + * @param $endpoint + * @return array|\WP_Error + */ + public function post( $headers, $body, $endpoint ) { + return wp_remote_post( self::STRIPE_ENDPOINT_URL . $endpoint, [ + 'headers' => $headers, + 'body' => $body, + ] ); + } +} diff --git a/modules/payments/module.php b/modules/payments/module.php new file mode 100644 index 00000000..b8a96a77 --- /dev/null +++ b/modules/payments/module.php @@ -0,0 +1,479 @@ + 'Paypal_Button', + self::STRIPE_LICENCE_FEATURE_NAME => 'Stripe_Button', + ]; + + public $secret_key = ''; + private $stripe_handler; + + public function get_widgets() { + return API::filter_active_features( static::WIDGET_NAME_CLASS_NAME_MAP ); + } + + /** + * Error handler + * + * @since 3.7.0 + * + * @param integer $status_code + * @param string $error_massage + */ + protected function error_handler( $status_code, $error_massage ) { + $resp['response']['code'] = $status_code; + $resp['body'] = wp_json_encode( + [ 'error' => [ 'message' => $error_massage ] ], + JSON_PRETTY_PRINT + ); + + wp_send_json( $resp ); + } + + public function get_name() { + return 'payments'; + } + + /** + * Reads secret test key from wp_options table + * + * @since 3.7.0 + * + * @return string + */ + public static function get_global_stripe_test_secret_key() { + return get_option( 'elementor_' . self::STRIPE_TEST_SECRET_KEY, '' ); + } + + /** + * Reads secret live key from wp_options table + * + * @since 3.7.0 + * + * @return string + */ + public static function get_global_stripe_live_secret_key() { + return get_option( 'elementor_' . self::STRIPE_LIVE_SECRET_KEY, '' ); + } + + /** + * Integrations page secret key validations' callback function + * + * @since 3.7.0 + * + * @return void + */ + public function ajax_validate_secret_key() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $action = Utils::_unstable_get_super_global_value( $_POST, 'action' ); + $nonce_action = ( ! strpos( $action, 'test' ) ? self::STRIPE_LIVE_SECRET_KEY : self::STRIPE_TEST_SECRET_KEY ); + + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $nonce = Utils::_unstable_get_super_global_value( $_POST, '_nonce' ); + if ( ! $nonce || ! wp_verify_nonce( $nonce, $nonce_action ) ) { + $this->error_handler( 403, esc_html__( 'Something went wrong, please refresh the page.', 'elementor-pro' ) ); + die(); + } + + if ( ! Utils::_unstable_get_super_global_value( $_POST, 'secret_key' ) ) { + wp_send_json_error(); + } else { + $this->secret_key = Utils::_unstable_get_super_global_value( $_POST, 'secret_key' ); + } + + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Permission denied' ); + } + + $stripe_handler = new Stripe_handler(); + $response = $stripe_handler->get( $this->secret_key, self::STRIPE_TAX_ENDPOINT_URL, [ 'limit' => 0 ] ); + $code = $response['response']['code']; + + if ( 200 !== $code ) { + wp_send_json_error(); + } else { + wp_send_json_success(); + } + } + + /** + * Ajax callback + * + * Returns a list of tax rates + * + * @since 3.7.0 + * + * @return array + */ + public function register_ajax_actions( $ajax ) { + return $ajax->register_ajax_action( 'pro_get_stripe_tax_rates', [ $this, 'get_stripe_tax_rates' ] ); + } + + /** + * returns a list of tax rates + * + * if tax rates are set in stripe admin dashboard + * from here the tax rates array is implemented in + * tax rates select control + * + * @param array $data + * + * @return array - returns to js ajax function. + * + * @throws \Exception + * @since 3.7.0 + * + */ + public function get_stripe_tax_rates( array $data ) { + Utils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + $tax_rates_lists = []; + $tax_rates_lists['live_api_key'] = $this->get_tax_rates( $this->get_global_stripe_live_secret_key() ); + $tax_rates_lists['test_api_key'] = $this->get_tax_rates( $this->get_global_stripe_test_secret_key() ); + return $tax_rates_lists; + } + + /** + * Get ajax tax rates from API + * + * Read all ajax tax rates from stripes API and + * + * @since 3.7.0 + * + * @param string $secret_key + * + * @return array - returns to js ajax function. + * + */ + protected function tax_rates_result_funnel( $secret_key ) { + $response = $this->stripe_handler->get( $secret_key, self::STRIPE_TAX_ENDPOINT_URL, [ 'active' => 'true' ] ); + + // If there is no internet connection or no active tax rates in stripe + if ( ! is_wp_error( $response ) ) { + $decoded_response = json_decode( $response['body'], true ); + + // If there is no API key or a wrong one in integrations page + if ( isset( $decoded_response['error'] ) || 0 === count( $decoded_response['data'] ) ) { + $data = []; + } else { + $data = $decoded_response['data']; + } + } else { + $data = []; + } + + return $data; + } + + /** + * Gets and Organizes all tax rates in a + * list suitable for the select control + * + * @since 3.7.0 + * + * @param string $secret_key + * + * @return array - returns to js ajax function. + * + */ + protected function get_tax_rates( $secret_key ) { + $data = $this->tax_rates_result_funnel( $secret_key ); + return $this->tax_rates_options( $data ); + } + + /** + * Create options array for tax_rates controls + * + * This function can return two scenarios: + * 1. Show tax rates options. + * 2. There are no active tax rates or the user is working on a local environment. + * + * @since 3.7.0 + * + * @param array $data the returned value of get_data_from_api() function + * + * @return array $tax_rates_options placed as the control options + */ + private function tax_rates_options( $data = [] ) { + $tax_rates_options = []; + if ( ! empty( $data ) ) { + foreach ( $data as $k => $v ) { + $is_inclusive = ( true === $v['inclusive'] ? 'inclusive' : 'exclusive' ); + $joint_tax_data = wp_json_encode( [ $v['id'], $is_inclusive ] ); + $display_name = $v['description'] ? $v['display_name'] . ' - ' . $v['description'] : $v['display_name']; + $tax_rates_options[ $joint_tax_data ] = $display_name; + } + // Add 'None' value as the first element in $test_tax_rates_options array. + return array_merge( [ '' => esc_html__( 'None', 'elementor-pro' ) ], $tax_rates_options ); + + } else { + $tax_rates_options = [ '' => esc_html__( 'None', 'elementor-pro' ) ]; + + } + return $tax_rates_options; + } + + /** + * Create options array for tax_rates controls + * + * Zero decimal currencies by stripe https://stripe.com/docs/currencies#zero-decimal + * this option is zero decimal what means that only complete numbers bill pass to stripe. + * for example 555.55 will return product_price of 555. + * + * @since 3.7.0 + * + * @param $currency string + * @param $product_price + * + * @return false|float $tax_rates_options placed as the control options + */ + public function currency_adaptation( $currency, $product_price ) { + $zero_decimal = [ 'BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF' ]; + if ( in_array( $currency, $zero_decimal ) ) { + // There is no need to multiply $product_price by 100 + return floor( $product_price ); + } else { + return floor( $product_price * 100 ); + } + } + + /** + * Secret key conditional function + * + * @since 3.7.0 + * + * @param string $test_mode + * + * @return void + */ + public function set_secret_key_by_environment_state( $test_mode = 'no' ) { + if ( ! $this->secret_key ) { + if ( 'yes' === $test_mode ) { + $this->secret_key = $this->get_global_stripe_test_secret_key(); + } else { + $this->secret_key = $this->get_global_stripe_live_secret_key(); + } + } + } + + /** + * Ajax callback function - API stripe call . + * + * get stripe user data on widget load + * sends the product data and returns the product page checkout url. + * + * @since 3.7.0 + */ + public function submit_stripe_form() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $data = Utils::_unstable_get_super_global_value( $_POST, 'data' ); + if ( ! isset( $data['nonce'] ) || ! wp_verify_nonce( $data['nonce'], 'stripe_form_submit' ) ) { + $this->error_handler( 403, esc_html__( 'Something went wrong, please refresh the page.', 'elementor-pro' ) ); + die(); + } + $args = []; + $widget_id = $data['widgetId'] ?? null; + $args['page_url'] = $data['pageUrl'] ?? null; + + Plugin::elementor()->db->switch_to_post( $data['postId'] ); + $document = Plugin::elementor()->documents->get( $data['postId'] ); + + // Retrieve data from widget document + if ( $document ) { + $widget = \ElementorPro\Modules\Forms\Module::find_element_recursive( $document->get_elements_data(), $widget_id ); + $widget_instance = Plugin::elementor()->elements_manager->create_element_instance( $widget ); + $widget_settings = $widget_instance->get_settings_for_display(); + + $args['product_name'] = $widget_settings['product_name'] ? $widget_settings['product_name'] : 'Product'; + $product_price = $widget_settings['stripe_product_price'] ? $widget_settings['stripe_product_price'] : null; + $args['currency'] = $widget['settings']['stripe_currency'] ? $widget['settings']['stripe_currency'] : 'USD'; + $args['quantity'] = $widget['settings']['stripe_quantity'] ? $widget['settings']['stripe_quantity'] : 1; + $args['success_url'] = ( empty( $widget_settings['redirect_after_success']['url'] ) ? $args['page_url'] : $widget_settings['redirect_after_success']['url'] ); + $args['shipping_amount'] = $widget_settings['shipping_amount'] ? $widget_settings['shipping_amount'] * 100 : ''; + $this->stripe_test_mode = $widget['settings']['sandbox_mode'] ? $widget['settings']['sandbox_mode'] : 'no'; + $args['test_mode'] = $this->stripe_test_mode; + $args['tax_rates'] = 'yes' === $args['test_mode'] ? $widget['settings']['stripe_test_env_tax_rates_list'] : $widget['settings']['stripe_live_env_tax_rates_list']; + } + + $args['unit_amount'] = $this->currency_adaptation( $args['currency'], $product_price ); + + $this->set_secret_key_by_environment_state( $args['test_mode'] ); + + if ( ! empty( $this->secret_key ) ) { + $headers = [ 'Authorization' => 'Bearer ' . $this->secret_key ]; + $body = $this->build_body_for_post_request( $args ); + $this->execute_post_request_to_stripe_api( $headers, $body ); + } else { + $this->error_handler( 401, esc_html__( 'You have not entered a valid secret key for this environment, Please add a valid secret key', 'elementor-pro' ) ); + } + } + + /** + * Builds the body for the API POST request. + * + * @since 3.7.0 + * + * @param $args + * + * @return array + */ + public function build_body_for_post_request( $args ) { + $body = [ + 'cancel_url' => $args['page_url'], + 'payment_method_types' => [ 'card' ], + 'success_url' => $args['success_url'], + 'mode' => 'payment', + 'line_items[0][quantity]' => $args['quantity'], + 'line_items[0][price_data][currency]' => $args['currency'], + 'line_items[0][price_data][product_data][name]' => $args['product_name'], + 'line_items[0][price_data][unit_amount]' => $args['unit_amount'], + ]; + + if ( $args['shipping_amount'] ) { + $body['shipping_options'][0]['shipping_rate_data']['type'] = 'fixed_amount'; + $body['shipping_options'][0]['shipping_rate_data']['fixed_amount']['amount'] = $args['shipping_amount']; + $body['shipping_options'][0]['shipping_rate_data']['fixed_amount']['currency'] = $args['currency']; + $body['shipping_options'][0]['shipping_rate_data']['display_name'] = esc_html__( 'shipping fee', 'elementor-pro' ); + } + + if ( isset( $args['tax_rates'] ) ) { + $tax_rate = json_decode( $args['tax_rates'] ); + $tax_id = [ $tax_rate[0] ]; + $tax_behavior = $tax_rate[1]; + + if ( ! empty( $tax_behavior ) && ! empty( $tax_id ) ) { + $body['line_items'][0]['price_data']['tax_behavior'] = $tax_behavior; + $body['line_items'][0]['tax_rates'] = $tax_id; + } + } + + return $body; + } + + /** + * API call handler + * + * @since 3.7.0 + * + * @param $headers + * @param $body + * + * @return void + */ + public function execute_post_request_to_stripe_api( $headers, $body ) { + $response = $this->stripe_handler->post( $headers, $body, self::STRIPE_CHECKOUT_URL_EXT ); + wp_send_json( $response ); + } + + /** + * Add secret_keys to Elementor integrations section + * + * @since 3.7.0 + * + * @param Settings $settings + */ + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'stripe_api_keys', [ + 'callback' => function () { + echo '

      ' . esc_html__( 'Stripe', 'elementor-pro' ) . '

      '; + echo '

      ' . esc_html__( 'Insert the API keys provided in the stripe admin dashboard to start collecting payments on your website using Stripe.', 'elementor-pro' ) . '
      '; + echo esc_html__( 'These keys will serve as your default API key for all stripe implementations on your site.', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::STRIPE_TEST_SECRET_KEY => [ + 'label' => esc_html__( 'Test Secret key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link to stripe api key explanation, 2: Link closing tag. */ + esc_html__( 'Enter your test secret key %1$slink%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_stripe_api_test_secret_key_button' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::STRIPE_TEST_SECRET_KEY . '_validate', wp_create_nonce( self::STRIPE_TEST_SECRET_KEY ), esc_html__( 'Validate Test API Key', 'elementor-pro' ) ), + ], + ], + self::STRIPE_LIVE_SECRET_KEY => [ + 'label' => esc_html__( 'Live Secret key', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link to stripe api key explanation, 2: Link closing tag. */ + esc_html__( 'Enter your Live secret key %1$slink%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + ], + 'validate_stripe_api_live_secret_key_button' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( '', self::STRIPE_TEST_SECRET_KEY . '_validate', wp_create_nonce( self::STRIPE_TEST_SECRET_KEY ), esc_html__( 'Validate Live API Key', 'elementor-pro' ) ), + ], + ], + 'stripe_legal_disclaimer' => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => sprintf( + /* translators: %s:
      . */ + esc_html__( 'Please note: The Stripe name and logos are trademarks or service marks of Stripe, Inc. or its affiliates in the U.S. and other countries. %s Other names may be trademarks of their respective owners.', 'elementor-pro' ), + '
      ' + ), + ], + ], + ], + ] ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + public function __construct() { + parent::__construct(); + + $this->stripe_handler = new Stripe_Handler(); + + add_action( 'wp_ajax_submit_stripe_form', [ $this, 'submit_stripe_form' ] ); + add_action( 'wp_ajax_nopriv_submit_stripe_form', [ $this, 'submit_stripe_form' ] ); + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + if ( current_user_can( 'administrator' ) && API::is_licence_has_feature( static::STRIPE_LICENCE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 999 ); + } + add_action( 'wp_ajax_' . self::STRIPE_TEST_SECRET_KEY . '_validate', [ $this, 'ajax_validate_secret_key' ] ); + add_action( 'wp_ajax_' . self::STRIPE_LIVE_SECRET_KEY . '_validate', [ $this, 'ajax_validate_secret_key' ] ); + } +} diff --git a/modules/payments/widgets/paypal-button.php b/modules/payments/widgets/paypal-button.php new file mode 100644 index 00000000..4ba64499 --- /dev/null +++ b/modules/payments/widgets/paypal-button.php @@ -0,0 +1,350 @@ + 'D', + self::BILLING_CYCLE_WEEKS => 'W', + self::BILLING_CYCLE_MONTHS => 'M', + self::BILLING_CYCLE_YEARS => 'Y', + ]; + + public function get_name() { + return 'paypal-button'; + } + + public function get_title() { + return esc_html__( 'PayPal Button', 'elementor-pro' ); + } + + public function get_icon() { + return 'eicon-paypal-button'; + } + + public function get_keywords() { + return [ 'paypal', 'payment', 'sell', 'donate' ]; + } + + public function has_widget_inner_wrapper(): bool { + return ! ProPlugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function get_merchant_name() { + return 'PayPal'; + } + + // Retrieve a numerical field from settings, and default to $min if it's too small. + protected function get_numeric_setting( $key, $min = 0 ) { + $num = doubleval( $this->get_settings_for_display( $key ) ); + + return ( $min > $num ) ? $min : $num; + } + + // Print a numerical field from settings, using `get_numeric_setting`. + protected function print_numeric_setting( $key, $min = 0 ) { + // PHPCS - the get_numeric_setting function is safe. + echo $this->get_numeric_setting( $key, $min ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + // Get the currently selected API communication method ( legacy / SDK ). + protected function get_api_method() { + $settings = $this->get_settings_for_display(); + + return ( self::API_TYPE_ADVANCED === $settings['merchant_account'] ) ? 'sdk' : 'legacy'; + } + + // Get validation errors. + protected function get_errors( $squash_errors = true ) { + $settings = $this->get_settings_for_display(); + $errors = []; + + // Don't render errors in the editor. + if ( Plugin::instance()->editor->is_edit_mode() ) { + return $errors; + } + + // No payment method provided. + if ( 'legacy' === $this->get_api_method() ) { + $empty_email = empty( $settings['email'] ); + $empty_sandbox_email = $this->is_sandbox() && empty( $settings['sandbox_email'] ); + + if ( $empty_email || $empty_sandbox_email ) { + $errors[ self::ERROR_MESSAGE_PAYMENT_METHOD ] = $this->get_custom_message( self::ERROR_MESSAGE_PAYMENT_METHOD ); + } + } + + // Other errors. + $empty_product_price = ( self::PAYMENT_TYPE_DONATION !== $settings['type'] && empty( $settings['product_price'] ) ); + $empty_donation_amount = ( self::DONATION_TYPE_FIXED === $settings['donation_type'] && empty( $settings['donation_amount'] ) ); + $empty_tax = ( ! empty( $settings['tax_type'] ) && empty( $settings['tax_rate'] ) ); + + if ( $empty_product_price || $empty_donation_amount || $empty_tax ) { + $errors[ self::ERROR_MESSAGE_GLOBAL ] = $this->get_custom_message( self::ERROR_MESSAGE_GLOBAL ); + } + + // Squash errors to show only a global error. + if ( $squash_errors && 1 < count( $errors ) ) { + return [ + self::ERROR_MESSAGE_GLOBAL => $this->get_custom_message( self::ERROR_MESSAGE_GLOBAL ), + ]; + } + + return $errors; + } + + // Render PayPal's legacy checkout form. + protected function render_legacy_form() { + $settings = $this->get_settings_for_display(); + + // Handle sandbox mode. + if ( ! $this->is_sandbox() ) { + $form_action = self::PROD_URL; + $email = $settings['email']; + } else { + $form_action = self::SANDBOX_URL; + $email = $settings['sandbox_email']; + $this->add_render_attribute( 'button', 'class', 'elementor-payment-sandbox-mode' ); + } + + if ( 'yes' === $settings['open_in_new_window'] ) { + $target = '_blank'; + } else { + $target = '_top'; + } + + // Set PayPal payment settings by payment type. + switch ( $settings['type'] ) { + case self::PAYMENT_TYPE_CHECKOUT: + $cmd = self::CMD_CHECKOUT; + $price_field = [ + 'name' => 'amount', + 'value' => $settings['product_price'], + ]; + break; + + case self::PAYMENT_TYPE_DONATION: + $cmd = self::CMD_DONATION; + $donation_amount = ''; + + // phpcs:ignore + if ( self::DONATION_TYPE_FIXED === $settings['donation_type'] ) { + $donation_amount = $settings['donation_amount']; + } + + $price_field = [ + 'name' => 'amount', + 'value' => $donation_amount, + ]; + break; + + case self::PAYMENT_TYPE_SUBSCRIPTION: + $cmd = self::CMD_SUBSCRIPTION; + $price_field = [ + 'name' => 'a3', + 'value' => $settings['product_price'], + ]; + $auto_renewal = ( 'yes' === $settings['auto_renewal'] ) ? 1 : 0; + $billing_cycle = self::BILLING_CYCLE_TYPES[ $settings['billing_cycle'] ]; + break; + } + + // PayPal HTML reference: + // https://developer.paypal.com/docs/paypal-payments-standard/integration-guide/html-reference-landing/ + + ?> +
      + + + + + + + + + + + + + + + + + + + + + + + add_render_attribute( 'button', 'type', 'submit' ); + $this->add_render_attribute( 'button', 'class', 'elementor-paypal-legacy' ); + parent::render_button( null, 'button' ); + + foreach ( $this->get_errors() as $type => $message ) { + ?> +
      + +
      + +
      + get_api_method() ) { + case 'legacy': + $this->render_legacy_form(); + break; + } + } + + // Account details section. + protected function register_account_section() { + $this->start_controls_section( + 'section_account', + [ + 'label' => esc_html__( 'Pricing & Payments', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'merchant_account', + [ + 'label' => esc_html__( 'Merchant Account', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => self::API_TYPE_SIMPLE, + 'options' => [ + self::API_TYPE_SIMPLE => esc_html__( 'Default (Simple)', 'elementor-pro' ), + self::API_TYPE_ADVANCED => esc_html__( 'Custom (Advanced)', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'email', + [ + 'label' => esc_html__( 'PayPal Account', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'description' => esc_html__( 'Transactions made through your PayPal button will be registered under this account.', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'merchant_account' => self::API_TYPE_SIMPLE, + ], + 'placeholder' => 'yours@email.com', + ] + ); + + $this->add_control( + 'sdk_token', + [ + 'label' => esc_html__( 'SDK Token', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'condition' => [ + 'merchant_account' => self::API_TYPE_ADVANCED, + ], + ] + ); + + $this->register_product_controls(); + + $this->end_controls_section(); + } + + /** + * Updates Button tab controls in 'Style' tab + * + * @since 3.7.0 + */ + public function register_paypal_button_controls() { + parent::register_controls(); + + $this->update_control( 'selected_icon', [ + 'default' => [ + 'value' => 'fab fa-paypal', + 'library' => 'fa-brands', + ], + ] ); + + $this->update_control( 'background_color', [ + 'default' => '#032E82', + ] ); + } + + /** + * Edit button control initial UI + * + * @since 3.7.0 + * + */ + protected function register_controls() { + $this->register_paypal_button_controls(); + } + + // Custom sandbox controls. + protected function register_sandbox_controls() { + $this->add_control( + 'sandbox_email', + [ + 'label' => esc_html__( 'Sandbox Email Account', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'description' => esc_html__( 'This is the address given to you by PayPal when you set up a sandbox with your developer account. You can use the sandbox to test your purchase flow.', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'sandbox_mode' => 'yes', + ], + ] + ); + } +} diff --git a/modules/payments/widgets/stripe-button.php b/modules/payments/widgets/stripe-button.php new file mode 100644 index 00000000..bbfa44a5 --- /dev/null +++ b/modules/payments/widgets/stripe-button.php @@ -0,0 +1,538 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Stripe currency supported list + * + * @since 3.7.0 + * + * @return array + */ + protected function get_stripe_currencies() { + return [ + 'AED' => _x( 'AED', 'Currency', 'elementor-pro' ), + 'AFN' => _x( 'AFN', 'Currency', 'elementor-pro' ), + 'ALL' => _x( 'ALL', 'Currency', 'elementor-pro' ), + 'AMD' => _x( 'AMD', 'Currency', 'elementor-pro' ), + 'ANG' => _x( 'ANG', 'Currency', 'elementor-pro' ), + 'AOA' => _x( 'AOA', 'Currency', 'elementor-pro' ), + 'ARS' => _x( 'ARS', 'Currency', 'elementor-pro' ), + 'AUD' => _x( 'AUD', 'Currency', 'elementor-pro' ), + 'AWG' => _x( 'AWG', 'Currency', 'elementor-pro' ), + 'AZN' => _x( 'AZN', 'Currency', 'elementor-pro' ), + 'BAM' => _x( 'BAM', 'Currency', 'elementor-pro' ), + 'BBD' => _x( 'BBD', 'Currency', 'elementor-pro' ), + 'BDT' => _x( 'BDT', 'Currency', 'elementor-pro' ), + 'BGN' => _x( 'BGN', 'Currency', 'elementor-pro' ), + 'BIF' => _x( 'BIF', 'Currency', 'elementor-pro' ), + 'BMD' => _x( 'BMD', 'Currency', 'elementor-pro' ), + 'BND' => _x( 'BND', 'Currency', 'elementor-pro' ), + 'BOB' => _x( 'BOB', 'Currency', 'elementor-pro' ), + 'BRL' => _x( 'BRL', 'Currency', 'elementor-pro' ), + 'BSD' => _x( 'BSD', 'Currency', 'elementor-pro' ), + 'BWP' => _x( 'BWP', 'Currency', 'elementor-pro' ), + 'BYN' => _x( 'BYN', 'Currency', 'elementor-pro' ), + 'BZD' => _x( 'BZD', 'Currency', 'elementor-pro' ), + 'CAD' => _x( 'CAD', 'Currency', 'elementor-pro' ), + 'CDF' => _x( 'CDF', 'Currency', 'elementor-pro' ), + 'CHF' => _x( 'CHF', 'Currency', 'elementor-pro' ), + 'CLP' => _x( 'CLP', 'Currency', 'elementor-pro' ), + 'CNY' => _x( 'CNY', 'Currency', 'elementor-pro' ), + 'COP' => _x( 'COP', 'Currency', 'elementor-pro' ), + 'CRC' => _x( 'CRC', 'Currency', 'elementor-pro' ), + 'CVE' => _x( 'CVE', 'Currency', 'elementor-pro' ), + 'CZK' => _x( 'CZK', 'Currency', 'elementor-pro' ), + 'DJF' => _x( 'DJF', 'Currency', 'elementor-pro' ), + 'DKK' => _x( 'DKK', 'Currency', 'elementor-pro' ), + 'DOP' => _x( 'DOP', 'Currency', 'elementor-pro' ), + 'DZD' => _x( 'DZD', 'Currency', 'elementor-pro' ), + 'EGP' => _x( 'EGP', 'Currency', 'elementor-pro' ), + 'ETB' => _x( 'ETB', 'Currency', 'elementor-pro' ), + 'EUR' => _x( 'EUR', 'Currency', 'elementor-pro' ), + 'FJD' => _x( 'FJD', 'Currency', 'elementor-pro' ), + 'FKP' => _x( 'FKP', 'Currency', 'elementor-pro' ), + 'GBP' => _x( 'GBP', 'Currency', 'elementor-pro' ), + 'GEL' => _x( 'GEL', 'Currency', 'elementor-pro' ), + 'GIP' => _x( 'GIP', 'Currency', 'elementor-pro' ), + 'GMD' => _x( 'GMD', 'Currency', 'elementor-pro' ), + 'GNF' => _x( 'GNF', 'Currency', 'elementor-pro' ), + 'GTQ' => _x( 'GTQ', 'Currency', 'elementor-pro' ), + 'GYD' => _x( 'GYD', 'Currency', 'elementor-pro' ), + 'HKD' => _x( 'HKD', 'Currency', 'elementor-pro' ), + 'HNL' => _x( 'HNL', 'Currency', 'elementor-pro' ), + 'HRK' => _x( 'HRK', 'Currency', 'elementor-pro' ), + 'HTG' => _x( 'HTG', 'Currency', 'elementor-pro' ), + 'IDR' => _x( 'IDR', 'Currency', 'elementor-pro' ), + 'ILS' => _x( 'ILS', 'Currency', 'elementor-pro' ), + 'INR' => _x( 'INR', 'Currency', 'elementor-pro' ), + 'ISK' => _x( 'ISK', 'Currency', 'elementor-pro' ), + 'JMD' => _x( 'JMD', 'Currency', 'elementor-pro' ), + 'JPY' => _x( 'JPY', 'Currency', 'elementor-pro' ), + 'KES' => _x( 'KES', 'Currency', 'elementor-pro' ), + 'KGS' => _x( 'KGS', 'Currency', 'elementor-pro' ), + 'KHR' => _x( 'KHR', 'Currency', 'elementor-pro' ), + 'KMF' => _x( 'KMF', 'Currency', 'elementor-pro' ), + 'KRW' => _x( 'KRW', 'Currency', 'elementor-pro' ), + 'KYD' => _x( 'KYD', 'Currency', 'elementor-pro' ), + 'KZT' => _x( 'KZT', 'Currency', 'elementor-pro' ), + 'LAK' => _x( 'LAK', 'Currency', 'elementor-pro' ), + 'LBP' => _x( 'LBP', 'Currency', 'elementor-pro' ), + 'LKR' => _x( 'LKR', 'Currency', 'elementor-pro' ), + 'LRD' => _x( 'LRD', 'Currency', 'elementor-pro' ), + 'LSL' => _x( 'LSL', 'Currency', 'elementor-pro' ), + 'MAD' => _x( 'MAD', 'Currency', 'elementor-pro' ), + 'MDL' => _x( 'MDL', 'Currency', 'elementor-pro' ), + 'MGA' => _x( 'MGA', 'Currency', 'elementor-pro' ), + 'MKD' => _x( 'MKD', 'Currency', 'elementor-pro' ), + 'MMK' => _x( 'MMK', 'Currency', 'elementor-pro' ), + 'MNT' => _x( 'MNT', 'Currency', 'elementor-pro' ), + 'MOP' => _x( 'MOP', 'Currency', 'elementor-pro' ), + 'MRO' => _x( 'MRO', 'Currency', 'elementor-pro' ), + 'MUR' => _x( 'MUR', 'Currency', 'elementor-pro' ), + 'MVR' => _x( 'MVR', 'Currency', 'elementor-pro' ), + 'MWK' => _x( 'MWK', 'Currency', 'elementor-pro' ), + 'MXN' => _x( 'MXN', 'Currency', 'elementor-pro' ), + 'MYR' => _x( 'MYR', 'Currency', 'elementor-pro' ), + 'MZN' => _x( 'MZN', 'Currency', 'elementor-pro' ), + 'NAD' => _x( 'NAD', 'Currency', 'elementor-pro' ), + 'NGN' => _x( 'NGN', 'Currency', 'elementor-pro' ), + 'NIO' => _x( 'NIO', 'Currency', 'elementor-pro' ), + 'NOK' => _x( 'NOK', 'Currency', 'elementor-pro' ), + 'NPR' => _x( 'NPR', 'Currency', 'elementor-pro' ), + 'NZD' => _x( 'NZD', 'Currency', 'elementor-pro' ), + 'PAB' => _x( 'PAB', 'Currency', 'elementor-pro' ), + 'PEN' => _x( 'PEN', 'Currency', 'elementor-pro' ), + 'PGK' => _x( 'PGK', 'Currency', 'elementor-pro' ), + 'PHP' => _x( 'PHP', 'Currency', 'elementor-pro' ), + 'PKR' => _x( 'PKR', 'Currency', 'elementor-pro' ), + 'PLN' => _x( 'PLN', 'Currency', 'elementor-pro' ), + 'PYG' => _x( 'PYG', 'Currency', 'elementor-pro' ), + 'QAR' => _x( 'QAR', 'Currency', 'elementor-pro' ), + 'RON' => _x( 'RON', 'Currency', 'elementor-pro' ), + 'RSD' => _x( 'RSD', 'Currency', 'elementor-pro' ), + 'RUB' => _x( 'RUB', 'Currency', 'elementor-pro' ), + 'RWF' => _x( 'RWF', 'Currency', 'elementor-pro' ), + 'SAR' => _x( 'SAR', 'Currency', 'elementor-pro' ), + 'SBD' => _x( 'SBD', 'Currency', 'elementor-pro' ), + 'SCR' => _x( 'SCR', 'Currency', 'elementor-pro' ), + 'SEK' => _x( 'SEK', 'Currency', 'elementor-pro' ), + 'SGD' => _x( 'SGD', 'Currency', 'elementor-pro' ), + 'SHP' => _x( 'SHP', 'Currency', 'elementor-pro' ), + 'SLL' => _x( 'SLL', 'Currency', 'elementor-pro' ), + 'SOS' => _x( 'SOS', 'Currency', 'elementor-pro' ), + 'SRD' => _x( 'SRD', 'Currency', 'elementor-pro' ), + 'STD' => _x( 'STD', 'Currency', 'elementor-pro' ), + 'SZL' => _x( 'SZL', 'Currency', 'elementor-pro' ), + 'THB' => _x( 'THB', 'Currency', 'elementor-pro' ), + 'TJS' => _x( 'TJS', 'Currency', 'elementor-pro' ), + 'TOP' => _x( 'TOP', 'Currency', 'elementor-pro' ), + 'TRY' => _x( 'TRY', 'Currency', 'elementor-pro' ), + 'TTD' => _x( 'TTD', 'Currency', 'elementor-pro' ), + 'TWD' => _x( 'TWD', 'Currency', 'elementor-pro' ), + 'TZS' => _x( 'TZS', 'Currency', 'elementor-pro' ), + 'UAH' => _x( 'UAH', 'Currency', 'elementor-pro' ), + 'UYU' => _x( 'UYU', 'Currency', 'elementor-pro' ), + 'UZS' => _x( 'UZS', 'Currency', 'elementor-pro' ), + 'VND' => _x( 'VND', 'Currency', 'elementor-pro' ), + 'VUV' => _x( 'VUV', 'Currency', 'elementor-pro' ), + 'WST' => _x( 'WST', 'Currency', 'elementor-pro' ), + 'XAF' => _x( 'XAF', 'Currency', 'elementor-pro' ), + 'XCD' => _x( 'XCD', 'Currency', 'elementor-pro' ), + 'XOF' => _x( 'XOF', 'Currency', 'elementor-pro' ), + 'XPF' => _x( 'XPF', 'Currency', 'elementor-pro' ), + 'YER' => _x( 'YER', 'Currency', 'elementor-pro' ), + 'ZAR' => _x( 'ZAR', 'Currency', 'elementor-pro' ), + 'ZMW' => _x( 'ZMW', 'Currency', 'elementor-pro' ), + 'USD' => _x( 'USD', 'Currency', 'elementor-pro' ), + ]; + } + + /** + * Global error message. + * + * @since 3.7.0 + * + * @return string + */ + protected function stripe_global_error_massage() { + return esc_html__( 'Something went wrong', 'elementor-pro' ); + } + + /** + * Gateway error message. + * + * @since 3.7.0 + * + * @return string + */ + protected function stripe_gateway_error_massage() { + return esc_html__( 'Gateway not connected. Contact seller', 'elementor-pro' ); + } + + /** + * Get validation errors. + * + * @since 3.7.0 + * + * @return array + */ + protected function get_errors() { + $settings = $this->get_settings_for_display(); + $errors = []; + + if ( empty( $settings['product_name'] ) || empty( $settings['stripe_product_price'] ) ) { + $errors[ self::ERROR_MESSAGE_GLOBAL ] = $this->get_custom_message( self::ERROR_MESSAGE_GLOBAL ); + } + + return $errors; + } + + /** + * Render the payment button. + * + * @param string $tag - this is an inheritance from the payment_button class + * + * @since 3.7.0 + * + * @return array + */ + protected function render_button( ?Widget_Base $instance = null, $tag = 'a' ) { + $settings = $this->get_settings_for_display(); + ?> + +
      + + + + + + + + + + add_render_attribute( 'input', 'type', 'submit' ); + $this->add_render_attribute( 'input', 'class', 'elementor-stripe' ); + parent::render_button( null, 'button' ); + + foreach ( $this->get_errors() as $type => $message ) { + ?> +
      + +
      + +
      + start_controls_section( + 'section_stripe_account', + [ + 'label' => esc_html__( 'Pricing & Payments', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'test_environment_msg', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + /* translators: 1: Elementor's integrations settings link opening tab, 2: Link closing tag. */ + esc_html__( 'For this widget to work, you need to set your Stripe API keys in the %1$sIntegrations Settings%2$s.', 'elementor-pro' ), + sprintf( '', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ), + 'separator' => 'after', + ] + ); + + $this->register_product_controls(); + + $this->remove_control( 'type' ); + + $this->update_control( + 'type', + [ + 'default' => self::STRIPE_PAYMENT_TYPE_CHECKOUT, + 'options' => [ + self::STRIPE_PAYMENT_TYPE_CHECKOUT => esc_html__( 'Checkout', 'elementor-pro' ), + ], + ] + ); + + $this->update_control( + 'product_name', + [ + 'label' => esc_html__( 'Product Name', 'elementor-pro' ), + 'required' => true, + ] + ); + + $this->add_control( + 'stripe_currency', + [ + 'label' => esc_html__( 'Currency', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_stripe_currencies(), + 'frontend_available' => true, + 'multiple' => false, + 'default' => 'USD', + 'description' => sprintf( + /* translators: 1: Stripe api key explanation link opening tag, 2: Link closing tag. */ + esc_html__( 'Notice! Please make sure to meet Stripe\'s guidelines regarding minimum charge amounts. %1$s Learn more. %2$s', 'elementor-pro' ), + sprintf( '', Module::STRIPE_TRANSACTIONS_LINK ), + '' + ), + 'render_type' => 'none', + 'required' => true, + 'select2options' => [ + 'placeholder' => esc_html__( 'USD', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'stripe_product_price', + [ + 'label' => esc_html__( 'Product Price', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '0.00', + 'dynamic' => [ + 'active' => true, + ], + 'min' => 0, + ] + ); + + $this->remove_control( 'product_price' ); + + $this->remove_control( 'currency' ); + + $this->remove_control( 'billing_cycle' ); + + $this->remove_control( 'auto_renewal' ); + + $this->remove_control( 'product_sku' ); + + $this->remove_control( 'quantity' ); + + $this->add_control( + 'stripe_quantity', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 1, + ] + ); + + $this->remove_control( 'tax_type' ); + + $this->add_control( + 'shipping_amount', + [ + 'label' => esc_html__( 'Shipping Price', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'dynamic' => [ + 'active' => true, + ], + 'min' => 0, + ] + ); + + $this->add_control( + 'stripe_test_env_tax_rates_list', + [ + 'label' => esc_html__( 'Tax Rate', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ '' => esc_html__( 'None', 'elementor-pro' ) ], + 'condition' => [ + 'sandbox_mode[value]' => 'yes', + ], + 'description' => esc_html__( 'To manage these options, go to your Stripe account > Products > Tax Rates.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'stripe_live_env_tax_rates_list', + [ + 'label' => esc_html__( 'Tax Rate', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ '' => esc_html__( 'None', 'elementor-pro' ) ], + 'condition' => [ + 'sandbox_mode[value]!' => 'yes', + ], + 'description' => esc_html__( 'To manage these options, go to your Stripe account > Products > Tax Rates.', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + } + /** + * Updates Button tab controls in 'Style' tab + * + * @since 3.7.0 + */ + public function register_stripe_button_controls() { + parent::register_controls(); + + $this->update_control( 'selected_icon', [ + 'default' => [ + 'value' => 'fab fa-stripe-s', + 'library' => 'fa-brands', + ], + 'recommended' => [ + 'fa-brands' => [ + 'stripe-s', + 'stripe', + 'cc-stripe', + ], + ], + ] ); + + $this->update_control( 'background_color', [ + 'default' => '#635bff', + ] ); + } + + /** + * Edit button control initial UI + * + * @since 3.7.0 + * + */ + protected function register_controls() { + $this->register_stripe_button_controls(); + } + + /** + * Update error messages controls text and placeholders. + * + * @since 3.7.0 + * + */ + protected function update_error_massages() { + $this->update_control( + 'error_message_' . self::ERROR_MESSAGE_GLOBAL, + [ + 'placeholder' => $this->stripe_global_error_massage(), + 'default' => $this->stripe_global_error_massage(), + ] + ); + + $this->update_control( + 'error_message_' . self::ERROR_MESSAGE_PAYMENT_METHOD, + [ + 'placeholder' => $this->stripe_gateway_error_massage(), + 'default' => $this->stripe_gateway_error_massage(), + ] + ); + } + + /** + * Custom sandbox controls. + * + * @since 3.7.0 + * + */ + protected function after_custom_messages_toggle() { + $this->add_control( + 'custom_error_on_notice', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'These messages override Stripe\'s error messages.', 'elementor-pro' ) . '
      ' . esc_html__( 'Use them on your live site - not while testing.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'custom_messages!' => '', + ], + ] + ); + } + + protected function register_sandbox_controls() { + $this->update_control( 'sandbox_mode', + [ + 'label' => esc_html__( 'Stripe test environment', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'sandbox_mode_on_notice', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => sprintf( + /* translators: 1: Elementor's integrations settings link opening tab, 2: Link closing tag. */ + esc_html__( 'Complete the entire checkout experience on your site with a mock payment method, using the Stripe Test key in the %1$sIntegrations Settings%2$s.', 'elementor-pro' ), + sprintf( '', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'sandbox_mode' => 'yes', + ], + ] + ); + + $this->remove_control( 'sandbox_email' ); + } +} diff --git a/modules/popup/admin-menu-items/popups-menu-item.php b/modules/popup/admin-menu-items/popups-menu-item.php new file mode 100644 index 00000000..ba58a010 --- /dev/null +++ b/modules/popup/admin-menu-items/popups-menu-item.php @@ -0,0 +1,32 @@ +license_admin->get_connect_url( [ + 'utm_source' => 'popup-templates', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + ] ); + + $renew_url = 'https://go.elementor.com/renew-popups/'; + + return API::is_license_expired() + ? $renew_url + : $connect_url; + } + + public function get_parent_slug() { + return Source_Local::ADMIN_MENU_SLUG; + } + + public function get_label() { + return esc_html__( 'Popups', 'elementor-pro' ); + } + + public function get_page_title() { + return esc_html__( 'Popups', 'elementor-pro' ); + } + + public function get_promotion_title() { + return esc_html__( 'Get Popup Builder', 'elementor-pro' ); + } + + public function get_promotion_description() { + return esc_html__( + "Create custom designed Popups. Use advanced display conditions and triggers to display the right popup, to the right visitor, at the right time and maximize conversions.", + 'elementor-pro' + ); + } + + /** + * @deprecated use get_promotion_description instead + * @return void + */ + public function render_promotion_description() { + echo $this->get_promotion_description(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/popup/assets/images/timing-tab.svg b/modules/popup/assets/images/timing-tab.svg new file mode 100644 index 00000000..dc25b6dd --- /dev/null +++ b/modules/popup/assets/images/timing-tab.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/modules/popup/assets/images/timing/browsers.svg b/modules/popup/assets/images/timing/browsers.svg new file mode 100644 index 00000000..1b5b88d4 --- /dev/null +++ b/modules/popup/assets/images/timing/browsers.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/devices.svg b/modules/popup/assets/images/timing/devices.svg new file mode 100644 index 00000000..21d002ef --- /dev/null +++ b/modules/popup/assets/images/timing/devices.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/logged_in.svg b/modules/popup/assets/images/timing/logged_in.svg new file mode 100644 index 00000000..47bf01eb --- /dev/null +++ b/modules/popup/assets/images/timing/logged_in.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/page_views.svg b/modules/popup/assets/images/timing/page_views.svg new file mode 100644 index 00000000..565ee7e9 --- /dev/null +++ b/modules/popup/assets/images/timing/page_views.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/schedule.svg b/modules/popup/assets/images/timing/schedule.svg new file mode 100644 index 00000000..75d5fbe8 --- /dev/null +++ b/modules/popup/assets/images/timing/schedule.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/sessions.svg b/modules/popup/assets/images/timing/sessions.svg new file mode 100644 index 00000000..63a5bc0d --- /dev/null +++ b/modules/popup/assets/images/timing/sessions.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/sources.svg b/modules/popup/assets/images/timing/sources.svg new file mode 100644 index 00000000..7ff097fe --- /dev/null +++ b/modules/popup/assets/images/timing/sources.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/times.svg b/modules/popup/assets/images/timing/times.svg new file mode 100644 index 00000000..704c75ce --- /dev/null +++ b/modules/popup/assets/images/timing/times.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/popup/assets/images/timing/url.svg b/modules/popup/assets/images/timing/url.svg new file mode 100644 index 00000000..ed52ff27 --- /dev/null +++ b/modules/popup/assets/images/timing/url.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/triggers-tab.svg b/modules/popup/assets/images/triggers-tab.svg new file mode 100644 index 00000000..0a23f2ab --- /dev/null +++ b/modules/popup/assets/images/triggers-tab.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/adblock_detection.svg b/modules/popup/assets/images/triggers/adblock_detection.svg new file mode 100644 index 00000000..d6342a18 --- /dev/null +++ b/modules/popup/assets/images/triggers/adblock_detection.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/click.svg b/modules/popup/assets/images/triggers/click.svg new file mode 100644 index 00000000..67ea5aac --- /dev/null +++ b/modules/popup/assets/images/triggers/click.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/exit_intent.svg b/modules/popup/assets/images/triggers/exit_intent.svg new file mode 100644 index 00000000..5f161ac4 --- /dev/null +++ b/modules/popup/assets/images/triggers/exit_intent.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/inactivity.svg b/modules/popup/assets/images/triggers/inactivity.svg new file mode 100644 index 00000000..7cf15f88 --- /dev/null +++ b/modules/popup/assets/images/triggers/inactivity.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/page_load.svg b/modules/popup/assets/images/triggers/page_load.svg new file mode 100644 index 00000000..edf92ba0 --- /dev/null +++ b/modules/popup/assets/images/triggers/page_load.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/modules/popup/assets/images/triggers/scrolling.svg b/modules/popup/assets/images/triggers/scrolling.svg new file mode 100644 index 00000000..b399768b --- /dev/null +++ b/modules/popup/assets/images/triggers/scrolling.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/modules/popup/assets/images/triggers/scrolling_to.svg b/modules/popup/assets/images/triggers/scrolling_to.svg new file mode 100644 index 00000000..5c405efd --- /dev/null +++ b/modules/popup/assets/images/triggers/scrolling_to.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/popup/display-settings/base.php b/modules/popup/display-settings/base.php new file mode 100644 index 00000000..62a35863 --- /dev/null +++ b/modules/popup/display-settings/base.php @@ -0,0 +1,62 @@ +current_group = $group_name; + + $args = [ + 'type' => Controls_Manager::HEADING, + 'label' => $group_title, + ]; + + $this->add_control( $group_name . '_heading', $args ); + } + + protected function end_settings_group() { + $this->add_control( + $this->current_group, + [ + 'type' => Controls_Manager::SWITCHER, + 'classes' => 'elementor-popup__display-settings__group-toggle', + 'frontend_available' => true, + ] + ); + + $this->current_group = null; + } + + protected function add_settings_group_control( $id, array $args ) { + $id = $this->get_prefixed_control_id( $id ); + + $args['frontend_available'] = true; + + if ( ! empty( $args['condition'] ) ) { + $args['condition'] = array_combine( + array_map( function( $key ) { + return $this->current_group . '_' . $key; + }, array_keys( $args['condition'] ) ), + $args['condition'] + ); + } + + $args['condition'][ $this->current_group ] = 'yes'; + + return $this->add_control( $id, $args ); + } + + protected function get_prefixed_control_id( $id ) { + return $this->current_group . '_' . $id; + } +} diff --git a/modules/popup/display-settings/timing.php b/modules/popup/display-settings/timing.php new file mode 100644 index 00000000..c4229bc1 --- /dev/null +++ b/modules/popup/display-settings/timing.php @@ -0,0 +1,310 @@ +start_controls_section( 'timing' ); + + $this->start_settings_group( 'page_views', esc_html__( 'Show after X page views', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'views', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Page Views', 'elementor-pro' ), + 'default' => 3, + 'min' => 1, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'sessions', esc_html__( 'Show after X sessions', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'sessions', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Sessions', 'elementor-pro' ), + 'default' => 2, + 'min' => 1, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'times', esc_html__( 'Show up to X times', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'times', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Times', 'elementor-pro' ), + 'default' => 3, + 'min' => 1, + ] + ); + + $this->add_settings_group_control( + 'period', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Per', 'elementor-pro' ), + 'default' => '', // Backward Compatibility - Persisting is old default value. + 'options' => [ + '' => esc_html__( 'Persisting', 'elementor-pro' ), + 'session' => esc_html__( 'Session', 'elementor-pro' ), + 'day' => esc_html__( 'Day', 'elementor-pro' ), + 'week' => esc_html__( 'Week', 'elementor-pro' ), + 'month' => esc_html__( 'Month', 'elementor-pro' ), + ], + ] + ); + + $this->add_settings_group_control( + 'count', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Count', 'elementor-pro' ), + 'options' => [ + '' => esc_html__( 'On Open', 'elementor-pro' ), + 'close' => esc_html__( 'On Close', 'elementor-pro' ), + ], + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'url', esc_html__( 'When arriving from specific URL', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'action', + [ + 'type' => Controls_Manager::SELECT, + 'default' => 'show', + 'options' => [ + 'show' => esc_html__( 'Show', 'elementor-pro' ), + 'hide' => esc_html__( 'Hide', 'elementor-pro' ), + 'regex' => esc_html__( 'Regex', 'elementor-pro' ), + ], + ] + ); + + $this->add_settings_group_control( + 'url', + [ + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'URL', 'elementor-pro' ), + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'sources', esc_html__( 'Show when arriving from', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'sources', + [ + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'default' => [ 'search', 'external', 'internal' ], + 'options' => [ + 'search' => esc_html__( 'Search Engines', 'elementor-pro' ), + 'external' => esc_html__( 'External Links', 'elementor-pro' ), + 'internal' => esc_html__( 'Internal Links', 'elementor-pro' ), + ], + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'logged_in', esc_html__( 'Hide for logged in users', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'users', + [ + 'type' => Controls_Manager::SELECT, + 'default' => 'all', + 'options' => [ + 'all' => esc_html__( 'All Users', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + ] + ); + + global $wp_roles; + + $roles = array_map( function( $role ) { + return $role['name']; + }, $wp_roles->roles ); + + $this->add_settings_group_control( + 'roles', + [ + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'default' => [], + 'options' => $roles, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select Roles', 'elementor-pro' ), + ], + 'condition' => [ + 'users' => 'custom', + ], + ] + ); + + $this->end_settings_group(); + + $available_devices = [ + 'desktop' => esc_html__( 'Desktop', 'elementor-pro' ), + ]; + + $default_devices = [ 'desktop' ]; + + $active_breakpoints = Plugin::elementor()->breakpoints->get_active_breakpoints(); + + foreach ( $active_breakpoints as $breakpoint_key => $breakpoint ) { + $available_devices[ $breakpoint_key ] = $breakpoint->get_label(); + $default_devices[] = $breakpoint_key; + } + + $this->start_settings_group( 'devices', esc_html__( 'Show on devices', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'devices', + [ + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'default' => $default_devices, + 'options' => $available_devices, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'browsers', esc_html__( 'Show on browsers', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'browsers', + [ + 'type' => Controls_Manager::SELECT, + 'default' => 'all', + 'options' => [ + 'all' => esc_html__( 'All Browsers', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + ] + ); + + $this->add_settings_group_control( + 'browsers_options', + [ + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'default' => [], + 'options' => [ + 'ie' => esc_html__( 'Internet Explorer', 'elementor-pro' ), + 'chrome' => esc_html__( 'Chrome', 'elementor-pro' ), + 'edge' => esc_html__( 'Edge', 'elementor-pro' ), + 'firefox' => esc_html__( 'Firefox', 'elementor-pro' ), + 'safari' => esc_html__( 'Safari', 'elementor-pro' ), + ], + 'condition' => [ + 'browsers' => 'custom', + ], + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'schedule', esc_html__( 'Schedule date and time', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'timezone', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Timezone', 'elementor-pro' ), + 'default' => 'site', + 'options' => [ + 'site' => esc_html__( 'Site', 'elementor-pro' ), + 'visitor' => esc_html__( 'Visitor', 'elementor-pro' ), + ], + ] + ); + + $this->add_settings_group_control( + 'start_date', + [ + 'label' => esc_html__( 'Start', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'picker_options' => [ + 'enableTime' => true, + 'minDate' => 'today', + ], + 'validation' => [ + 'date_time' => [ + 'control_name' => $this->get_prefixed_control_id( 'end_date' ), + 'operator' => '<=', + ], + ], + ] + ); + + $this->add_settings_group_control( + 'end_date', + [ + 'label' => esc_html__( 'End', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'picker_options' => [ + 'enableTime' => true, + 'minDate' => 'today', + ], + 'validation' => [ + 'date_time' => [ + 'control_name' => $this->get_prefixed_control_id( 'start_date' ), + 'operator' => '>=', + ], + ], + ] + ); + + $datetime = new \DateTime( 'now', new \DateTimeZone( wp_timezone_string() ) ); + $datetime = $datetime->format( 'Y-m-d H:i:s' ); + + $this->add_settings_group_control( + 'server_datetime', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => $datetime, + ] + ); + + $this->end_settings_group(); + + $this->end_controls_section(); + } +} diff --git a/modules/popup/display-settings/triggers.php b/modules/popup/display-settings/triggers.php new file mode 100644 index 00000000..d8ca6b2d --- /dev/null +++ b/modules/popup/display-settings/triggers.php @@ -0,0 +1,200 @@ +start_controls_section( 'triggers' ); + + $this->maybe_add_send_app_promotion_control(); + + $this->start_settings_group( 'page_load', esc_html__( 'On Page Load', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'delay', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Within', 'elementor-pro' ) . ' (sec)', + 'default' => 0, + 'min' => 0, + 'step' => 0.1, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'scrolling', esc_html__( 'On Scroll', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'direction', + [ + 'type' => Controls_Manager::SELECT, + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'default' => 'down', + 'options' => [ + 'down' => esc_html__( 'Down', 'elementor-pro' ), + 'up' => esc_html__( 'Up', 'elementor-pro' ), + ], + ] + ); + + $this->add_settings_group_control( + 'offset', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Within', 'elementor-pro' ) . ' (%)', + 'default' => 50, + 'min' => 1, + 'max' => 100, + 'condition' => [ + 'direction' => 'down', + ], + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'scrolling_to', esc_html__( 'On Scroll To Element', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'selector', + [ + 'type' => Controls_Manager::TEXT, + 'label' => esc_html__( 'Selector', 'elementor-pro' ), + 'placeholder' => '.my-class', + 'ai' => [ + 'active' => false, + ], + ], + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'click', esc_html__( 'On Click', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'times', + [ + 'label' => esc_html__( 'Clicks', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 1, + 'min' => 1, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'inactivity', esc_html__( 'After Inactivity', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'time', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Within', 'elementor-pro' ) . ' (sec)', + 'default' => 30, + 'min' => 1, + 'step' => 0.1, + ] + ); + + $this->end_settings_group(); + + $this->start_settings_group( 'exit_intent', esc_html__( 'On Page Exit Intent', 'elementor-pro' ) ); + + $this->end_settings_group(); + + $this->start_settings_group( 'adblock_detection', esc_html__( 'AdBlock Detection', 'elementor-pro' ) ); + + $this->add_settings_group_control( + 'delay', + [ + 'type' => Controls_Manager::NUMBER, + 'label' => esc_html__( 'Within', 'elementor-pro' ) . ' (sec)', + 'default' => 0, + 'min' => 0, + 'step' => 0.1, + ] + ); + + $this->end_settings_group(); + + $this->end_controls_section(); + } + + private function get_send_app_notice_template( $notice_id, $notice_content ): string { + if ( Hints::is_dismissed( $notice_id ) ) { + return ''; + } + + $action_url = Hints::get_plugin_action_url( 'send-app' ); + $button_data = wp_json_encode( [ 'action_url' => $action_url ] ); + + return '
      +
      + + + +
      +
      +
      ' . $notice_content . '
      +
      + +
      +
      + +
      '; + } + + private function maybe_add_send_app_promotion_control(): void { + if ( Hints::is_plugin_installed( 'send-app' ) ) { + return; + } + + $notice_id = 'send_app_forms_triggers_notice'; + if ( ! Hints::should_show_hint( $notice_id ) ) { + return; + } + + $notice_content = wp_kses( + __( 'Turn popup clicks into sales with Send. Trigger automated emails the moment visitors engage.', 'elementor-pro' ), + [ + 'br' => [], + 'strong' => [], + ] + ); + + $this->add_control( + 'send_app_promo', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => $this->get_send_app_notice_template( $notice_id, $notice_content ), + ] + ); + } +} diff --git a/modules/popup/document.php b/modules/popup/document.php new file mode 100644 index 00000000..0fd7cb49 --- /dev/null +++ b/modules/popup/document.php @@ -0,0 +1,865 @@ +display_settings ) { + $settings = $this->get_display_settings_data(); + + if ( ! $settings ) { + $settings = [ + 'triggers' => [], + 'timing' => [], + ]; + } + + $id = $this->get_main_id(); + + $this->display_settings = [ + 'triggers' => new Triggers( [ + 'id' => $id, + 'settings' => $settings['triggers'], + ] ), + 'timing' => new Timing( [ + 'id' => $id, + 'settings' => $settings['timing'], + ] ), + ]; + } + + return $this->display_settings; + } + + public function get_initial_config() { + $config = parent::get_initial_config(); + + $display_settings = $this->get_display_settings(); + + $config['displaySettings'] = [ + 'triggers' => [ + 'controls' => $display_settings['triggers']->get_controls(), + 'settings' => $display_settings['triggers']->get_settings(), + ], + 'timing' => [ + 'controls' => $display_settings['timing']->get_controls(), + 'settings' => $display_settings['timing']->get_settings(), + ], + ]; + + $config['container'] = '.elementor-popup-modal .dialog-widget-content'; + + return $config; + } + + public function get_name() { + return 'popup'; + } + + public function get_css_wrapper_selector() { + return '#elementor-popup-modal-' . $this->get_main_id(); + } + + public function get_display_settings_data() { + return $this->get_main_meta( self::DISPLAY_SETTINGS_META_KEY ); + } + + public function save_display_settings_data( $display_settings_data ) { + $this->update_main_meta( self::DISPLAY_SETTINGS_META_KEY, $display_settings_data ); + } + + public function get_frontend_settings() { + $settings = parent::get_frontend_settings(); + + $display_settings = $this->get_display_settings(); + + // Disable triggers if the popup is not printed by the theme builder conditions. + // avoid auto show the popup if it's enqueued by a dynamic tag and etc.) + $popups_by_condition = ThemeBuilderModule::instance()->get_conditions_manager()->get_documents_for_location( 'popup' ); + + if ( $popups_by_condition && isset( $popups_by_condition[ $this->get_main_id() ] ) ) { + $settings['triggers'] = $display_settings['triggers']->get_frontend_settings(); + } + + $settings['timing'] = $display_settings['timing']->get_frontend_settings(); + + return $settings; + } + + public function get_export_data() { + $data = parent::get_export_data(); + + $display_settings = $this->get_display_settings(); + + $data['display_settings'] = [ + 'triggers' => $display_settings['triggers']->get_frontend_settings(), + 'timing' => $display_settings['timing']->get_frontend_settings(), + ]; + + return $data; + } + + public function import( array $data ) { + parent::import( $data ); + + $this->save_display_settings_data( $data['display_settings'] ); + } + + protected function register_controls() { + $this->start_controls_section( + 'popup_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_SETTINGS, + ] + ); + + $this->add_control( + 'assets_loading_hidden_control', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => 'hidden', + 'assets' => [ + 'styles' => [ + [ + 'name' => 'e-popup', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], // Only CSS `` data-type is allowed, not ``. + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'em' => [ + 'min' => 10, + 'max' => 100, + ], + 'rem' => [ + 'min' => 10, + 'max' => 100, + ], + 'vh' => [ + 'min' => 10, + 'max' => 100, + ], + ], + 'default' => [ + 'size' => 640, + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-message' => 'width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'height_type', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'auto', + 'options' => [ + 'auto' => esc_html__( 'Fit To Content', 'elementor-pro' ), + 'fit_to_screen' => esc_html__( 'Fit To Screen', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'selectors_dictionary' => [ + 'fit_to_screen' => '100vh', + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-message' => 'height: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'height', + [ + 'label' => esc_html__( 'Custom Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'vh' => [ + 'min' => 10, + 'max' => 100, + ], + ], + 'condition' => [ + 'height_type' => 'custom', + ], + 'default' => [ + 'size' => 380, + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-message' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'content_position', + [ + 'label' => esc_html__( 'Content Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'top', + 'options' => [ + 'top' => esc_html__( 'Top', 'elementor-pro' ), + 'center' => esc_html__( 'Center', 'elementor-pro' ), + 'bottom' => esc_html__( 'Bottom', 'elementor-pro' ), + ], + 'condition' => [ + 'height_type!' => 'auto', + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-message' => 'align-items: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'position_heading', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'horizontal_position', + [ + 'label' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'justify-content: {{VALUE}}', + ], + 'selectors_dictionary' => [ + 'left' => 'flex-start', + 'right' => 'flex-end', + ], + ] + ); + + $this->add_responsive_control( + 'vertical_position', + [ + 'label' => esc_html__( 'Vertical', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'toggle' => false, + 'default' => 'center', + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'align-items: {{VALUE}}', + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'bottom' => 'flex-end', + ], + ] + ); + + $this->add_control( + 'overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => 'pointer-events: all', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'close_button', + [ + 'label' => esc_html__( 'Close Button', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'selectors' => [ + // Using flex to make sure that each icon type (i or SVG) will be vertically aligned. + '{{WRAPPER}} .dialog-close-button' => 'display: flex', + ], + ] + ); + + $this->add_responsive_control( + 'entrance_animation', + [ + 'label' => esc_html__( 'Entrance Animation', 'elementor-pro' ), + 'type' => Controls_Manager::ANIMATION, + 'frontend_available' => true, + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'exit_animation', + [ + 'label' => esc_html__( 'Exit Animation', 'elementor-pro' ), + 'type' => Controls_Manager::EXIT_ANIMATION, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'entrance_animation_duration', + [ + 'label' => esc_html__( 'Animation Duration', 'elementor-pro' ) . ' (s)', + 'type' => Controls_Manager::SLIDER, + 'frontend_available' => true, + 'default' => [ + 'size' => 1.2, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 5, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-widget-content' => 'animation-duration: {{SIZE}}s', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'entrance_animation', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'exit_animation', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + + $this->start_controls_section( + 'section_page_style', + [ + 'label' => esc_html__( 'Popup', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'background', + 'selector' => '{{WRAPPER}} .dialog-widget-content', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'border', + 'selector' => '{{WRAPPER}} .dialog-widget-content', + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .dialog-widget-content' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .dialog-widget-content', + 'fields_options' => [ + 'box_shadow_type' => [ + 'default' => 'yes', + ], + 'box_shadow' => [ + 'default' => [ + 'horizontal' => 2, + 'vertical' => 8, + 'blur' => 23, + 'spread' => 3, + 'color' => 'rgba(0,0,0,0.2)', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_overlay', + [ + 'label' => esc_html__( 'Overlay', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'overlay' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'overlay_background', + 'types' => [ 'classic', 'gradient' ], + 'selector' => '{{WRAPPER}}', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'default' => 'rgba(0,0,0,.8)', + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_close_button', + [ + 'label' => esc_html__( 'Close Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'close_button!' => '', + ], + ] + ); + + $this->add_control( + 'close_button_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Inside', 'elementor-pro' ), + 'outside' => esc_html__( 'Outside', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'close_button_vertical', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => -500, + 'max' => 500, + ], + 'em' => [ + 'min' => -50, + 'max' => 50, + ], + 'rem' => [ + 'min' => -50, + 'max' => 50, + ], + ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button' => 'top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'close_button_horizontal', + [ + 'label' => esc_html__( 'Horizontal Position', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => -500, + 'max' => 500, + ], + 'em' => [ + 'min' => -50, + 'max' => 50, + ], + 'rem' => [ + 'min' => -50, + 'max' => 50, + ], + ], + 'default' => [ + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .dialog-close-button' => 'right: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .dialog-close-button' => 'left: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'after', + ] + ); + + $this->start_controls_tabs( 'close_button_style_tabs' ); + + $this->start_controls_tab( + 'tab_x_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'close_button_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button i' => 'color: {{VALUE}}', + '{{WRAPPER}} .dialog-close-button svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'close_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_x_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'close_button_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button:hover i' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'close_button_hover_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .dialog-close-button' => 'font-size: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_advanced', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_ADVANCED, + ] + ); + + $this->add_control( + 'close_button_delay', + [ + 'label' => esc_html__( 'Show Close Button After', 'elementor-pro' ) . ' (sec)', + 'type' => Controls_Manager::NUMBER, + 'min' => 0.1, + 'max' => 60, + 'step' => 0.1, + 'condition' => [ + 'close_button' => 'yes', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'close_automatically', + [ + 'label' => esc_html__( 'Automatically Close After', 'elementor-pro' ) . ' (sec)', + 'type' => Controls_Manager::NUMBER, + 'min' => 0.1, + 'max' => 60, + 'step' => 0.1, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'prevent_close_on_background_click', + [ + 'label' => esc_html__( 'Prevent Closing on Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'prevent_close_on_esc_key', + [ + 'label' => esc_html__( 'Prevent Closing on ESC key', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'prevent_scroll', + [ + 'label' => esc_html__( 'Disable Page Scrolling', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'avoid_multiple_popups', + [ + 'label' => esc_html__( 'Avoid Multiple Popups', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'description' => esc_html__( 'If the user has seen another popup on the page hide this popup', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'a11y_navigation', + [ + 'label' => esc_html__( 'Accessible navigation', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'description' => esc_html__( 'Allow keyboard tab navigation for accessibility', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'open_selector', + [ + 'label' => esc_html__( 'Open By Selector', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( '#id, .class', 'elementor-pro' ), + 'description' => esc_html__( 'In order to open a popup on selector click, please set your Popup Conditions', 'elementor-pro' ), + 'frontend_available' => true, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_responsive_control( + 'margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .dialog-widget-content' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .dialog-message' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'classes', + [ + 'label' => esc_html__( 'CSS Classes', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'title' => esc_html__( 'Add your custom class WITHOUT the dot. e.g: my-class', 'elementor-pro' ), + 'ai' => [ + 'active' => false, + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + Plugin::elementor()->controls_manager->add_custom_css_controls( $this ); + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + $config['type'] = 'popup'; + $config['default_route'] = 'templates/popups'; + $config['autoImportSettings'] = true; + + return $config; + } +} diff --git a/modules/popup/form-action.php b/modules/popup/form-action.php new file mode 100644 index 00000000..52a4a112 --- /dev/null +++ b/modules/popup/form-action.php @@ -0,0 +1,143 @@ +start_controls_section( + 'section_popup', + [ + 'label' => esc_html__( 'Popup', 'elementor-pro' ), + 'condition' => [ + 'submit_actions' => $this->get_name(), + ], + ] + ); + + $widget->add_control( + 'popup_action', + [ + 'label' => esc_html__( 'Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Choose', 'elementor-pro' ), + 'open' => esc_html__( 'Open Popup', 'elementor-pro' ), + 'close' => esc_html__( 'Close Popup', 'elementor-pro' ), + ], + ] + ); + + $widget->add_control( + 'popup_action_popup_id', + [ + 'label' => esc_html__( 'Popup', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'posts_per_page' => 20, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => 'popup', + ], + ], + ], + ], + 'condition' => [ + 'popup_action' => 'open', + ], + ] + ); + + $widget->add_control( + 'popup_action_do_not_show_again', + [ + 'label' => esc_html__( 'Don\'t Show Again', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'popup_action' => 'close', + ], + ] + ); + + $widget->end_controls_section(); + } + + public function on_export( $element ) { + unset( + $element['settings']['popup_action'], + $element['settings']['popup_action_popup_id'], + $element['settings']['popup_action_do_not_show_again'] + ); + + return $element; + } + + public function run( $record, $ajax_handler ) { + $popup_action = $record->get_form_settings( 'popup_action' ); + + if ( empty( $popup_action ) ) { + return; + } + + $action_settings = [ + 'action' => $popup_action, + ]; + + if ( 'open' === $popup_action ) { + $popup_id = $record->get_form_settings( 'popup_action_popup_id' ); + + if ( empty( $popup_id ) ) { + return; + } + + $action_settings['id'] = $popup_id; + } else { + $action_settings['do_not_show_again'] = $record->get_form_settings( 'popup_action_do_not_show_again' ); + } + + $ajax_handler->add_response_data( 'popup', $action_settings ); + } + + public function maybe_print_popup( $settings, $widget ) { + if ( ! is_array( $settings['submit_actions'] ) || ! in_array( 'popup', $settings['submit_actions'] ) ) { + return; + } + + $has_valid_settings = ( ! empty( $settings['popup_action'] ) && 'open' === $settings['popup_action'] && ! empty( $settings['popup_action_popup_id'] ) ); + if ( ! $has_valid_settings ) { + return; + } + + Module::add_popup_to_location( $settings['popup_action_popup_id'] ); + } + + public function __construct() { + /** @var FormsModule $forms_module */ + $forms_module = FormsModule::instance(); + + // Register popup form action + $forms_module->actions_registrar->register( $this ); + + add_action( 'elementor-pro/forms/pre_render', [ $this, 'maybe_print_popup' ], 10, 2 ); + } +} diff --git a/modules/popup/module.php b/modules/popup/module.php new file mode 100644 index 00000000..b856eaea --- /dev/null +++ b/modules/popup/module.php @@ -0,0 +1,304 @@ +can_use_popups() ) { + add_action( 'elementor/documents/register', [ $this, 'register_documents' ] ); + add_action( 'elementor/theme/register_locations', [ $this, 'register_location' ] ); + add_action( 'elementor/dynamic_tags/register', [ $this, 'register_tag' ] ); + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + add_action( 'wp_footer', [ $this, 'print_popups' ] ); + add_action( 'elementor_pro/init', [ $this, 'add_form_action' ] ); + + add_action( 'elementor/frontend/before_register_styles', [ $this, 'register_styles' ] ); + } else { + add_action( 'load-post.php', [ $this, 'disable_editing' ] ); + add_action( 'admin_init', [ $this, 'maybe_redirect_to_promotion_page' ] ); + } + + if ( Plugin::elementor()->experiments->is_feature_active( 'admin_menu_rearrangement' ) ) { + add_action( 'elementor/admin/menu_registered/elementor', function( MainMenu $menu ) { + $this->register_admin_menu( $menu ); + } ); + } else { + add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu_manager ) { + if ( $this->can_use_popups() ) { + $admin_menu_manager->register( $this->get_admin_url( true ), new Popups_Menu_Item() ); + } else { + $admin_menu_manager->register( static::PROMOTION_MENU_SLUG, new Popups_Promotion_Menu_Item() ); + } + } ); + + // TODO: BC - Remove in the future. + add_action( 'admin_menu', function() { + $this->register_admin_menu_legacy(); + }, 21 /* After `Admin_Menu_Manager` */ ); + } + + add_filter( 'elementor/finder/categories', [ $this, 'add_finder_items' ] ); + add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'localize_settings' ] ); + } + + public function register_frontend_styles() { + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + + wp_register_style( + 'e-popup', + ELEMENTOR_PRO_URL . 'assets/css/conditionals/popup' . $suffix . '.css', + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function enqueue_preview_styles() { + wp_enqueue_style( 'e-popup' ); + } + + public function disable_editing() { + $post_id = Utils::_unstable_get_super_global_value( $_GET, 'post' ); + + if ( ! $post_id ) { + return; + } + + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( ! $document ) { + return; + } + + $template_type = $document->get_main_meta( DocumentBase::TYPE_META_KEY ); + + if ( static::DOCUMENT_TYPE === $template_type ) { + $error = new \WP_Error( 'e_popups_editing_disabled', esc_html__( 'Invalid post type.', 'elementor-pro' ) ); + wp_die( $error ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + public function maybe_redirect_to_promotion_page() { + if ( $this->is_on_popups_admin_page() ) { + wp_redirect( $this->get_promotion_url() ); + exit(); + } + } + + private function is_on_popups_admin_page() { + global $pagenow; + + return isset( $pagenow ) && + 'edit.php' === $pagenow && + Source_Local::CPT === Utils::_unstable_get_super_global_value( $_GET, 'post_type' ) && + static::DOCUMENT_TYPE === Utils::_unstable_get_super_global_value( $_GET, Source_Local::TAXONOMY_TYPE_SLUG ); + } + + private function get_promotion_url() { + return add_query_arg( + [ + 'page' => static::PROMOTION_MENU_SLUG, + ], + Source_Local::ADMIN_MENU_SLUG + ); + } + + public function get_name() { + return 'popup'; + } + + public function add_form_action() { + $this->add_component( 'form-action', new Form_Action() ); + } + + public static function add_popup_to_location( $popup_id ) { + /** @var \ElementorPro\Modules\ThemeBuilder\Module $theme_builder */ + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + + $theme_builder->get_locations_manager()->add_doc_to_location( Document::get_property( 'location' ), $popup_id ); + } + + public function register_documents( Documents_Manager $documents_manager ) { + $documents_manager->register_document_type( self::DOCUMENT_TYPE, Document::get_class_full_name() ); + } + + public function register_location( Locations_Manager $location_manager ) { + $location_manager->register_location( + 'popup', + [ + 'label' => esc_html__( 'Popup', 'elementor-pro' ), + 'multiple' => true, + 'public' => false, + 'edit_in_content' => false, + ] + ); + } + + public function print_popups() { + elementor_theme_do_location( 'popup' ); + } + + public function register_tag( DynamicTagsManager $dynamic_tags ) { + $tag = __NAMESPACE__ . '\Tag'; + + $dynamic_tags->register( new $tag() ); + } + + public function register_ajax_actions( Ajax $ajax ) { + $ajax->register_ajax_action( 'pro_popup_save_display_settings', [ $this, 'save_display_settings' ] ); + } + + /** + * @throws \Exception + */ + public function save_display_settings( $data ) { + $document = Utils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + /** @var Document $document */ + $document->save_display_settings_data( $data['settings'] ); + } + + /** + * Add New item to admin menu. + * + * @since 3.6.0 + * @access private + */ + private function register_admin_menu( MainMenu $menu ) { + $menu->add_submenu( [ + 'menu_title' => esc_html__( 'Popups', 'elementor-pro' ), + 'menu_slug' => $this->get_admin_url( true ), + 'index' => 10, + ] ); + } + + /** + * Add New item to admin menu. + * + * Fired by `admin_menu` action. + * + * @since 3.6.0 + * @access private + */ + private function register_admin_menu_legacy() { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + add_submenu_page( + Source_Local::ADMIN_MENU_SLUG, + '', + esc_html__( 'Popups', 'elementor-pro' ), + 'publish_posts', + $this->get_admin_url( true ) + ); + } + + public function add_finder_items( array $categories ) { + $categories['general']['items']['popups'] = [ + 'title' => esc_html__( 'Popups', 'elementor-pro' ), + 'icon' => 'library-save', + 'url' => $this->get_admin_url(), + 'keywords' => [ 'template', 'popup', 'library' ], + ]; + + if ( ! $this->can_use_popups() ) { + $lock = new Feature_Lock( [ 'type' => 'popup' ] ); + + $categories['general']['items']['popups']['lock'] = $lock->get_config(); + } + + return $categories; + } + + private function get_admin_url( $relative = false ) { + $base_url = Source_Local::ADMIN_MENU_SLUG; + if ( ! $relative ) { + $base_url = admin_url( $base_url ); + } + + return add_query_arg( + [ + 'tabs_group' => 'popup', + 'elementor_library_type' => 'popup', + ], + $base_url + ); + } + + private function can_use_popups() { + return ( API::is_license_active() && API::is_licence_has_feature( static::DOCUMENT_TYPE, API::BC_VALIDATION_CALLBACK ) ) || $this->has_popups(); + } + + private function has_popups() { + if ( null !== $this->has_popups ) { + return $this->has_popups; + } + + $existing_popups = new \WP_Query( [ + 'post_type' => Source_Local::CPT, + 'posts_per_page' => 1, + 'post_status' => 'any', + 'meta_query' => [ + [ + 'key' => DocumentBase::TYPE_META_KEY, + 'value' => Document::get_type(), + ], + ], + 'meta_key' => DocumentBase::TYPE_META_KEY, + ] ); + + $this->has_popups = $existing_popups->post_count > 0; + + return $this->has_popups; + } + + public function localize_settings( array $settings ): array { + $settings['popup']['hasPopUps'] = $this->has_popups(); + + return $settings; + } + + protected function get_assets_base_url() { + return ELEMENTOR_PRO_URL; + } + + public function register_styles() { + wp_register_style( + 'e-popup', + $this->get_css_assets_url( 'popup', 'assets/css/conditionals/', true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/popup/tag.php b/modules/popup/tag.php new file mode 100644 index 00000000..b767c712 --- /dev/null +++ b/modules/popup/tag.php @@ -0,0 +1,134 @@ +add_control( + 'action', + [ + 'label' => esc_html__( 'Action', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'open', + 'options' => [ + 'open' => esc_html__( 'Open Popup', 'elementor-pro' ), + 'close' => esc_html__( 'Close Popup', 'elementor-pro' ), + 'toggle' => esc_html__( 'Toggle Popup', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'popup', + [ + 'label' => esc_html__( 'Popup', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'posts_per_page' => 20, + 'post_status' => [ 'publish', 'private' ], + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => 'popup', + ], + ], + ], + ], + 'label_block' => true, + 'condition' => [ + 'action' => [ 'open', 'toggle' ], + ], + ] + ); + + $this->add_control( + 'do_not_show_again', + [ + 'label' => esc_html__( 'Don\'t Show Again', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'action' => 'close', + ], + ] + ); + } + + public function render() { + $settings = $this->get_active_settings(); + + if ( 'close' === $settings['action'] ) { + $this->print_close_popup_link( $settings ); + + return; + } + + $this->print_open_popup_link( $settings ); + } + + // Keep Empty to avoid default advanced section + protected function register_advanced_section() {} + + private function print_open_popup_link( array $settings ) { + if ( ! $settings['popup'] ) { + return; + } + + $link_action_url = Plugin::elementor()->frontend->create_action_hash( 'popup:open', [ + 'id' => $settings['popup'], + 'toggle' => 'toggle' === $settings['action'], + ] ); + + Module::add_popup_to_location( $settings['popup'] ); + + // PHPCS - `create_action_hash` is safe. + echo $link_action_url; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + private function print_close_popup_link( array $settings ) { + // PHPCS - `create_action_hash` is safe. + echo Plugin::elementor()->frontend->create_action_hash( 'popup:close', [ 'do_not_show_again' => $settings['do_not_show_again'] ] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/posts/data/controller.php b/modules/posts/data/controller.php new file mode 100644 index 00000000..89bfb1fd --- /dev/null +++ b/modules/posts/data/controller.php @@ -0,0 +1,61 @@ +documents->get( $request->get_param( 'post_id' ) ); + + if ( ! $document ) { + return new \WP_Error( + 'document_not_exist', + __( 'Document doesn\'t exist', 'elementor-pro' ), + [ 'status' => 404 ] + ); + } + + $element_data = $document->get_elements_data(); + $posts_widget = Utils::find_element_recursive( $element_data, $request->get_param( 'element_id' ) ); + + if ( empty( $posts_widget ) ) { + return new \WP_Error( + 'Element_not_exist', + __( 'Posts widget doesn\'t exist', 'elementor-pro' ), + [ 'status' => 404 ] + ); + } + + set_query_var( 'paged', $request->get_param( 'page' ) ); + + /** @var \ElementorPro\Modules\Posts\Widgets\Posts $element_instance */ + $element_instance = Plugin::elementor()->elements_manager->create_element_instance( $posts_widget ); + + ob_start(); + $element_instance->render_content(); + $html = ob_get_clean(); + + return [ + 'content' => $html, + ]; + } + + public function get_permission_callback( $request ) { + return true; + } +} diff --git a/modules/posts/module.php b/modules/posts/module.php new file mode 100644 index 00000000..2760efc0 --- /dev/null +++ b/modules/posts/module.php @@ -0,0 +1,91 @@ +get_css_assets_url( 'widget-posts', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + /** + * Fix WP 5.5 pagination issue. + * + * Return true to mark that it's handled and avoid WP to set it as 404. + * + * @see https://github.com/elementor/elementor/issues/12126 + * @see https://core.trac.wordpress.org/ticket/50976 + * + * Based on the logic at \WP::handle_404. + * + * @param $handled - Default false. + * @param $wp_query + * + * @return bool + */ + public function allow_posts_widget_pagination( $handled, $wp_query ) { + // Check it's not already handled and it's a single paged query. + if ( $handled || empty( $wp_query->query_vars['page'] ) || ! is_singular() || empty( $wp_query->post ) ) { + return $handled; + } + + $document = Plugin::elementor()->documents->get( $wp_query->post->ID ); + + return $this->is_valid_pagination( $document->get_elements_data(), $wp_query->query_vars['page'] ); + } + + public function __construct() { + parent::__construct(); + + Plugin::elementor()->data_manager->register_controller( Controller::class ); + + add_filter( 'pre_handle_404', [ $this, 'allow_posts_widget_pagination' ], 10, 2 ); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + } + +} diff --git a/modules/posts/skins/skin-base.php b/modules/posts/skins/skin-base.php new file mode 100644 index 00000000..2e32c7ab --- /dev/null +++ b/modules/posts/skins/skin-base.php @@ -0,0 +1,1416 @@ +parent = $widget; + + $this->register_design_controls(); + } + + public function register_controls( Widget_Base $widget ) { + $this->parent = $widget; + + $this->register_columns_controls(); + $this->register_post_count_control(); + $this->register_thumbnail_controls(); + $this->register_title_controls(); + $this->register_excerpt_controls(); + $this->register_meta_data_controls(); + $this->register_read_more_controls(); + $this->register_link_controls(); + } + + public function register_design_controls() { + $this->register_design_layout_controls(); + $this->register_design_image_controls(); + $this->register_design_content_controls(); + } + + protected function register_thumbnail_controls() { + $this->add_control( + 'thumbnail', + [ + 'label' => esc_html__( 'Image Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'top', + 'options' => [ + 'top' => esc_html__( 'Top', 'elementor-pro' ), + 'left' => esc_html__( 'Left', 'elementor-pro' ), + 'right' => esc_html__( 'Right', 'elementor-pro' ), + 'none' => esc_html__( 'None', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-posts--thumbnail-', + ] + ); + + $this->add_control( + 'masonry', + [ + 'label' => esc_html__( 'Masonry', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + $this->get_control_id( 'columns!' ) => '1', + $this->get_control_id( 'thumbnail' ) => 'top', + ], + 'render_type' => 'ui', + 'frontend_available' => true, + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'thumbnail_size', + 'default' => 'medium', + 'exclude' => [ 'custom' ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + 'prefix_class' => 'elementor-posts--thumbnail-size-', + ] + ); + + $this->add_responsive_control( + 'item_ratio', + [ + 'label' => esc_html__( 'Image Ratio', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 0.66, + ], + 'tablet_default' => [ + 'size' => '', + ], + 'mobile_default' => [ + 'size' => 0.5, + ], + 'range' => [ + 'px' => [ + 'min' => 0.1, + 'max' => 2, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-posts-container .elementor-post__thumbnail' => 'padding-bottom: calc( {{SIZE}} * 100% );', + '{{WRAPPER}}:after' => 'content: "{{SIZE}}";', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + $this->get_control_id( 'masonry' ) => '', + ], + ] + ); + + $this->add_responsive_control( + 'image_width', + [ + 'label' => esc_html__( 'Image Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + '%' => [ + 'min' => 10, + 'max' => 100, + ], + 'px' => [ + 'min' => 10, + 'max' => 600, + ], + 'em' => [ + 'min' => 1, + 'max' => 60, + ], + 'rem' => [ + 'min' => 1, + 'max' => 60, + ], + ], + 'default' => [ + 'size' => 100, + 'unit' => '%', + ], + 'tablet_default' => [ + 'size' => '', + 'unit' => '%', + ], + 'mobile_default' => [ + 'size' => 100, + 'unit' => '%', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__thumbnail__link' => 'width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + } + + protected function register_columns_controls() { + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '3', + 'tablet_default' => '2', + 'mobile_default' => '1', + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-grid%s-', + 'frontend_available' => true, + ] + ); + } + + protected function register_post_count_control() { + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Posts Per Page', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + } + + protected function register_title_controls() { + $this->add_control( + 'show_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'h3', + 'condition' => [ + $this->get_control_id( 'show_title' ) => 'yes', + ], + ] + ); + + } + + protected function register_excerpt_controls() { + $this->add_control( + 'show_excerpt', + [ + 'label' => esc_html__( 'Excerpt', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'excerpt_length', + [ + 'label' => esc_html__( 'Excerpt Length', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + /** This filter is documented in wp-includes/formatting.php */ + 'default' => apply_filters( 'excerpt_length', 25 ), + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'apply_to_custom_excerpt', + [ + 'label' => esc_html__( 'Apply to custom Excerpt', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'default' => 'no', + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + } + + protected function register_read_more_controls() { + $this->add_control( + 'show_read_more', + [ + 'label' => esc_html__( 'Read More', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'read_more_text', + [ + 'label' => esc_html__( 'Read More Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Read More »', 'elementor-pro' ), + 'condition' => [ + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'read_more_alignment', + [ + 'label' => esc_html__( 'Automatically align buttons', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'default' => '', + 'render_type' => 'template', + 'selectors' => [ + // --item-display is used for the styling of both elementor-post__card and elementor-post__text + '{{WRAPPER}}' => '--item-display: flex; --read-more-alignment: 1;', + ], + 'condition' => [ + $this->get_control_id( 'masonry!' ) => 'yes', + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + } + + protected function register_link_controls() { + $this->add_control( + 'open_new_tab', + [ + 'label' => esc_html__( 'Open in new window', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'default' => 'no', + 'render_type' => 'none', + ] + ); + } + + protected function get_optional_link_attributes_html() { + $settings = $this->parent->get_settings(); + $new_tab_setting_key = $this->get_control_id( 'open_new_tab' ); + $optional_attributes_html = 'yes' === $settings[ $new_tab_setting_key ] ? 'target="_blank"' : ''; + + return $optional_attributes_html; + } + + protected function register_meta_data_controls() { + $this->add_control( + 'meta_data', + [ + 'label' => esc_html__( 'Meta Data', 'elementor-pro' ), + 'label_block' => true, + 'type' => Controls_Manager::SELECT2, + 'default' => [ 'date', 'comments' ], + 'multiple' => true, + 'options' => [ + 'author' => esc_html__( 'Author', 'elementor-pro' ), + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'time' => esc_html__( 'Time', 'elementor-pro' ), + 'comments' => esc_html__( 'Comments', 'elementor-pro' ), + 'modified' => esc_html__( 'Date Modified', 'elementor-pro' ), + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'meta_separator', + [ + 'label' => esc_html__( 'Separator Between', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '///', + 'ai' => [ + 'active' => false, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__meta-data span + span:before' => 'content: "{{VALUE}}"', + ], + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + } + + /** + * Style Tab + */ + protected function register_design_layout_controls() { + $this->start_controls_section( + 'section_design_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 30, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 35, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-posts--align-', + ] + ); + + $this->end_controls_section(); + } + + protected function register_design_image_controls() { + $this->start_controls_section( + 'section_design_image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'img_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__thumbnail' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'image_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-posts--thumbnail-left .elementor-post__thumbnail__link' => 'margin-right: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-posts--thumbnail-right .elementor-post__thumbnail__link' => 'margin-left: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-posts--thumbnail-top .elementor-post__thumbnail__link' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'default' => [ + 'size' => 20, + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + + $this->start_controls_tabs( 'thumbnail_effects_tabs' ); + + $this->start_controls_tab( 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'thumbnail_filters', + 'selector' => '{{WRAPPER}} .elementor-post__thumbnail img', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Css_Filter::get_type(), + [ + 'name' => 'thumbnail_hover_filters', + 'selector' => '{{WRAPPER}} .elementor-post:hover .elementor-post__thumbnail img', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function register_design_content_controls() { + $this->start_controls_section( + 'section_design_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + $this->get_control_id( 'show_title' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__title, {{WRAPPER}} .elementor-post__title a' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'show_title' ) => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-post__title, {{WRAPPER}} .elementor-post__title a', + 'condition' => [ + $this->get_control_id( 'show_title' ) => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-post__title', + ] + ); + + $this->add_responsive_control( + 'title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__title' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'show_title' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'heading_meta_style', + [ + 'label' => esc_html__( 'Meta', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->add_control( + 'meta_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__meta-data' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->add_control( + 'meta_separator_color', + [ + 'label' => esc_html__( 'Separator Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__meta-data span:before' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'meta_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'selector' => '{{WRAPPER}} .elementor-post__meta-data', + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->add_responsive_control( + 'meta_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__meta-data' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->add_control( + 'heading_excerpt_style', + [ + 'label' => esc_html__( 'Excerpt', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'excerpt_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__excerpt p' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'excerpt_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-post__excerpt p', + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'excerpt_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__excerpt' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'show_excerpt' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'heading_readmore_style', + [ + 'label' => esc_html__( 'Read More', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'read_more_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__read-more' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'read_more_typography', + // The 'a' selector is added for specificity, for when this control's selector is used in globals CSS. + 'selector' => '{{WRAPPER}} a.elementor-post__read-more', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'condition' => [ + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'read_more_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__text' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'show_read_more' ) => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $this->parent->query_posts(); + + /** @var \WP_Query $query */ + $query = $this->parent->get_query(); + + if ( ! $query->found_posts ) { + $this->handle_no_posts_found(); + return; + } + + $this->render_loop_header(); + + // It's the global `wp_query` it self. and the loop was started from the theme. + if ( $query->in_the_loop ) { + $this->current_permalink = get_permalink(); + $this->render_post(); + } else { + while ( $query->have_posts() ) { + $query->the_post(); + + $this->add_render_hooks(); + $this->current_permalink = get_permalink(); + $this->render_post(); + $this->remove_render_hooks(); + } + } + + wp_reset_postdata(); + + $this->render_loop_footer(); + } + + protected function add_render_hooks() {} + + protected function remove_render_hooks() {} + + public function filter_excerpt_length() { + return $this->get_instance_value( 'excerpt_length' ); + } + + public function filter_excerpt_more( $more ) { + return ''; + } + + public function get_container_class() { + return 'elementor-posts--skin-' . $this->get_id(); + } + + protected function render_thumbnail() { + $thumbnail = $this->get_instance_value( 'thumbnail' ); + + if ( 'none' === $thumbnail && ! Plugin::elementor()->editor->is_edit_mode() ) { + return; + } + + $settings = $this->parent->get_settings(); + $setting_key = $this->get_control_id( 'thumbnail_size' ); + $settings[ $setting_key ] = [ + 'id' => get_post_thumbnail_id(), + ]; + $thumbnail_html = Group_Control_Image_Size::get_attachment_image_html( $settings, $setting_key ); + + if ( empty( $thumbnail_html ) ) { + return; + } + + $optional_attributes_html = $this->get_optional_link_attributes_html(); + + ?> + > +
      +
      + get_instance_value( 'show_title' ) ) { + return; + } + + $optional_attributes_html = $this->get_optional_link_attributes_html(); + + $tag = $this->get_instance_value( 'title_tag' ); + ?> + < class="elementor-post__title"> + > + + + > + get_instance_value( 'show_excerpt' ) ) { + return; + } + + add_filter( 'excerpt_more', [ $this, 'filter_excerpt_more' ], 20 ); + add_filter( 'excerpt_length', [ $this, 'filter_excerpt_length' ], 20 ); + + ?> +
      + get_instance_value( 'apply_to_custom_excerpt' ); + + // Force the manually-generated Excerpt length as well if the user chose to enable 'apply_to_custom_excerpt'. + if ( 'yes' === $apply_to_custom_excerpt && ! empty( $post->post_excerpt ) ) { + $max_length = (int) $this->get_instance_value( 'excerpt_length' ); + $excerpt = apply_filters( 'the_excerpt', get_the_excerpt() ); + $excerpt = ProUtils::trim_words( $excerpt, $max_length ); + echo wp_kses_post( $excerpt ); + } else { + the_excerpt(); + } + ?> +
      + parent->get_settings_for_display(); + $read_more_key = $this->get_control_id( 'read_more_text' ); + $read_more = $settings[ $read_more_key ]; + + if ( ! $this->get_instance_value( 'show_read_more' ) ) { + return; + } + + $aria_label_text = sprintf( + /* translators: %s: Post title. */ + esc_attr__( 'Read more about %s', 'elementor-pro' ), + get_the_title() + ); + + $optional_attributes_html = $this->get_optional_link_attributes_html(); + + if ( $this->display_read_more_bottom() ) : ?> +
      + + + > + + + + display_read_more_bottom() ) : ?> +
      + +
      role="listitem"> + +
      + +
      + +
      + get_container_class(), + ]; + } + + protected function handle_no_posts_found() {} + + protected function render_loop_header() { + $classes = $this->get_loop_header_widget_classes(); + + /** @var \WP_Query $e_wp_query */ + $e_wp_query = $this->parent->get_query(); + + // Use grid only if found posts. + if ( isset( $e_wp_query->found_posts ) || Taxonomy_Loop_Provider::is_loop_taxonomy() ) { + $classes[] = 'elementor-grid'; + } + + $render_attributes = apply_filters( 'elementor/skin/loop_header_attributes', [ + 'class' => $classes, + 'role' => 'list', + ] ); + + $this->parent->add_render_attribute( 'container', $render_attributes ); + + ?> +
      parent->print_render_attribute_string( 'container' ); ?>> + parent->get_settings_for_display(); + ?> +
      + +
      + parent->get_settings_for_display(); + + // If the skin has no pagination, there's nothing to render in the loop footer. + if ( ! isset( $parent_settings['pagination_type'] ) ) { + return; + } + + $using_ajax_pagination = in_array( $parent_settings['pagination_type'], [ + Posts_Base::LOAD_MORE_ON_CLICK, + Posts_Base::LOAD_MORE_INFINITE_SCROLL, + ], true); + + if ( $using_ajax_pagination && ! empty( $parent_settings['load_more_spinner']['value'] ) ) : ?> + + 'true' ] ); ?> + + + + parent->get_query()->max_num_pages; + + // Page limit control should not effect in load more mode. + if ( '' !== $parent_settings['pagination_page_limit'] && ! $using_ajax_pagination ) { + $page_limit = min( $parent_settings['pagination_page_limit'], $page_limit ); + } + + if ( 2 > $page_limit ) { + return; + } + + $this->parent->add_render_attribute( 'pagination', 'class', 'elementor-pagination' ); + + $has_numbers = in_array( $parent_settings['pagination_type'], [ 'numbers', 'numbers_and_prev_next' ] ); + $has_prev_next = in_array( $parent_settings['pagination_type'], [ 'prev_next', 'numbers_and_prev_next' ] ); + + $load_more_type = $parent_settings['pagination_type']; + + $current_page = $this->parent->get_current_page(); + $next_page = intval( $current_page ) + 1; + + $this->parent->add_render_attribute( 'load_more_anchor', [ + 'data-page' => $current_page, + 'data-max-page' => $this->parent->get_query()->max_num_pages, + 'data-next-page' => $this->parent->get_wp_link_page( $next_page ), + ] ); + + ?> +
      parent->print_render_attribute_string( 'load_more_anchor' ); ?>>
      + parent->set_settings( 'link', [ 'url' => '#' ] ); + + $this->render_button( $this->parent ); + } + + $this->render_message(); + return; + } + + $links = []; + + if ( $has_numbers ) { + $paginate_args = [ + 'type' => 'array', + 'current' => $this->parent->get_current_page(), + 'total' => $page_limit, + 'prev_next' => false, + 'show_all' => 'yes' !== $parent_settings['pagination_numbers_shorten'], + 'before_page_number' => '' . esc_html__( 'Page', 'elementor-pro' ) . '', + ]; + + if ( is_singular() && ! is_front_page() && ! $this->parent->is_rest_request() ) { + $paginate_args = $this->get_paginate_args_for_singular_post( $paginate_args ); + } + + if ( is_archive() && $this->parent->current_url_contains_taxonomy_filter() ) { + $paginate_args = $this->get_paginate_args_for_archive_with_filters( $paginate_args ); + } + + if ( $this->parent->is_rest_request() ) { + $paginate_args = $this->get_paginate_args_for_rest_request( $paginate_args ); + } + + if ( $this->parent->is_allow_to_use_custom_page_option() ) { + $paginate_args['format'] = $this->get_pagination_format( $paginate_args ); + } + + $links = paginate_links( $paginate_args ); + } + + if ( $has_prev_next ) { + $prev_next = $this->parent->get_posts_nav_link( $page_limit ); + array_unshift( $links, $prev_next['prev'] ); + $links[] = $prev_next['next']; + } + + // PHPCS - Seems that `$links` is safe. + ?> + + parent->get_id() . '=%#%'; + } + + protected function get_paginate_args_for_singular_post( $paginate_args ) { + global $wp_rewrite; + + if ( $wp_rewrite->using_permalinks() ) { + $paginate_args['base'] = trailingslashit( get_permalink() ) . '%_%'; + $paginate_args['format'] = user_trailingslashit( '%#%', 'single_paged' ); + } else { + $paginate_args['format'] = '?page=%#%'; + } + + return $paginate_args; + } + + protected function get_paginate_args_for_archive_with_filters( $paginate_args ) { + global $wp_rewrite; + + if ( ! $wp_rewrite->using_permalinks() ) { + $paginate_args['format'] = '?page=%#%'; + } + + return $paginate_args; + } + + protected function get_paginate_args_for_rest_request( $paginate_args ) { + global $wp_rewrite; + + $link_unescaped = wp_get_referer(); + $url_components = wp_parse_url( $link_unescaped ); + $add_args = []; + + if ( isset( $url_components['query'] ) ) { + wp_parse_str( $url_components['query'], $add_args ); + } + + $url_to_post_id = url_to_postid( $link_unescaped ); + $pagination_base_url = 0 !== $url_to_post_id + ? get_permalink( $url_to_post_id ) + : get_query_var( 'pagination_base_url' ); + + if ( $wp_rewrite->using_permalinks() ) { + $paginate_args['base'] = trailingslashit( $pagination_base_url ) . '%_%'; + $paginate_args['format'] = user_trailingslashit( '%#%', 'single_paged' ); + $paginate_args['add_args'] = $add_args; + + if ( 0 === $url_to_post_id ) { + unset( $paginate_args['format'] ); + } + } else { + $base = $this->parent->is_allow_to_use_custom_page_option() ? $pagination_base_url . '&%_%' : trailingslashit( $pagination_base_url ) . '%_%'; + $paginate_args['base'] = $base; + $paginate_args['format'] = '&page=%#%'; + $paginate_args['add_args'] = $add_args; + } + + return $paginate_args; + } + + protected function render_meta_data() { + /** @var array $settings e.g. [ 'author', 'date', ... ] */ + $settings = $this->get_instance_value( 'meta_data' ); + if ( empty( $settings ) ) { + return; + } + ?> + + + + + + + + + + parent->get_settings(); + + if ( 'full_content' === $settings['_skin'] ) { + return false; + } + + return 'yes' === $settings[ $this->get_control_id( 'read_more_alignment' ) ] && + 'yes' === $settings[ $this->get_control_id( 'show_read_more' ) ] && + 'yes' !== $settings[ $this->get_control_id( 'masonry' ) ]; + } + + protected function render_comments() { + ?> + + + + render_post_header(); + $this->render_thumbnail(); + $this->render_text_header(); + $this->render_title(); + $this->render_meta_data(); + $this->render_excerpt(); + $this->render_read_more(); + $this->render_text_footer(); + $this->render_post_footer(); + } +} diff --git a/modules/posts/skins/skin-cards.php b/modules/posts/skins/skin-cards.php new file mode 100644 index 00000000..11e97ab6 --- /dev/null +++ b/modules/posts/skins/skin-cards.php @@ -0,0 +1,649 @@ +get_id(); + $this->parent->start_controls_tab( $this->get_control_id( $id ), $args ); + } + + public function end_controls_tab() { + $this->parent->end_controls_tab(); + } + + public function start_controls_tabs( $id ) { + $args['condition']['_skin'] = $this->get_id(); + $this->parent->start_controls_tabs( $this->get_control_id( $id ) ); + } + + public function end_controls_tabs() { + $this->parent->end_controls_tabs(); + } + + public function register_controls( Widget_Base $widget ) { + $this->parent = $widget; + + $this->register_columns_controls(); + $this->register_post_count_control(); + $this->register_thumbnail_controls(); + $this->register_title_controls(); + $this->register_excerpt_controls(); + $this->register_meta_data_controls(); + $this->register_read_more_controls(); + $this->register_link_controls(); + $this->register_badge_controls(); + $this->register_avatar_controls(); + } + + public function register_design_controls() { + $this->register_design_layout_controls(); + $this->register_design_card_controls(); + $this->register_design_image_controls(); + $this->register_design_content_controls(); + } + + protected function register_thumbnail_controls() { + parent::register_thumbnail_controls(); + $this->remove_responsive_control( 'image_width' ); + $this->update_control( + 'thumbnail', + [ + 'label' => esc_html__( 'Show Image', 'elementor-pro' ), + 'options' => [ + 'top' => esc_html__( 'Yes', 'elementor-pro' ), + 'none' => esc_html__( 'No', 'elementor-pro' ), + ], + 'render_type' => 'template', + ] + ); + } + + protected function register_meta_data_controls() { + parent::register_meta_data_controls(); + $this->update_control( + 'meta_separator', + [ + 'default' => '•', + ] + ); + } + + public function register_additional_design_image_controls() { + $this->update_control( + 'image_spacing', + [ + 'selectors' => [ + '{{WRAPPER}} .elementor-post__text' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + + $this->remove_control( 'img_border_radius' ); + + $this->add_control( + 'heading_badge_style', + [ + 'label' => esc_html__( 'Badge', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_position', + [ + 'label' => 'Badge Position', + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'default' => 'right', + 'selectors' => [ + '{{WRAPPER}} .elementor-post__badge' => '{{VALUE}}: 0', + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__badge' => 'background-color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__badge' => 'color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__badge' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 5, + 'max' => 50, + ], + 'em' => [ + 'min' => 0.5, + 'max' => 5, + ], + 'rem' => [ + 'min' => 0.5, + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__badge' => 'font-size: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'badge_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'default' => [ + 'size' => 20, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__badge' => 'margin: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'badge_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-post__card .elementor-post__badge', + 'exclude' => [ 'font_size', 'line-height' ], + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + + $this->add_control( + 'heading_avatar_style', + [ + 'label' => esc_html__( 'Avatar', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + $this->get_control_id( 'show_avatar' ) => 'show-avatar', + ], + ] + ); + + $this->add_control( + 'avatar_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__avatar' => 'top: calc(-{{SIZE}}{{UNIT}} / 2);', + '{{WRAPPER}} .elementor-post__avatar img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-post__thumbnail__link' => 'margin-bottom: calc({{SIZE}}{{UNIT}} / 2)', + ], + 'condition' => [ + $this->get_control_id( 'show_avatar' ) => 'show-avatar', + ], + ] + ); + } + + public function register_badge_controls() { + $this->add_control( + 'show_badge', + [ + 'label' => esc_html__( 'Badge', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'badge_taxonomy', + [ + 'label' => esc_html__( 'Badge Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'label_block' => true, + 'default' => 'category', + 'options' => $this->get_taxonomies(), + 'condition' => [ + $this->get_control_id( 'show_badge' ) => 'yes', + ], + ] + ); + } + + public function register_avatar_controls() { + $this->add_control( + 'show_avatar', + [ + 'label' => esc_html__( 'Avatar', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'show-avatar', + 'default' => 'show-avatar', + 'separator' => 'before', + 'prefix_class' => 'elementor-posts--', + 'render_type' => 'template', + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => 'none', + ], + ] + ); + } + + public function register_design_card_controls() { + $this->start_controls_section( + 'section_design_card', + [ + 'label' => esc_html__( 'Card', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'card_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'card_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'card_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card' => 'border-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'card_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'card_padding', + [ + 'label' => esc_html__( 'Horizontal Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__text' => 'padding: 0 {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-post__meta-data' => 'padding: 10px {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-post__avatar' => 'padding-right: {{SIZE}}{{UNIT}}; padding-left: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'card_vertical_padding', + [ + 'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'box_shadow_box_shadow_type', // The name of this control is like that, for future extensibility to group_control box shadow. + [ + 'label' => esc_html__( 'Box Shadow', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'prefix_class' => 'elementor-card-shadow-', + 'default' => 'yes', + ] + ); + + $this->add_control( + 'hover_effect', + [ + 'label' => esc_html__( 'Hover Effect', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'gradient' => esc_html__( 'Gradient', 'elementor-pro' ), + //'zoom-in' => esc_html__( 'Zoom In', 'elementor-pro' ), + //'zoom-out' => esc_html__( 'Zoom Out', 'elementor-pro' ), + ], + 'default' => 'gradient', + 'separator' => 'before', + 'prefix_class' => 'elementor-posts__hover-', + ] + ); + + $this->add_control( + 'meta_border_color', + [ + 'label' => esc_html__( 'Meta Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-post__card .elementor-post__meta-data' => 'border-top-color: {{VALUE}}', + ], + 'condition' => [ + $this->get_control_id( 'meta_data!' ) => [], + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_design_content_controls() { + parent::register_design_content_controls(); + + $this->remove_control( 'meta_spacing' ); + + $this->update_control( + 'read_more_spacing', + [ + 'selectors' => [ + '{{WRAPPER}} .elementor-post__read-more' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ], + [ + 'recursive' => true, + ] + ); + } + + protected function get_taxonomies() { + $taxonomies = get_taxonomies( [ 'show_in_nav_menus' => true ], 'objects' ); + + $options = [ '' => '' ]; + + foreach ( $taxonomies as $taxonomy ) { + $options[ $taxonomy->name ] = $taxonomy->label; + } + + return $options; + } + + protected function render_post_header() { + ?> +
      role="listitem"> +
      + +
      +
      + +
      + +
      + get_instance_value( 'badge_taxonomy' ); + if ( empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) { + return; + } + + $terms = get_the_terms( get_the_ID(), $taxonomy ); + if ( empty( $terms[0] ) ) { + return; + } + ?> +
      name ); ?>
      + get_instance_value( 'thumbnail' ) ) { + return; + } + + $settings = $this->parent->get_settings(); + $setting_key = $this->get_control_id( 'thumbnail_size' ); + $settings[ $setting_key ] = [ + 'id' => get_post_thumbnail_id(), + ]; + $thumbnail_html = Group_Control_Image_Size::get_attachment_image_html( $settings, $setting_key ); + + if ( empty( $thumbnail_html ) ) { + return; + } + + $optional_attributes_html = $this->get_optional_link_attributes_html(); + + ?> + >
      + get_instance_value( 'show_badge' ) ) { + $this->render_badge(); + } + + if ( $this->get_instance_value( 'show_avatar' ) ) { + $this->render_avatar(); + } + } + + protected function render_post() { + $this->render_post_header(); + $this->render_thumbnail(); + $this->render_text_header(); + $this->render_title(); + $this->render_excerpt(); + $this->render_read_more(); + $this->render_text_footer(); + $this->render_meta_data(); + $this->render_post_footer(); + } +} diff --git a/modules/posts/skins/skin-classic.php b/modules/posts/skins/skin-classic.php new file mode 100644 index 00000000..9ec309a5 --- /dev/null +++ b/modules/posts/skins/skin-classic.php @@ -0,0 +1,194 @@ +start_controls_section( + 'section_design_box', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'box_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post' => 'border-style: solid; border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'box_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'content_padding', + [ + 'label' => esc_html__( 'Content Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__text' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + 'separator' => 'after', + ] + ); + + $this->start_controls_tabs( 'bg_effects_tabs' ); + + $this->start_controls_tab( 'classic_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .elementor-post', + ] + ); + + $this->add_control( + 'box_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'box_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'classic_style_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow_hover', + 'selector' => '{{WRAPPER}} .elementor-post:hover', + ] + ); + + $this->add_control( + 'box_bg_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'box_border_color_hover', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-post:hover' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } +} diff --git a/modules/posts/skins/skin-content-base.php b/modules/posts/skins/skin-content-base.php new file mode 100644 index 00000000..1201ba7c --- /dev/null +++ b/modules/posts/skins/skin-content-base.php @@ -0,0 +1,333 @@ +parent->get_name(); + add_action( 'elementor/element/' . $widget_name . '/section_layout/before_section_end', [ $this, 'register_skin_controls' ] ); + + if ( 'archive-posts' === $widget_name ) { + add_action( 'elementor/element/archive-posts/section_layout/after_section_end', [ $this, 'register_style_sections' ] ); + } else { + add_action( 'elementor/element/posts/section_query/after_section_end', [ $this, 'register_style_sections' ] ); + } + } + + public function get_title() { + return esc_html__( 'Full Content', 'elementor-pro' ); + } + + public function register_skin_controls( Widget_Base $widget ) { + $this->parent = $widget; + $this->register_post_count_control(); + $this->register_row_gap_control(); + $this->register_thumbnail_controls(); + $this->register_title_controls(); + $this->register_meta_data_controls(); + $this->register_link_controls(); + } + + public function register_thumbnail_controls() { + $this->add_control( + 'thumbnail', + [ + 'label' => esc_html__( 'Show Thumbnail', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'thumbnail', + 'prefix_class' => 'elementor-posts--show-', + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'thumbnail_size', + 'default' => 'medium', + 'exclude' => [ 'custom' ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => '', + ], + 'prefix_class' => 'elementor-posts--thumbnail-size-', + ] + ); + + $this->add_responsive_control( + 'item_ratio', + [ + 'label' => esc_html__( 'Image Ratio', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 0.66, + ], + 'tablet_default' => [ + 'size' => '', + ], + 'mobile_default' => [ + 'size' => 0.5, + ], + 'range' => [ + 'px' => [ + 'min' => 0.1, + 'max' => 2, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-posts-container .elementor-post__thumbnail' => 'padding-bottom: calc( {{SIZE}} * 100% );', + '{{WRAPPER}}:after' => 'content: "{{SIZE}}"; position: absolute; color: transparent;', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => '', + ], + ] + ); + + $this->add_responsive_control( + 'image_width', + [ + 'label' => esc_html__( 'Image Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 600, + ], + 'em' => [ + 'max' => 6, + ], + 'rem' => [ + 'max' => 6, + ], + ], + 'default' => [ + 'size' => 100, + 'unit' => '%', + ], + 'tablet_default' => [ + 'size' => '', + 'unit' => '%', + ], + 'mobile_default' => [ + 'size' => 100, + 'unit' => '%', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__thumbnail__link' => 'width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + $this->get_control_id( 'thumbnail!' ) => '', + ], + ] + ); + } + + public function register_design_controls() { + $this->register_additional_design_controls(); + $this->register_design_image_controls(); + $this->register_design_content_controls(); + $this->update_image_spacing_control(); + } + + public function register_row_gap_control() { + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 35, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}} .elementor-posts-container article' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + } + + // Update selectors for full content + public function update_image_spacing_control() { + $image_spacing_control = [ + 'selectors' => [ + '{{WRAPPER}} .elementor-posts--skin-full_content a.elementor-post__thumbnail__link' => 'margin-bottom: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-posts--skin-archive_full_content a.elementor-post__thumbnail__link' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ]; + $this->update_control( 'image_spacing', $image_spacing_control ); + } + + protected function render_thumbnail() { + $thumbnail = $this->get_instance_value( 'thumbnail' ); + + // In edit mode we render thumbnail to avoid server side rendering on each change. + if ( empty( $thumbnail ) && ! Plugin::elementor()->editor->is_edit_mode() ) { + return; + } + + $settings = $this->parent->get_settings(); + $setting_key = $this->get_control_id( 'thumbnail_size' ); + $settings[ $setting_key ] = [ + 'id' => get_post_thumbnail_id(), + ]; + $thumbnail_html = Group_Control_Image_Size::get_attachment_image_html( $settings, $setting_key ); + + if ( empty( $thumbnail_html ) ) { + return; + } + + $optional_attributes_html = $this->get_optional_link_attributes_html(); + + // PHPCS - `get_permalink` is safe. + ?> + > +
      +
      + ID ) ) { + // PHPCS - `get_the_password_form`. is safe. + echo get_the_password_form( $post->ID ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } + + // Avoid recursion + if ( isset( $did_posts[ $post->ID ] ) ) { + return; + } + + $level++; + $did_posts[ $post->ID ] = true; + // End avoid recursion + + $editor = Plugin::elementor()->editor; + $is_edit_mode = $editor->is_edit_mode(); + + if ( Plugin::elementor()->preview->is_preview_mode( $post->ID ) ) { + $content = Plugin::elementor()->preview->builder_wrapper( '' ); // XSS ok + } else { + /** + * @var ThemeBuilder ThemeBuilder + */ + $document = ThemeBuilder::instance()->get_document( $post->ID ); + // On view theme document show it's preview content. + if ( $document ) { + $preview_type = $document->get_settings( 'preview_type' ); + $preview_id = $document->get_settings( 'preview_id' ); + + if ( 0 === strpos( $preview_type, 'single' ) && ! empty( $preview_id ) ) { + $post = get_post( $preview_id ); + + if ( ! $post ) { + $level--; + + return; + } + } + } + + // Set edit mode as false, so don't render settings and etc. use the $is_edit_mode to indicate if we need the CSS inline + $editor->set_edit_mode( false ); + + // Print manually (and don't use `the_content()`) because it's within another `the_content` filter, and the Elementor filter has been removed to avoid recursion. + $content = Plugin::elementor()->frontend->get_builder_content( $post->ID, $with_css ); + + Plugin::elementor()->frontend->remove_content_filter(); + + if ( empty( $content ) ) { + // Split to pages. + setup_postdata( $post ); + + /** This filter is documented in wp-includes/post-template.php */ + // PHPCS - `get_the_content` is safe. + echo apply_filters( 'the_content', get_the_content() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + wp_link_pages( [ + 'before' => '', + 'link_before' => '', + 'link_after' => '', + 'pagelink' => '' . esc_html__( 'Page', 'elementor-pro' ) . ' %', + 'separator' => ', ', + ] ); + + Plugin::elementor()->frontend->add_content_filter(); + + $level--; + + // Restore edit mode state + Plugin::elementor()->editor->set_edit_mode( $is_edit_mode ); + + return; + } else { + Plugin::elementor()->frontend->remove_content_filters(); + $content = apply_filters( 'the_content', $content ); + Plugin::elementor()->frontend->restore_content_filters(); + } + } // End if(). + + // Restore edit mode state + Plugin::elementor()->editor->set_edit_mode( $is_edit_mode ); + + if ( $with_wrapper ) { + echo '
      ' . balanceTags( $content, true ) . '
      '; // XSS ok. + } else { + echo $content; // XSS ok. + } + + $level--; + + if ( 0 === $level ) { + $did_posts = []; + } + } + + protected function render_post() { + $this->render_post_header(); + $this->render_thumbnail(); + $this->render_text_header(); + $this->render_title(); + $this->render_meta_data(); + $this->render_post_content( true ); + $this->render_text_footer(); + $this->render_post_footer(); + } +} diff --git a/modules/posts/skins/skin-full-content.php b/modules/posts/skins/skin-full-content.php new file mode 100644 index 00000000..e8ad346c --- /dev/null +++ b/modules/posts/skins/skin-full-content.php @@ -0,0 +1,14 @@ + esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ]; + } + + protected function register_button_content_controls( $args = [] ) { + $default_args = [ + 'section_condition' => [], + 'button_text' => esc_html__( 'Click here', 'elementor-pro' ), + 'control_label_name' => esc_html__( 'Text', 'elementor-pro' ), + 'exclude_inline_options' => [], + ]; + + $args = wp_parse_args( $args, $default_args ); + + $this->add_control( + 'button_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + 'info' => esc_html__( 'Info', 'elementor-pro' ), + 'success' => esc_html__( 'Success', 'elementor-pro' ), + 'warning' => esc_html__( 'Warning', 'elementor-pro' ), + 'danger' => esc_html__( 'Danger', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-button-', + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'text', + [ + 'label' => $args['control_label_name'], + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => $args['button_text'], + 'placeholder' => $args['button_text'], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'url' => '#', + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'sm', + 'options' => self::get_button_sizes(), + 'style_transfer' => true, + 'condition' => array_merge( $args['section_condition'], [ 'size[value]!' => 'sm' ] ), // a workaround to hide the control, unless it's in use (not default). + ] + ); + + $this->add_control( + 'selected_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'condition' => $args['section_condition'], + 'exclude_inline_options' => $args['exclude_inline_options'], + ] + ); + + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $this->add_control( + 'icon_align', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => is_rtl() ? 'row-reverse' : 'row', + 'options' => [ + 'row' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$start}", + ], + 'row-reverse' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$end}", + ], + ], + 'selectors_dictionary' => [ + 'left' => is_rtl() ? 'row-reverse' : 'row', + 'right' => is_rtl() ? 'row' : 'row-reverse', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button-content-wrapper' => 'flex-direction: {{VALUE}};', + ], + 'condition' => array_merge( + $args['section_condition'], + [ + 'text!' => '', + 'selected_icon[value]!' => '', + ] + ), + ] + ); + + $this->add_control( + 'icon_indent', + [ + 'label' => esc_html__( 'Icon Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button .elementor-button-content-wrapper' => 'gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => array_merge( + $args['section_condition'], + [ + 'text!' => '', + 'selected_icon[value]!' => '', + ] + ), + ] + ); + + $this->add_control( + 'button_css_id', + [ + 'label' => esc_html__( 'Button ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => '', + 'title' => esc_html__( 'Add your custom id WITHOUT the Pound key. e.g: my-id', 'elementor-pro' ), + 'description' => sprintf( + /* translators: 1: `` opening tag, 2: `` closing tag. */ + esc_html__( 'Please make sure the ID is unique and not used elsewhere on the page. This field allows %1$sA-z 0-9%2$s & underscore chars without spaces.', 'elementor-pro' ), + '', + '' + ), + 'separator' => 'before', + 'condition' => $args['section_condition'], + ] + ); + } + + protected function register_button_style_controls( $args = [] ) { + $default_args = [ + 'section_condition' => [], + 'prefix_class' => 'elementor%s-align-', + 'alignment_default' => '', + 'content_alignment_default' => '', + ]; + + $args = wp_parse_args( $args, $default_args ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-h-align-stretch', + ], + ], + 'prefix_class' => $args['prefix_class'], + 'default' => $args['alignment_default'], + 'condition' => $args['section_condition'], + ] + ); + + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $this->add_responsive_control( + 'content_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-text-align-{$start}", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-text-align-{$end}", + ], + 'space-between' => [ + 'title' => esc_html__( 'Space between', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'default' => $args['content_alignment_default'], + 'selectors' => [ + '{{WRAPPER}} .elementor-button .elementor-button-content-wrapper' => 'justify-content: {{VALUE}};', + ], + 'condition' => array_merge( $args['section_condition'], [ 'align' => 'justify' ] ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-button', + 'condition' => $args['section_condition'], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'text_shadow', + 'selector' => '{{WRAPPER}} .elementor-button', + 'condition' => $args['section_condition'], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style', [ + 'condition' => $args['section_condition'], + ] ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'fill: {{VALUE}}; color: {{VALUE}};', + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-button', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + ], + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'button_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-button', + 'condition' => $args['section_condition'], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-button:hover svg, {{WRAPPER}} .elementor-button:focus svg' => 'fill: {{VALUE}};', + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background_hover', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus' => 'border-color: {{VALUE}};', + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-button:hover, {{WRAPPER}} .elementor-button:focus', + 'condition' => $args['section_condition'], + ] + ); + + $this->add_control( + 'button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'condition' => $args['section_condition'], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'border', + 'selector' => '{{WRAPPER}} .elementor-button', + 'separator' => 'before', + 'condition' => $args['section_condition'], + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => $args['section_condition'], + ] + ); + + $this->add_responsive_control( + 'text_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + 'condition' => $args['section_condition'], + ] + ); + } + + /** + * Render button widget output on the frontend. + * + * Written in PHP and used to generate the final HTML. + * + * @param \Elementor\Widget_Base|null $instance + * + * @since 3.4.0 + * @access protected + */ + protected function render_button( ?Widget_Base $instance = null ) { + if ( empty( $instance ) ) { + $instance = $this; + } + + $settings = $instance->get_settings_for_display(); + + if ( empty( $settings['text'] ) && empty( $settings['selected_icon']['value'] ) ) { + return; + } + + $instance->add_render_attribute( 'wrapper', 'class', 'elementor-button-wrapper' ); + + $instance->add_render_attribute( 'button', 'class', 'elementor-button' ); + + if ( ! empty( $settings['link']['url'] ) ) { + $instance->add_link_attributes( 'button', $settings['link'] ); + $instance->add_render_attribute( 'button', 'class', 'elementor-button-link' ); + } else { + $instance->add_render_attribute( 'button', 'role', 'button' ); + } + + if ( ! empty( $settings['button_css_id'] ) ) { + $instance->add_render_attribute( 'button', 'id', $settings['button_css_id'] ); + } + + if ( ! empty( $settings['size'] ) ) { + $instance->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['size'] ); + } else { + $instance->add_render_attribute( 'button', 'class', 'elementor-size-sm' ); // BC, to make sure the class is always present + } + + if ( ! empty( $settings['hover_animation'] ) ) { + $instance->add_render_attribute( 'button', 'class', 'elementor-animation-' . $settings['hover_animation'] ); + } + ?> + + get_settings(); + + $migrated = isset( $settings['__fa4_migrated']['selected_icon'] ); + $is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed(); + + $instance->add_render_attribute( [ + 'content-wrapper' => [ + 'class' => 'elementor-button-content-wrapper', + ], + 'icon' => [ + 'class' => 'elementor-button-icon', + ], + 'text' => [ + 'class' => 'elementor-button-text', + ], + ] ); + + // TODO: replace the protected with public + //$instance->add_inline_editing_attributes( 'text', 'none' ); + ?> + print_render_attribute_string( 'content-wrapper' ); ?>> + + print_render_attribute_string( 'icon' ); ?>> + 'true' ] ); + else : ?> + + + + + + print_render_attribute_string( 'text' ); ?>> + + + get_widgets_that_support_pagination(); + + Plugin::elementor()->db->iterate_data( + $elements, + $this->check_pagination_handler( $posts_widgets, $current_page, $is_valid ) + ); + + return $is_valid; + } + + /** + * Get all widgets that may add pagination. + * + * @return array + */ + public function get_widgets_that_support_pagination() { + $widgets = Plugin::elementor()->widgets_manager->get_widget_types(); + + $posts_widgets = []; + + foreach ( $widgets as $widget ) { + if ( $widget instanceof Posts_Base || $widget instanceof Global_Widget ) { + $posts_widgets[] = $widget->get_name(); + } + } + + return $posts_widgets; + } + + /** + * @return void + */ + public function check_pagination_handler( array $posts_widgets, $current_page, &$is_valid ) { + return function ( $element ) use ( &$is_valid, $posts_widgets, $current_page ) { + if ( ! $this->is_valid_post_widget( $element, $posts_widgets ) ) { + return; + } + + $is_valid = $this->should_allow_pagination( $element, $current_page ); + }; + } + + /** + * @return bool + */ + private function is_valid_post_widget( $element, $posts_widgets ) { + return isset( $element['widgetType'] ) && in_array( $element['widgetType'], $posts_widgets, true ); + } + + /** + * @return bool + */ + private function widget_has_pagination( $element ) { + return ! empty( $element['settings']['pagination_type'] ); + } + + /** + * @return bool + */ + private function should_allow_pagination( $element, $current_page ) { + if ( ! $this->widget_has_pagination( $element ) ) { + return false; + } + + $using_ajax_pagination = in_array($element['settings']['pagination_type'], [ + Posts_Base::LOAD_MORE_ON_CLICK, + Posts_Base::LOAD_MORE_INFINITE_SCROLL, + ], true); + + if ( empty( $element['settings']['pagination_page_limit'] ) || $using_ajax_pagination ) { + return true; + } + + return (int) $current_page <= (int) $element['settings']['pagination_page_limit']; + } + + public function get_base_url() { + if ( is_page() || is_single() ) { + // Check if it's a normal page. + return get_permalink(); + } elseif ( is_year() ) { + return get_year_link( get_query_var( 'year' ) ); + } elseif ( is_month() ) { + return get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) ); + } elseif ( is_day() ) { + return get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) ); + } elseif ( is_category() || is_tag() || is_tax() ) { + $queried_object = get_queried_object(); + return get_term_link( $queried_object->term_id, $queried_object->taxonomy ); + } elseif ( is_author() ) { + return get_author_posts_url( get_the_author_meta( 'ID' ) ); + } elseif ( is_search() ) { + return get_search_link(); + } elseif ( is_archive() ) { + // Check if it's an archive page. + return get_post_type_archive_link( get_post_type() ); + } elseif ( is_singular() && 'post' !== get_post_type() && 'page' !== get_post_type() ) { + // Check if it's a single post/page of a custom post type. + $post_type = get_post_type_object( get_post_type() ); + + if ( $post_type->has_archive ) { + return get_post_type_archive_link( get_post_type() ); + } else { + return get_permalink(); + } + } elseif ( $this->is_posts_page() ) { + return get_permalink( get_option( 'page_for_posts' ) ); + } + + // Fallback to home URL. + return home_url( '/' ); + } + + /** + * Determines whether the query is for an existing blog posts index page + * + * @param bool $custom_page_option + * @return bool + */ + private function is_posts_page( $custom_page_option = true ) { + if ( $custom_page_option ) { + return ! is_front_page() && is_home(); + } + + $posts_page_id = (int) get_option( 'page_for_posts' ); + $base_url = get_query_var( 'pagination_base_url' ); + + if ( ! empty( $base_url ) ) { + $post_id = url_to_postid( $base_url ); + + return $posts_page_id === $post_id; + } + + return false; + } +} diff --git a/modules/posts/traits/query-note-trait.php b/modules/posts/traits/query-note-trait.php new file mode 100644 index 00000000..5c2b72c6 --- /dev/null +++ b/modules/posts/traits/query-note-trait.php @@ -0,0 +1,46 @@ +documents->get_current() ) { + $id = Utils::get_current_post_id(); + } else { + $id = get_the_ID(); + } + + return 'archive' === get_post_meta( $id, Document::TYPE_META_KEY, true ); + } + + public function inject_archive_query_note( $placement_id, $condition_id, $widget ) { + $archive_setting_url = admin_url( 'options-reading.php' ); + + $widget->start_injection( [ + 'of' => $placement_id, + 'at' => 'before', + ] ); + + $widget->add_control( + 'archive_query_note', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => sprintf( + esc_html__( 'The amount of items displayed in your Archive is set in your WordPress settings. %s', 'elementor-pro' ), + '' . esc_html__( 'Take me there', 'elementor-pro' ) . '' + ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + $condition_id => 'current_query', + ], + ] + ); + + $widget->end_injection(); + } +} diff --git a/modules/posts/widgets/portfolio.php b/modules/posts/widgets/portfolio.php new file mode 100644 index 00000000..4cc64858 --- /dev/null +++ b/modules/posts/widgets/portfolio.php @@ -0,0 +1,727 @@ +_query; + } + + protected function register_controls() { + $this->register_query_section_controls(); + } + + private function register_query_section_controls() { + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '3', + 'tablet_default' => '2', + 'mobile_default' => '1', + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-grid%s-', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Posts Per Page', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'thumbnail_size', + 'exclude' => [ 'custom' ], + 'default' => 'medium', + 'prefix_class' => 'elementor-portfolio--thumbnail-size-', + ] + ); + + $this->add_control( + 'masonry', + [ + 'label' => esc_html__( 'Masonry', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'condition' => [ + 'columns!' => '1', + ], + 'render_type' => 'ui', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'item_ratio', + [ + 'label' => esc_html__( 'Item Ratio', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 0.66, + ], + 'range' => [ + 'px' => [ + 'min' => 0.1, + 'max' => 2, + 'step' => 0.01, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post__thumbnail__link' => 'padding-bottom: calc( {{SIZE}} * 100% )', + '{{WRAPPER}}:after' => 'content: "{{SIZE}}"; position: absolute; color: transparent;', + ], + 'condition' => [ + 'masonry' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'show_title', + [ + 'label' => esc_html__( 'Show Title', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'h3', + 'condition' => [ + 'show_title' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_group_control( + Group_Control_Related::get_type(), + [ + 'name' => 'posts', + 'presets' => [ 'full' ], + 'exclude' => [ + 'posts_per_page', //use the one from Layout section + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'filter_bar', + [ + 'label' => esc_html__( 'Filter Bar', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'show_filter_bar', + [ + 'label' => esc_html__( 'Show', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'taxonomy', + [ + 'label' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'label_block' => true, + 'default' => [], + 'options' => $this->get_taxonomies(), + 'condition' => [ + 'show_filter_bar' => 'yes', + 'posts_post_type!' => 'by_id', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_design_layout', + [ + 'label' => esc_html__( 'Items', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + /* + * The `item_gap` control is replaced by `column_gap` and `row_gap` controls since v 2.1.6 + * It is left (hidden) in the widget, to provide compatibility with older installs + */ + + $this->add_control( + 'item_gap', + [ + 'label' => esc_html__( 'Item Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}; --grid-column-gap: {{SIZE}}{{UNIT}};', + ], + 'frontend_available' => true, + 'classes' => 'elementor-hidden', + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => ' --grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-portfolio-item__img, {{WRAPPER}} .elementor-portfolio-item__overlay' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_design_overlay', + [ + 'label' => esc_html__( 'Item Overlay', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'color_background', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} a .elementor-portfolio-item__overlay' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'color_title', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'separator' => 'before', + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} a .elementor-portfolio-item__title' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'show_title' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography_title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-portfolio-item__title', + 'condition' => [ + 'show_title' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_design_filter', + [ + 'label' => esc_html__( 'Filter Bar', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_filter_bar' => 'yes', + ], + ] + ); + + $this->add_control( + 'color_filter', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-portfolio__filter' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'color_filter_active', + [ + 'label' => esc_html__( 'Active Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-portfolio__filter.elementor-active' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography_filter', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-portfolio__filter', + ] + ); + + $this->add_control( + 'filter_item_spacing', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-portfolio__filter:not(:last-child)' => 'margin-right: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}} .elementor-portfolio__filter:not(:first-child)' => 'margin-left: calc({{SIZE}}{{UNIT}}/2)', + ], + ] + ); + + $this->add_control( + 'filter_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-portfolio__filters' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function get_taxonomies() { + $taxonomies = get_taxonomies( [ 'show_in_nav_menus' => true ], 'objects' ); + + $options = [ '' => '' ]; + + foreach ( $taxonomies as $taxonomy ) { + $options[ $taxonomy->name ] = $taxonomy->label; + } + + return $options; + } + + protected function get_posts_tags() { + $taxonomy = $this->get_settings( 'taxonomy' ); + + foreach ( $this->_query->posts as $post ) { + if ( ! $taxonomy ) { + $post->tags = []; + + continue; + } + + $tags = wp_get_post_terms( $post->ID, $taxonomy ); + + $tags_slugs = []; + + foreach ( $tags as $tag ) { + $tags_slugs[ $tag->term_id ] = $tag; + } + + $post->tags = $tags_slugs; + } + } + + public function query_posts() { + + $query_args = [ + 'posts_per_page' => $this->get_settings( 'posts_per_page' ), + ]; + + /** @var Module_Query $elementor_query */ + $elementor_query = Module_Query::instance(); + $this->_query = $elementor_query->get_query( $this, 'posts', $query_args, [] ); + } + + public function render() { + $this->query_posts(); + + $wp_query = $this->get_query(); + + if ( ! $wp_query->found_posts ) { + return; + } + + $this->get_posts_tags(); + + $this->render_loop_header(); + + while ( $wp_query->have_posts() ) { + $wp_query->the_post(); + + $this->render_post(); + } + + $this->render_loop_footer(); + + wp_reset_postdata(); + } + + protected function render_thumbnail() { + $settings = $this->get_settings(); + + $settings['thumbnail_size'] = [ + 'id' => get_post_thumbnail_id(), + ]; + ?> +
      + +
      + get_settings( 'taxonomy' ); + + if ( ! $taxonomy ) { + return; + } + + $terms = []; + + foreach ( $this->_query->posts as $post ) { + $terms += $post->tags; + } + + if ( empty( $terms ) ) { + return; + } + + usort( $terms, function( $a, $b ) { + return strcmp( $a->name, $b->name ); + } ); + + ?> +
        +
      • + +
      • name ); ?>
      • + +
      + get_settings( 'show_title' ) ) { + return; + } + + $tag = $this->get_settings( 'title_tag' ); + ?> + < class="elementor-portfolio-item__title"> + + > + tags ) { + return; + } + + $separator = ''; + + $tags_array = []; + + foreach ( $post->tags as $tag ) { + $tags_array[] = '' . esc_html( $tag->name ) . ''; + } + + ?> +
      + + +
      + term_id; + }, $post->tags ); + + $classes = [ + 'elementor-portfolio-item', + 'elementor-post', + implode( ' ', $tags_classes ), + ]; + + // PHPCS - `get_permalink` is safe. + ?> +
      role="listitem"> + + + +
      + +
      + +
      + get_settings( 'show_filter_bar' ) ) { + $this->render_filter_menu(); + } + ?> +
      + +
      + render_post_header(); + $this->render_thumbnail(); + $this->render_overlay_header(); + $this->render_title(); + // $this->render_categories_names(); + $this->render_overlay_footer(); + $this->render_post_footer(); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'posts'; + } +} diff --git a/modules/posts/widgets/posts-base.php b/modules/posts/widgets/posts-base.php new file mode 100644 index 00000000..30b8ecf2 --- /dev/null +++ b/modules/posts/widgets/posts-base.php @@ -0,0 +1,924 @@ +query; + } + + public function render() {} + + public function register_load_more_button_style_controls() { + $this->add_control( + 'heading_load_more_style_button', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + ] + ); + + $this->register_button_style_controls( [ + 'section_condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + 'prefix_class' => 'load-more-align-', + 'alignment_default' => 'center', + ] ); + } + + public function register_load_more_message_style_controls() { + $this->add_control( + 'heading_load_more_on_click_no_posts_message', + [ + 'label' => esc_html__( 'No More Posts Message', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'heading_load_more_on_click_infinity_scroll_no_posts_message', + [ + 'label' => esc_html__( 'No More Posts Message', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'pagination_type' => 'load_more_infinite_scroll', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'load_more_no_posts_message', + 'selector' => '{{WRAPPER}} .e-load-more-message', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + ] + ); + + $this->add_control( + 'load_more_no_posts_message_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => '--load-more-message-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'load_more_spinner_color', + [ + 'label' => esc_html__( 'Spinner Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => '--load-more-spinner-color: {{VALUE}};', + ], + 'separator' => 'before', + 'condition' => [ + 'load_more_spinner[value]!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'load_more_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--load-more—spacing: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + } + + public function register_pagination_section_controls() { + $this->start_controls_section( + 'section_pagination', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'condition' => [ + '_skin!' => [ + LoopBuilderModule::LOOP_POST_TAXONOMY_SKIN_ID, + WoocommerceModule::LOOP_PRODUCT_TAXONOMY_SKIN_ID, + ], + ], + ] + ); + + $this->add_control( + 'pagination_type', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => $this->get_pagination_type_options(), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pagination_page_limit', + [ + 'label' => esc_html__( 'Page Limit', 'elementor-pro' ), + 'default' => '5', + 'condition' => [ + 'pagination_type!' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + '', + ], + ], + ] + ); + + $this->add_control( + 'pagination_numbers_shorten', + [ + 'label' => esc_html__( 'Shorten', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_prev_label', + [ + 'label' => esc_html__( 'Previous Label', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( '« Previous', 'elementor-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_next_label', + [ + 'label' => esc_html__( 'Next Label', 'elementor-pro' ), + 'default' => esc_html__( 'Next »', 'elementor-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'pagination_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .elementor-pagination' => 'text-align: {{VALUE}};', + ], + 'condition' => [ + 'pagination_type!' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + '', + ], + ], + ] + ); + + $this->add_control( + 'pagination_individual_divider', + [ + 'type' => Controls_Manager::DIVIDER, + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_individual_handle', + [ + 'label' => esc_html__( 'Individual Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_individual_handle_message', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'For multiple Posts Widgets on the same page, toggle this on to control the pagination for each individually. Note: It affects the page\'s URL structure.', 'elementor-pro' ), + 'content_classes' => 'elementor-control-field-description', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + 'prev_next', + ], + ], + ] + ); + + $this->add_control( + 'load_more_spinner', + [ + 'label' => esc_html__( 'Spinner', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-spinner', + 'library' => 'fa-solid', + ], + 'exclude_inline_options' => [ 'svg' ], + 'recommended' => [ + 'fa-solid' => [ + 'spinner', + 'cog', + 'sync', + 'sync-alt', + 'asterisk', + 'circle-notch', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'heading_load_more_button', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + ] + ); + + $this->register_button_content_controls( [ + 'button_text' => esc_html__( 'Load More', 'elementor-pro' ), + 'control_label_name' => esc_html__( 'Button Text', 'elementor-pro' ), + 'section_condition' => [ + 'pagination_type' => 'load_more_on_click', + ], + 'exclude_inline_options' => [ 'svg' ], + ] ); + + $this->remove_control( 'button_type' ); + $this->remove_control( 'link' ); + $this->remove_control( 'size' ); + + $this->add_control( + 'heading_load_more_no_posts_message', + [ + 'label' => esc_html__( 'No More Posts Message', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_responsive_control( + 'load_more_no_posts_message_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--load-more-message-alignment: {{VALUE}};', + ], + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + ], + ] + ); + + $this->add_control( + 'load_more_no_posts_message_switcher', + [ + 'label' => esc_html__( 'Custom Messages', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + ], + ] + ); + + $this->add_control( + 'load_more_no_posts_custom_message', + [ + 'label' => esc_html__( 'No more posts message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'No more posts to show', 'elementor-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + 'load_more_no_posts_message_switcher' => 'yes', + ], + 'label_block' => true, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + + // Pagination style controls for prev/next and numbers pagination. + $this->start_controls_section( + 'section_pagination_style', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'pagination_type!' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + '', + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'pagination_typography', + 'selector' => '{{WRAPPER}} .elementor-pagination', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + ] + ); + + $this->add_control( + 'pagination_color_heading', + [ + 'label' => esc_html__( 'Colors', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'pagination_colors' ); + + $this->start_controls_tab( + 'pagination_color_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-pagination .page-numbers:not(.dots)' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'pagination_color_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-pagination a.page-numbers:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'pagination_color_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_active_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-pagination .page-numbers.current' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'pagination_spacing', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'separator' => 'before', + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-pagination .page-numbers:not(:first-child)' => 'margin-left: calc( {{SIZE}}{{UNIT}}/2 );', + 'body:not(.rtl) {{WRAPPER}} .elementor-pagination .page-numbers:not(:last-child)' => 'margin-right: calc( {{SIZE}}{{UNIT}}/2 );', + 'body.rtl {{WRAPPER}} .elementor-pagination .page-numbers:not(:first-child)' => 'margin-right: calc( {{SIZE}}{{UNIT}}/2 );', + 'body.rtl {{WRAPPER}} .elementor-pagination .page-numbers:not(:last-child)' => 'margin-left: calc( {{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_responsive_control( + 'pagination_spacing_top', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-pagination' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + // Pagination style controls for on-load pagination with type on-click/infinity-scroll. + $this->start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'pagination_type' => [ + 'load_more_on_click', + 'load_more_infinite_scroll', + ], + ], + ] + ); + + $this->register_load_more_button_style_controls(); + + $this->register_load_more_message_style_controls(); + + $this->end_controls_section(); + } + + abstract public function query_posts(); + + public function get_current_page() { + if ( '' === $this->get_settings_for_display( 'pagination_type' ) ) { + return 1; + } + + return max( + 1, + get_query_var( 'paged' ), + get_query_var( 'page' ), + Utils::_unstable_get_super_global_value( $_GET, 'e-page-' . $this->get_id() ) + ); + } + + public function is_rest_request() { + $request_uri = Utils::_unstable_get_super_global_value( $_SERVER, 'REQUEST_URI' ); + + return false !== wp_get_referer() && + isset( $_SERVER['REQUEST_URI'] ) && + ( false !== strpos( $request_uri, 'wp-json' ) || false !== strpos( $request_uri, 'rest_route' ) ); + } + + public function get_wp_link_page( $i ) { + if ( ( ! is_singular() || is_front_page() ) && ! $this->is_rest_request() && ! $this->is_allow_to_use_custom_page_option() ) { + return get_pagenum_link( $i ); + } + + // Based on wp-includes/post-template.php:957 `_wp_link_page`. + global $wp_rewrite; + $post = get_post(); + $query_args = []; + $url = get_permalink(); + + if ( $this->is_rest_request() ) { + $link_unescaped = wp_get_referer(); + $post_id = url_to_postid( $link_unescaped ); + + if ( $post_id > 0 ) { + $post = get_post( $post_id ); + } + + $url = $this->get_base_url_for_rest_request( $post_id, $url ); + } + + if ( $i > 1 ) { + if ( '' === get_option( 'permalink_structure' ) || in_array( $post->post_status, [ 'draft', 'pending' ] ) ) { + $url = add_query_arg( $this->get_wp_pagination_query_var(), $i, $url ); + } elseif ( get_option( 'show_on_front' ) === 'page' && (int) get_option( 'page_on_front' ) === $post->ID ) { + $url = trailingslashit( $url ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . $i, 'single_paged' ); + } else { + $url = trailingslashit( $url ) . user_trailingslashit( $i, 'single_paged' ); + } + } + + if ( $i > 1 && $this->is_allow_to_use_custom_page_option() ) { + $url = $this->get_wp_link_page_url_for_custom_page_option( $url, $i, $post_id ?? 0 ); + } + + if ( 1 === $i && $this->is_allow_to_use_custom_page_option() ) { + $url = $this->get_base_url(); + } + + if ( is_preview() ) { + $url = $this->get_wp_link_page_url_for_preview( $post, $query_args, $url ); + } + + if ( $this->is_rest_request() ) { + $url = $this->get_wp_link_page_url_for_rest_request( $url, $link_unescaped ); + } + + if ( ! $this->is_rest_request() && $this->current_url_contains_taxonomy_filter() && ! is_preview() ) { + $url = $this->get_wp_link_page_url_for_normal_page_load( $url ); + } + + return esc_url( apply_filters( 'elementor/posts/wp_link_page', $url ) ); + } + + public function is_allow_to_use_custom_page_option() { + return 'ajax' === $this->get_settings_for_display( 'pagination_load_type' ) || 'yes' === $this->get_settings_for_display( 'pagination_individual_handle' ); + } + + protected function get_base_url_for_rest_request( $post_id, $url ) { + if ( $post_id > 0 ) { + return get_permalink( $post_id ); + } + + global $wp_rewrite; + + if ( $wp_rewrite->using_permalinks() && ( $this->current_url_contains_taxonomy_filter() || $this->referer_contains_taxonomy_filter() ) ) { + $url = $this->is_allow_to_use_custom_page_option() ? get_query_var( 'pagination_base_url' ) : get_query_var( 'pagination_base_url' ) . user_trailingslashit( "$wp_rewrite->pagination_base/", 'single_paged' ); + } else { + $url = remove_query_arg( 'p', $url ); + } + + return $url; + } + + protected function get_wp_link_page_url_for_preview( $post, $query_args, $url ) { + if ( 'draft' === $post->post_status || ! isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) { + return $url; + } + + $query_args['preview_id'] = Utils::_unstable_get_super_global_value( $_GET, 'preview_id' ); + $query_args['preview_nonce'] = Utils::_unstable_get_super_global_value( $_GET, 'preview_nonce' ); + + if ( $this->is_rest_request() || ! $this->current_url_contains_taxonomy_filter() ) { + return get_preview_post_link( $post, $query_args, $url ); + } + + wp_parse_str( htmlspecialchars_decode( Utils::_unstable_get_super_global_value( $_SERVER, 'QUERY_STRING' ) ), $query_params ); + + foreach ( $query_params as $param_key => $param_value ) { + if ( false !== strpos( $param_key, 'e-filter-' ) ) { + $query_args[ $param_key ] = $param_value; + } + } + + return get_preview_post_link( $post, $query_args, $url ); + } + + protected function get_wp_link_page_url_for_rest_request( $url, $link_unescaped ) { + $url_components = wp_parse_url( $link_unescaped ); + $query_args = []; + + if ( isset( $url_components['query'] ) ) { + wp_parse_str( $url_components['query'], $query_args ); + } + + $url = ! empty( $query_args ) ? $url . '&' . http_build_query( $query_args ) : $url; + + return $this->format_query_string_concatenation( $url ); + } + + protected function get_wp_link_page_url_for_normal_page_load( $url ) { + wp_parse_str( htmlspecialchars_decode( Utils::_unstable_get_super_global_value( $_SERVER, 'QUERY_STRING' ) ), $query_params ); + + $e_filters = ''; + + foreach ( $query_params as $param_key => $param_value ) { + if ( false !== strpos( $param_key, 'e-filter' ) ) { + $e_filters .= '&' . $param_key . '=' . $param_value; + } + } + + return $this->format_query_string_concatenation( $url . $e_filters ); + } + + public function current_url_contains_taxonomy_filter() { + return false !== strpos( Utils::_unstable_get_super_global_value( $_SERVER, 'QUERY_STRING' ), 'e-filter-' ); + } + + public function referer_contains_taxonomy_filter() { + return false !== strpos( Utils::_unstable_get_super_global_value( $_SERVER, 'HTTP_REFERER' ), 'e-filter-' ); + } + + protected function format_query_string_concatenation( $input ) { + if ( false === strpos( $input, '?' ) ) { + // If "?" doesn't exist in the input URL, replace the first "&" with "?" + $input = preg_replace( '/&/', '?', $input, 1 ); + } + + return $input; + } + + public function get_posts_nav_link( $page_limit = null ) { + if ( ! $page_limit ) { + $page_limit = $this->query->max_num_pages; + } + + $return = []; + + $paged = $this->get_current_page(); + + $link_template = '%s'; + $disabled_template = '%s'; + + if ( $paged > 1 ) { + $next_page = intval( $paged ) - 1; + if ( $next_page < 1 ) { + $next_page = 1; + } + + $return['prev'] = sprintf( $link_template, 'prev', $this->get_wp_link_page( $next_page ), $this->get_settings_for_display( 'pagination_prev_label' ) ); + } else { + $return['prev'] = sprintf( $disabled_template, 'prev', $this->get_settings_for_display( 'pagination_prev_label' ) ); + } + + $next_page = intval( $paged ) + 1; + + if ( $next_page <= $page_limit ) { + $return['next'] = sprintf( $link_template, 'next', $this->get_wp_link_page( $next_page ), $this->get_settings_for_display( 'pagination_next_label' ) ); + } else { + $return['next'] = sprintf( $disabled_template, 'next', $this->get_settings_for_display( 'pagination_next_label' ) ); + } + + return $return; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->end_controls_section(); + } + + protected function get_pagination_type_options() { + return [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'numbers' => esc_html__( 'Numbers', 'elementor-pro' ), + 'prev_next' => esc_html__( 'Previous/Next', 'elementor-pro' ), + 'numbers_and_prev_next' => esc_html__( 'Numbers', 'elementor-pro' ) . ' + ' . esc_html__( 'Previous/Next', 'elementor-pro' ), + self::LOAD_MORE_ON_CLICK => esc_html__( 'Load on Click', 'elementor-pro' ), + self::LOAD_MORE_INFINITE_SCROLL => esc_html__( 'Infinite Scroll', 'elementor-pro' ), + ]; + } + + public function render_plain_content() {} + + /** + * @param string $url + * @param int $i + * @param int $post_id + * @return string + */ + private function get_wp_link_page_url_for_custom_page_option( $url, $i, $post_id ) { + $base_raw_url = $this->is_rest_request() ? $this->get_base_url_for_rest_request( $post_id, $url ) : $this->get_base_url(); + $pagination_key = 'e-page-' . $this->get_id(); + + if ( 'yes' === $this->get_settings_for_display( 'pagination_individual_handle' ) ) { + $base_raw_url .= $this->get_pagination_query_vars_for_others_individually_paginated_widgets( $pagination_key ); + } + + return $this->format_query_string_concatenation( $base_raw_url . '&' . $pagination_key . '=' . $i ); + } + + private function get_pagination_query_vars_for_others_individually_paginated_widgets( string $pagination_key ): string { + wp_parse_str( htmlspecialchars_decode( Utils::_unstable_get_super_global_value( $_SERVER, 'QUERY_STRING' ) ), $query_params ); + + $e_page = ''; + + foreach ( $query_params as $param_key => $param_value ) { + if ( false !== strpos( $param_key, 'e-page' ) && $pagination_key !== $param_key ) { + $e_page .= '&' . $param_key . '=' . $param_value; + } + } + + return $e_page; + } + + /** + * @return string + */ + private function get_wp_pagination_query_var() { + if ( '' === get_option( 'permalink_structure' ) && $this->is_posts_page( $this->is_allow_to_use_custom_page_option() ) ) { + return 'paged'; + } + + return 'page'; + } +} diff --git a/modules/posts/widgets/posts.php b/modules/posts/widgets/posts.php new file mode 100644 index 00000000..e9e6da0a --- /dev/null +++ b/modules/posts/widgets/posts.php @@ -0,0 +1,134 @@ +add_skin( new Skins\Skin_Classic( $this ) ); + $this->add_skin( new Skins\Skin_Cards( $this ) ); + $this->add_skin( new Skins\Skin_Full_Content( $this ) ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->register_query_section_controls(); + $this->register_pagination_section_controls(); + } + + /** + * Get Query Name + * + * Returns the query control name used in the widget's main query. + * + * @since 3.8.0 + * + * @return string + */ + public function get_query_name() { + return $this->get_name(); + } + + public function query_posts() { + $query_args = [ + 'posts_per_page' => $this->get_posts_per_page_value(), + 'paged' => $this->get_current_page(), + 'has_custom_pagination' => $this->is_allow_to_use_custom_page_option(), + ]; + + /** @var Module_Query $elementor_query */ + $elementor_query = Module_Query::instance(); + $this->query = $elementor_query->get_query( $this, $this->get_query_name(), $query_args, [] ); + } + + /** + * Get Posts Per Page Value + * + * Returns the value of the Posts Per Page control of the widget. This method was created because in some cases, + * the control is registered in the widget, and in some cases, it is registered in a widget skin. + * + * @since 3.8.0 + * @access protected + * + * @return mixed + */ + protected function get_posts_per_page_value() { + return $this->get_current_skin()->get_instance_value( 'posts_per_page' ); + } + + protected function register_query_section_controls() { + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_group_control( + Group_Control_Related::get_type(), + [ + 'name' => $this->get_name(), + 'presets' => [ 'full' ], + 'exclude' => [ + 'posts_per_page', //use the one from Layout section + ], + ] + ); + + if ( $this->is_editing_archive_template() ) { + $this->inject_archive_query_note( 'posts_query_id', 'posts_post_type', $this ); + } + + $this->end_controls_section(); + } +} diff --git a/modules/pricing/module.php b/modules/pricing/module.php new file mode 100644 index 00000000..f2f49363 --- /dev/null +++ b/modules/pricing/module.php @@ -0,0 +1,77 @@ +get_widgets_style_list(); + + foreach ( $widget_styles as $widget_style_name ) { + wp_register_style( + $widget_style_name, + $this->get_css_assets_url( $widget_style_name, null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + wp_register_style( + 'e-ribbon', + $this->get_css_assets_url( 'ribbon', 'assets/css/conditionals/', true ), + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function enqueue_preview_styles() { + wp_enqueue_style( 'e-ribbon' ); + } + + private function get_widgets_style_list(): array { + return [ + 'widget-price-list', + 'widget-price-table', + ]; + } +} diff --git a/modules/pricing/widgets/price-list.php b/modules/pricing/widgets/price-list.php new file mode 100644 index 00000000..7eaa4e0c --- /dev/null +++ b/modules/pricing/widgets/price-list.php @@ -0,0 +1,765 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-price-list' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_list', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'price', + [ + 'label' => esc_html__( 'Price', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'label_block' => 'true', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'item_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => '', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'default' => [ 'url' => '#' ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'price_list', + [ + 'label' => esc_html__( 'List Items', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'title' => esc_html__( 'First item on the list', 'elementor-pro' ), + 'item_description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'price' => '$20', + 'link' => [ 'url' => '#' ], + ], + [ + 'title' => esc_html__( 'Second item on the list', 'elementor-pro' ), + 'item_description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'price' => '$9', + 'link' => [ 'url' => '#' ], + ], + [ + 'title' => esc_html__( 'Third item on the list', 'elementor-pro' ), + 'item_description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'price' => '$32', + 'link' => [ 'url' => '#' ], + ], + ], + 'title_field' => '{{{ title }}}', + ] + ); + + $this->add_control( + 'title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'span', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'description_tag', + [ + 'label' => esc_html__( 'Description HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'p', + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'image_size', + 'default' => 'thumbnail', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_list_style', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'vertical_align', + [ + 'label' => esc_html__( 'Vertical Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-item' => 'align-items: {{VALUE}};', + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'bottom' => 'flex-end', + ], + 'default' => 'top', + ] + ); + + $this->add_responsive_control( + 'row_gap', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'separator' => 'before', + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list li:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + 'default' => [ + 'size' => 20, + ], + ] + ); + + $this->add_responsive_control( + 'image_spacing', + [ + 'label' => esc_html__( 'Image Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body.rtl {{WRAPPER}} .elementor-price-list-image' => 'padding-left: calc({{SIZE}}{{UNIT}}/2);', + 'body.rtl {{WRAPPER}} .elementor-price-list-image + .elementor-price-list-text' => 'padding-right: calc({{SIZE}}{{UNIT}}/2);', + 'body:not(.rtl) {{WRAPPER}} .elementor-price-list-image' => 'padding-right: calc({{SIZE}}{{UNIT}}/2);', + 'body:not(.rtl) {{WRAPPER}} .elementor-price-list-image + .elementor-price-list-text' => 'padding-left: calc({{SIZE}}{{UNIT}}/2);', + ], + 'default' => [ + 'size' => 20, + ], + ] + ); + + $this->add_responsive_control( + 'content_spacing', + [ + 'label' => esc_html__( 'Content Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-header' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading__title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-header' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-price-list-header', + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'text_stroke', + 'selector' => '{{WRAPPER}} .elementor-price-list-header', + ] + ); + + $this->add_control( + 'price_title', + [ + 'label' => __( 'Price', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'price_color', + [ + 'label' => __( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-price' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'price_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-price-list-price', + ] + ); + + $this->add_control( + 'heading_item_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'description_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-description' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-price-list-description', + ] + ); + + $this->add_control( + 'heading_separator', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'separator_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + ], + 'default' => 'dotted', + 'render_type' => 'template', + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-separator' => 'border-bottom-style: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'separator_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 10, + ], + 'em' => [ + 'max' => 1, + ], + 'rem' => [ + 'max' => 1, + ], + ], + 'condition' => [ + 'separator_style!' => 'none', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-separator' => 'border-bottom-width: {{SIZE}}{{UNIT}}', + ], + 'default' => [ + 'size' => 2, + ], + ] + ); + + $this->add_control( + 'separator_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-separator' => 'border-bottom-color: {{VALUE}};', + ], + 'condition' => [ + 'separator_style!' => 'none', + ], + ] + ); + + $this->add_control( + 'separator_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 40, + ], + 'em' => [ + 'max' => 4, + ], + 'rem' => [ + 'max' => 4, + ], + ], + 'condition' => [ + 'separator_style!' => 'none', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-separator' => 'margin-left: {{SIZE}}{{UNIT}}; margin-right: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-list-image img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + private function render_image( $item, $instance ) { + $image_id = $item['image']['id']; + $image_size = $instance['image_size_size']; + if ( 'custom' === $image_size ) { + $image_src = Group_Control_Image_Size::get_attachment_image_src( $image_id, 'image_size', $instance ); + } else { + $image_src = wp_get_attachment_image_src( $image_id, $image_size ); + $image_src = $image_src[0]; + } + + return sprintf( + '%s', + esc_url( $image_src ), + esc_attr( wp_kses_post( $item['title'] ) ) + ); + } + + private function render_item_header( $item ) { + $url = $item['link']['url']; + + $item_id = $item['_id']; + + if ( $url ) { + $unique_link_id = 'item-link-' . $item_id; + + $this->add_render_attribute( $unique_link_id, 'class', 'elementor-price-list-item' ); + + $this->add_link_attributes( $unique_link_id, $item['link'] ); + + return '
    • get_render_attribute_string( $unique_link_id ) . '>'; + } else { + return '
    • '; + } + } + + private function render_item_footer( $item ) { + if ( $item['link']['url'] ) { + return '
    • '; + } else { + return ''; + } + } + + protected function render() { + $settings = $this->get_settings_for_display(); ?> + +
        + + $item ) : ?> + get_repeater_setting_key( 'title', 'price_list', $index ); + $description_repeater_setting_key = $this->get_repeater_setting_key( 'item_description', 'price_list', $index ); + $this->add_inline_editing_attributes( $title_repeater_setting_key ); + $this->add_inline_editing_attributes( $description_repeater_setting_key ); + $this->add_render_attribute( $title_repeater_setting_key, 'class', 'elementor-price-list-title' ); + $this->add_render_attribute( $description_repeater_setting_key, 'class', 'elementor-price-list-description' ); + ?> + render_item_header( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> + +
        + render_image( $item, $settings ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> +
        + + +
        + +
        + + < print_render_attribute_string( $title_repeater_setting_key ); ?>> + print_unescaped_setting( 'title', 'price_list', $index ); ?> + > + + + + + + print_unescaped_setting( 'price', 'price_list', $index ); ?> + +
        + + + < print_render_attribute_string( $description_repeater_setting_key ); ?>> + print_unescaped_setting( 'item_description', 'price_list', $index ); ?> + > + +
        + render_item_footer( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> + + + +
      + + +
        + <# + var titleTag = elementor.helpers.validateHTMLTag( settings.title_tag ); + var descriptionTag = elementor.helpers.validateHTMLTag( settings.description_tag ); + + for ( var i in settings.price_list ) { + var item = settings.price_list[i], + item_open_wrap = '
      • ', + item_close_wrap = '
      • '; + if ( item.link?.url ) { + item_open_wrap = '
      • '; + item_close_wrap = '
      • '; + } + + if ( ! _.isEmpty( item.title ) || ! _.isEmpty( item.price ) || ! _.isEmpty( item.description ) || ! _.isEmpty( item.image ) ) { #> + + {{{ item_open_wrap }}} + <# if ( item.image && item.image.id ) { + + var image = { + id: item.image.id, + url: item.image.url, + size: settings.image_size_size, + dimension: settings.image_size_custom_dimension, + model: view.getEditModel() + }; + + var image_url = elementor.imagesManager.getImageUrl( image ); + + if ( image_url ) { #> +
        {{ item.title }}
        + <# } #> + + <# } #> + + + <# if ( ! _.isEmpty( item.title ) || ! _.isEmpty( item.price ) || ! _.isEmpty( item.item_description ) ) { #> +
        + + <# if ( ! _.isEmpty( item.title ) || ! _.isEmpty( item.price ) ) { #> +
        + + <# if ( ! _.isEmpty( item.title ) ) { #> + <{{ titleTag }} class="elementor-price-list-title">{{{ item.title }}} + <# } #> + + <# if ( 'none' != settings.separator_style ) { #> + + <# } #> + + <# if ( ! _.isEmpty( item.price ) ) { #> + {{{ item.price }}} + <# } #> + +
        + <# } #> + + <# if ( ! _.isEmpty( item.item_description ) ) { #> + <{{descriptionTag}} class="elementor-price-list-description">{{{ item.item_description }}} + <# } #> + +
        + <# } #> + + {{{ item_close_wrap }}} + + <# } #> + <# } #> +
      + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-price-table' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_header', + [ + 'label' => esc_html__( 'Header', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Enter your title', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'sub_heading', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Enter your description', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'heading_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + ], + 'default' => 'h3', + 'condition' => [ + 'heading!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_pricing', + [ + 'label' => esc_html__( 'Pricing', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'currency_symbol', + [ + 'label' => esc_html__( 'Currency Symbol', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'dollar' => '$ ' . _x( 'Dollar', 'Currency', 'elementor-pro' ), + 'euro' => '€ ' . _x( 'Euro', 'Currency', 'elementor-pro' ), + 'baht' => '฿ ' . _x( 'Baht', 'Currency', 'elementor-pro' ), + 'franc' => '₣ ' . _x( 'Franc', 'Currency', 'elementor-pro' ), + 'guilder' => 'ƒ ' . _x( 'Guilder', 'Currency', 'elementor-pro' ), + 'krona' => 'kr ' . _x( 'Krona', 'Currency', 'elementor-pro' ), + 'lira' => '₤ ' . _x( 'Lira', 'Currency', 'elementor-pro' ), + 'peseta' => '₧ ' . _x( 'Peseta', 'Currency', 'elementor-pro' ), + 'peso' => '₱ ' . _x( 'Peso', 'Currency', 'elementor-pro' ), + 'pound' => '£ ' . _x( 'Pound Sterling', 'Currency', 'elementor-pro' ), + 'real' => 'R$ ' . _x( 'Real', 'Currency', 'elementor-pro' ), + 'ruble' => '₽ ' . _x( 'Ruble', 'Currency', 'elementor-pro' ), + 'rupee' => '₨ ' . _x( 'Rupee', 'Currency', 'elementor-pro' ), + 'indian_rupee' => '₹ ' . _x( 'Rupee (Indian)', 'Currency', 'elementor-pro' ), + 'shekel' => '₪ ' . _x( 'Shekel', 'Currency', 'elementor-pro' ), + 'yen' => '¥ ' . _x( 'Yen/Yuan', 'Currency', 'elementor-pro' ), + 'won' => '₩ ' . _x( 'Won', 'Currency', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'dollar', + ] + ); + + $this->add_control( + 'currency_symbol_custom', + [ + 'label' => esc_html__( 'Custom Symbol', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'currency_symbol' => 'custom', + ], + ] + ); + + $this->add_control( + 'price', + [ + 'label' => esc_html__( 'Price', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '39.99', + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'currency_format', + [ + 'label' => esc_html__( 'Currency Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => '1,234.56 (Default)', + ',' => '1.234,56', + ], + ] + ); + + $this->add_control( + 'sale', + [ + 'label' => esc_html__( 'Sale', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'default' => '', + ] + ); + + $this->add_control( + 'original_price', + [ + 'label' => esc_html__( 'Original Price', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '59', + 'condition' => [ + 'sale' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'period', + [ + 'label' => esc_html__( 'Period', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Monthly', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_features', + [ + 'label' => esc_html__( 'Features', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'item_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'List Item', 'elementor-pro' ), + ] + ); + + $default_icon = [ + 'value' => 'far fa-check-circle', + 'library' => 'fa-regular', + ]; + + $repeater->add_control( + 'selected_item_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'item_icon', + 'default' => $default_icon, + ] + ); + + $repeater->add_control( + 'item_icon_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} i' => 'color: {{VALUE}}', + '{{WRAPPER}} {{CURRENT_ITEM}} svg' => 'fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'features_list', + [ + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'item_text' => esc_html__( 'List Item #1', 'elementor-pro' ), + 'selected_item_icon' => $default_icon, + ], + [ + 'item_text' => esc_html__( 'List Item #2', 'elementor-pro' ), + 'selected_item_icon' => $default_icon, + ], + [ + 'item_text' => esc_html__( 'List Item #3', 'elementor-pro' ), + 'selected_item_icon' => $default_icon, + ], + ], + 'title_field' => '{{{ item_text }}}', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_footer', + [ + 'label' => esc_html__( 'Footer', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Button Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Click Here', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'default' => [ + 'url' => '#', + ], + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'footer_additional_info', + [ + 'label' => esc_html__( 'Additional Info', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'This is text element', 'elementor-pro' ), + 'rows' => 3, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_ribbon', + [ + 'label' => esc_html__( 'Ribbon', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_ribbon', + [ + 'label' => esc_html__( 'Show', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'ribbon_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Popular', 'elementor-pro' ), + 'condition' => [ + 'show_ribbon' => 'yes', + ], + 'dynamic' => [ + 'active' => true, + ], + 'assets' => [ + 'styles' => [ + [ + 'name' => 'e-ribbon', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'ribbon_title', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'ribbon_horizontal_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_header_style', + [ + 'label' => esc_html__( 'Header', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'heading', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'sub_heading', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'header_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-price-table-header-background-color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'heading', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'sub_heading', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'header_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__header' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'heading', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'sub_heading', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'heading_heading_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'heading!' => '', + ], + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__heading' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'heading!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__heading', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'condition' => [ + 'heading!' => '', + ], + ] + ); + + $this->add_control( + 'heading_sub_heading_style', + [ + 'label' => esc_html__( 'Sub Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'sub_heading!' => '', + ], + ] + ); + + $this->add_control( + 'sub_heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__subheading' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'sub_heading!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sub_heading_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__subheading', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'condition' => [ + 'sub_heading!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_pricing_element_style', + [ + 'label' => esc_html__( 'Pricing', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'pricing_element_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__price' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'pricing_element_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__price' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__currency, {{WRAPPER}} .elementor-price-table__integer-part, {{WRAPPER}} .elementor-price-table__fractional-part' => 'color: {{VALUE}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'price_typography', + // Targeting also the .elementor-price-table class in order to get a higher specificity from the inline CSS. + 'selector' => '{{WRAPPER}} .elementor-price-table .elementor-price-table__price', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_control( + 'heading_currency_style', + [ + 'label' => esc_html__( 'Currency Symbol', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'currency_symbol!' => '', + ], + ] + ); + + $this->add_control( + 'currency_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__price > .elementor-price-table__currency' => 'font-size: calc({{SIZE}}em/100)', + ], + 'condition' => [ + 'currency_symbol!' => '', + ], + ] + ); + + $this->add_control( + 'currency_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'before', + 'options' => [ + 'before' => [ + 'title' => esc_html__( 'Before', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'after' => [ + 'title' => esc_html__( 'After', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + ] + ); + + $this->add_control( + 'currency_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'default' => 'top', + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__currency' => 'align-self: {{VALUE}}', + ], + 'condition' => [ + 'currency_symbol!' => '', + ], + ] + ); + + $this->add_control( + 'fractional_part_style', + [ + 'label' => esc_html__( 'Fractional Part', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'fractional-part_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__fractional-part' => 'font-size: calc({{SIZE}}em/100)', + ], + ] + ); + + $this->add_control( + 'fractional_part_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'default' => 'top', + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__after-price' => 'justify-content: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_original_price_style', + [ + 'label' => esc_html__( 'Original Price', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'sale' => 'yes', + 'original_price!' => '', + ], + ] + ); + + $this->add_control( + 'original_price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__original-price' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'sale' => 'yes', + 'original_price!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'original_price_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__original-price', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'condition' => [ + 'sale' => 'yes', + 'original_price!' => '', + ], + ] + ); + + $this->add_control( + 'original_price_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'default' => 'bottom', + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__original-price' => 'align-self: {{VALUE}}', + ], + 'condition' => [ + 'sale' => 'yes', + 'original_price!' => '', + ], + ] + ); + + $this->add_control( + 'heading_period_style', + [ + 'label' => esc_html__( 'Period', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'period!' => '', + ], + ] + ); + + $this->add_control( + 'period_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__period' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'period!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'period_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__period', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'condition' => [ + 'period!' => '', + ], + ] + ); + + $this->add_control( + 'period_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'label_block' => false, + 'options' => [ + 'below' => esc_html__( 'Below', 'elementor-pro' ), + 'beside' => esc_html__( 'Beside', 'elementor-pro' ), + ], + 'default' => 'below', + 'condition' => [ + 'period!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_features_list_style', + [ + 'label' => esc_html__( 'Features', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'features_list_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'features_list_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'features_list_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list' => '--e-price-table-features-list-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'features_list_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__features-list li', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'features_list_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'item_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + '%' => [ + 'min' => 25, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__feature-inner' => 'margin-left: calc((100% - {{SIZE}}%)/2); margin-right: calc((100% - {{SIZE}}%)/2)', + ], + ] + ); + + $this->add_control( + 'list_divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + ], + 'default' => 'solid', + 'condition' => [ + 'list_divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list li:before' => 'border-top-style: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ddd', + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'list_divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list li:before' => 'border-top-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 2, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 10, + ], + 'em' => [ + 'max' => 1, + ], + 'rem' => [ + 'max' => 1, + ], + ], + 'condition' => [ + 'list_divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list li:before' => 'border-top-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'divider_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'condition' => [ + 'list_divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list li:before' => 'margin-left: calc((100% - {{SIZE}}%)/2); margin-right: calc((100% - {{SIZE}}%)/2)', + ], + ] + ); + + $this->add_control( + 'divider_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 15, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'condition' => [ + 'list_divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__features-list li:before' => 'margin-top: {{SIZE}}{{UNIT}}; margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_footer_style', + [ + 'label' => esc_html__( 'Footer', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'footer_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__footer' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'footer_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__footer' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'heading_footer_button', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'button_text!' => '', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'md', + 'options' => [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__button' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-price-table__button', + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-price-table__button', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + 'color' => [ + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + ], + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), [ + 'name' => 'button_border', + 'selector' => '{{WRAPPER}} .elementor-price-table__button', + 'separator' => 'before', + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__button:hover' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background_hover', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-price-table__button:hover', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__button:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'condition' => [ + 'button_text!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'heading_additional_info', + [ + 'label' => esc_html__( 'Additional Info', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'button_text', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'footer_additional_info', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'additional_info_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__additional_info' => 'color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'button_text', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'footer_additional_info', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'additional_info_typography', + 'selector' => '{{WRAPPER}} .elementor-price-table__additional_info', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'button_text', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'footer_additional_info', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_control( + 'additional_info_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'top' => 15, + 'right' => 30, + 'bottom' => 0, + 'left' => 30, + 'unit' => 'px', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-price-table__additional_info' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'button_text', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'footer_additional_info', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_ribbon_style', + [ + 'label' => esc_html__( 'Ribbon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->add_control( + 'ribbon_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $ribbon_distance_transform = is_rtl() ? 'translateY(-50%) translateX({{SIZE}}{{UNIT}}) rotate(-45deg)' : 'translateY(-50%) translateX(-50%) translateX({{SIZE}}{{UNIT}}) rotate(-45deg)'; + + $this->add_responsive_control( + 'ribbon_distance', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'margin-top: {{SIZE}}{{UNIT}}; transform: ' . $ribbon_distance_transform, + ], + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->add_control( + 'ribbon_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}} .elementor-ribbon-inner' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'ribbon_typography', + 'selector' => '{{WRAPPER}} .elementor-ribbon-inner', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .elementor-ribbon-inner', + 'condition' => [ + 'show_ribbon' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + private function render_currency_symbol( $symbol, $location ) { + $currency_position = $this->get_settings( 'currency_position' ); + $location_setting = ! empty( $currency_position ) ? $currency_position : 'before'; + if ( ! empty( $symbol ) && $location === $location_setting ) { + echo '' . esc_html( $symbol ) . ''; + } + } + + private function get_currency_symbol( $symbol_name ) { + $symbols = [ + 'dollar' => '$', + 'euro' => '€', + 'franc' => '₣', + 'pound' => '£', + 'ruble' => '₽', + 'shekel' => '₪', + 'baht' => '฿', + 'yen' => '¥', + 'won' => '₩', + 'guilder' => 'ƒ', + 'peso' => '₱', + 'peseta' => '₧', + 'lira' => '₤', + 'rupee' => '₨', + 'indian_rupee' => '₹', + 'real' => 'R$', + 'krona' => 'kr', + ]; + + return isset( $symbols[ $symbol_name ] ) ? $symbols[ $symbol_name ] : ''; + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $symbol = ''; + + if ( ! empty( $settings['currency_symbol'] ) ) { + if ( 'custom' !== $settings['currency_symbol'] ) { + $symbol = $this->get_currency_symbol( $settings['currency_symbol'] ); + } else { + $symbol = $settings['currency_symbol_custom']; + } + } + $currency_format = empty( $settings['currency_format'] ) ? '.' : $settings['currency_format']; + $price = explode( $currency_format, $settings['price'] ); + $intpart = $price[0]; + $fraction = ''; + if ( 2 === count( $price ) ) { + $fraction = $price[1]; + } + + $this->add_render_attribute( 'button_text', 'class', [ + 'elementor-price-table__button', + 'elementor-button', + 'elementor-size-' . $settings['button_size'], + ] ); + + if ( ! empty( $settings['link']['url'] ) ) { + $this->add_link_attributes( 'button_text', $settings['link'] ); + } + + if ( ! empty( $settings['button_hover_animation'] ) ) { + $this->add_render_attribute( 'button_text', 'class', 'elementor-animation-' . $settings['button_hover_animation'] ); + } + + $this->add_render_attribute( 'heading', 'class', 'elementor-price-table__heading' ); + $this->add_render_attribute( 'sub_heading', 'class', 'elementor-price-table__subheading' ); + $this->add_render_attribute( 'period', 'class', [ 'elementor-price-table__period', 'elementor-typo-excluded' ] ); + $this->add_render_attribute( 'footer_additional_info', 'class', 'elementor-price-table__additional_info' ); + + $this->add_inline_editing_attributes( 'heading', 'none' ); + $this->add_inline_editing_attributes( 'sub_heading', 'none' ); + $this->add_inline_editing_attributes( 'period', 'none' ); + $this->add_inline_editing_attributes( 'footer_additional_info' ); + $this->add_inline_editing_attributes( 'button_text' ); + + $period_position = $settings['period_position']; + $period_element = 'get_render_attribute_string( 'period' ) . '>' . wp_kses_post( $settings['period'] ) . ''; + $heading_tag = Utils::validate_html_tag( $settings['heading_tag'] ); + + $migration_allowed = Icons_Manager::is_migration_allowed(); + ?> + +
      + +
      + + < print_render_attribute_string( 'heading' ); ?>> + + > + + + + print_render_attribute_string( 'sub_heading' ); ?>> + + + +
      + + +
      + +
      + render_currency_symbol( $symbol, 'before' ); + echo wp_kses_post( $settings['original_price'] ); + $this->render_currency_symbol( $symbol, 'after' ); + ?> +
      + + render_currency_symbol( $symbol, 'before' ); ?> + + + + + + + +
      + + + + + + + +
      + + + render_currency_symbol( $symbol, 'after' ); ?> + + + + +
      + + +
        + $item ) : + $repeater_setting_key = $this->get_repeater_setting_key( 'item_text', 'features_list', $index ); + $this->add_inline_editing_attributes( $repeater_setting_key ); + + $migrated = isset( $item['__fa4_migrated']['selected_item_icon'] ); + // add old default + if ( ! isset( $item['item_icon'] ) && ! $migration_allowed ) { + $item['item_icon'] = 'fa fa-check-circle'; + } + $is_new = ! isset( $item['item_icon'] ) && $migration_allowed; + ?> +
      • +
        + 'true' ] ); + else : ?> + + + + print_render_attribute_string( $repeater_setting_key ); ?>> + + + +
        +
      • + +
      + + + + + +
      + + add_render_attribute( 'ribbon-wrapper', 'class', 'elementor-ribbon' ); + + if ( ! empty( $settings['ribbon_horizontal_position'] ) ) : + $this->add_render_attribute( 'ribbon-wrapper', 'class', 'elementor-ribbon-' . $settings['ribbon_horizontal_position'] ); + endif; + + $this->add_render_attribute( 'ribbon_title', 'class', 'elementor-ribbon-inner' ); + $this->add_inline_editing_attributes( 'ribbon_title' ); + ?> +
      print_render_attribute_string( 'ribbon-wrapper' ); ?>> +
      print_render_attribute_string( 'ribbon_title' ); ?>> + +
      +
      + + <# + var symbols = { + dollar: '$', + euro: '€', + franc: '₣', + pound: '£', + ruble: '₽', + shekel: '₪', + baht: '฿', + yen: '¥', + won: '₩', + guilder: 'ƒ', + peso: '₱', + peseta: '₧', + lira: '₤', + rupee: '₨', + indian_rupee: '₹', + real: 'R$', + krona: 'kr' + }; + + var symbol = '', + iconsHTML = {}; + + if ( settings.currency_symbol ) { + if ( 'custom' !== settings.currency_symbol ) { + symbol = symbols[ settings.currency_symbol ] || ''; + } else { + symbol = settings.currency_symbol_custom; + } + } + + var buttonClasses = 'elementor-price-table__button elementor-button elementor-size-' + settings.button_size; + + if ( settings.button_hover_animation ) { + buttonClasses += ' elementor-animation-' + settings.button_hover_animation; + } + + view.addRenderAttribute( 'heading', 'class', 'elementor-price-table__heading' ); + view.addRenderAttribute( 'sub_heading', 'class', 'elementor-price-table__subheading' ); + view.addRenderAttribute( 'period', 'class', ['elementor-price-table__period', 'elementor-typo-excluded'] ); + view.addRenderAttribute( 'footer_additional_info', 'class', 'elementor-price-table__additional_info' ); + view.addRenderAttribute( 'button_text', 'class', buttonClasses ); + + view.addInlineEditingAttributes( 'heading', 'none' ); + view.addInlineEditingAttributes( 'sub_heading', 'none' ); + view.addInlineEditingAttributes( 'period', 'none' ); + view.addInlineEditingAttributes( 'footer_additional_info' ); + view.addInlineEditingAttributes( 'button_text' ); + + var currencyFormat = settings.currency_format || '.', + price = settings.price.split( currencyFormat ), + intpart = price[0], + fraction = price[1], + periodElement = '' + _.escape( settings.period ) + ''; + #> +
      + <# if ( settings.heading || settings.sub_heading ) { #> +
      + <# if ( settings.heading ) { #> + <# var headingTag = elementor.helpers.validateHTMLTag( settings.heading_tag ) #> + <{{ headingTag }} {{{ view.getRenderAttributeString( 'heading' ) }}}>{{ settings.heading }} + <# } #> + <# if ( settings.sub_heading ) { #> + {{ settings.sub_heading }} + <# } #> +
      + <# } #> + +
      + <# if ( settings.sale && settings.original_price ) { #> +
      + <# if ( ! _.isEmpty( symbol ) && ( 'before' == settings.currency_position || _.isEmpty( settings.currency_position ) ) ) { #> + {{{ symbol }}}{{ settings.original_price }} + <# } #> + <# + /* The duplicate usage of the original price setting in the "if blocks" is to avoid whitespace between the number and the symbol. */ + if ( _.isEmpty( symbol ) ) { + #> + {{ settings.original_price }} + <# } #> + <# if ( ! _.isEmpty( symbol ) && 'after' == settings.currency_position ) { #> + {{ settings.original_price }}{{{ symbol }}} + <# } #> +
      + <# } #> + + <# if ( ! _.isEmpty( symbol ) && ( 'before' == settings.currency_position || _.isEmpty( settings.currency_position ) ) ) { #> + {{{ symbol }}} + <# } #> + <# if ( intpart ) { #> + {{{ intpart }}} + <# } #> +
      + <# if ( fraction ) { #> + {{{ fraction }}} + <# } #> + <# if ( settings.period && 'beside' === settings.period_position ) { #> + {{{ periodElement }}} + <# } #> +
      + + <# if ( ! _.isEmpty( symbol ) && 'after' == settings.currency_position ) { #> + {{{ symbol }}} + <# } #> + + <# if ( settings.period && 'below' === settings.period_position ) { #> + {{{ periodElement }}} + <# } #> +
      + + <# if ( settings.features_list ) { #> +
        + <# _.each( settings.features_list, function( item, index ) { + + var featureKey = view.getRepeaterSettingKey( 'item_text', 'features_list', index ), + migrated = elementor.helpers.isIconMigrated( item, 'selected_item_icon' ); + + view.addInlineEditingAttributes( featureKey ); #> + +
      • +
        + <# if ( item.item_icon || item.selected_item_icon ) { + iconsHTML[ index ] = elementor.helpers.renderIcon( view, item.selected_item_icon, { 'aria-hidden': 'true' }, 'i', 'object' ); + if ( ( ! item.item_icon || migrated ) && iconsHTML[ index ] && iconsHTML[ index ].rendered ) { #> + {{{ iconsHTML[ index ].value }}} + <# } else { #> + + <# } + } #> + <# if ( ! _.isEmpty( item.item_text.trim() ) ) { #> + {{ item.item_text }} + <# } else { #> +   + <# } #> +
        +
      • + <# } ); #> +
      + <# } #> + + <# if ( settings.button_text || settings.footer_additional_info ) { #> + + <# } #> +
      + + <# if ( 'yes' === settings.show_ribbon && settings.ribbon_title ) { + view.addRenderAttribute( 'ribbon', 'class', 'elementor-ribbon' ); + + if ( settings.ribbon_horizontal_position ) { + view.addRenderAttribute( 'ribbon', 'class', 'elementor-ribbon-' + settings.ribbon_horizontal_position ); + } + + view.addRenderAttribute( 'ribbon_title', 'class', 'elementor-ribbon-inner' ); + view.addInlineEditingAttributes( 'ribbon_title' ); + #> +
      +
      {{ settings.ribbon_title }}
      +
      + <# } #> + get_css_assets_url( 'widget-progress-tracker', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/progress-tracker/widgets/progress-tracker.php b/modules/progress-tracker/widgets/progress-tracker.php new file mode 100644 index 00000000..235dbd84 --- /dev/null +++ b/modules/progress-tracker/widgets/progress-tracker.php @@ -0,0 +1,676 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-progress-tracker' ]; + } + + private function register_content_controls() { + $this->start_controls_section( + 'section_content_scrolling_tracker', + [ + 'label' => esc_html__( 'Progress Tracker', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'type', + [ + 'label' => esc_html__( 'Tracker Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'frontend_available' => true, + 'options' => [ + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'circular' => esc_html__( 'Circular', 'elementor-pro' ), + ], + 'default' => 'horizontal', + ] + ); + + $this->add_control( + 'relative_to', + [ + 'label' => esc_html__( 'Progress relative to', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'frontend_available' => true, + 'options' => [ + 'entire_page' => esc_html__( 'Entire Page', 'elementor-pro' ), + 'post_content' => esc_html__( 'Post Content', 'elementor-pro' ), + 'selector' => esc_html__( 'Selector', 'elementor-pro' ), + ], + 'default' => 'entire_page', + ] + ); + + $this->add_control( + 'selector', + [ + 'label' => esc_html__( 'Selector', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'Add the CSS ID or Class of a specific element on this page to track its progress separately', 'elementor-pro' ), + 'frontend_available' => true, + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'relative_to' => 'selector', + ], + 'placeholder' => '#id, .class', + ] + ); + + $this->add_control( + 'relative_to_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Note: You can only track progress relative to Post Content on a single post template.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'relative_to' => 'post_content', + ], + ] + ); + + $this->add_control( + 'direction', + [ + 'label' => esc_html__( 'Direction', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'ltr' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'rtl' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'render_type' => 'template', + 'frontend_available' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--direction: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'percentage', + [ + 'label' => esc_html__( 'Percentage', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'no', + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'percentage_position', + [ + 'label' => esc_html__( 'Percentage Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'rtl' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'ltr' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'type' => 'horizontal', + 'percentage' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--text-direction: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + private function register_tracker_style_controls() { + $this->start_controls_section( + 'section_style_scrolling_tracker', + [ + 'label' => esc_html__( 'Tracker', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'circular_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--circular-width: {{SIZE}}{{UNIT}}; --circular-height: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_control( + 'heading_progress_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Progress Indicator', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'circular_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--circular-color: {{VALUE}}', + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_responsive_control( + 'circular_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 400, + ], + 'em' => [ + 'max' => 40, + ], + 'rem' => [ + 'max' => 40, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--circular-progress-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'horizontal_color', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .current-progress', + 'condition' => [ + 'type' => 'horizontal', + ], + 'fields_options' => [ + 'background' => [ + 'label' => esc_html__( 'Progress Color', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_control( + 'horizontal_border_style', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'none', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-progress-border: {{VALUE}};', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-progress-border-top-width: {{TOP}}{{UNIT}}; --horizontal-progress-border-right-width: {{RIGHT}}{{UNIT}}; --horizontal-progress-border-bottom-width: {{BOTTOM}}{{UNIT}}; --horizontal-progress-border-left-width: {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'horizontal_border_style!' => 'none', + 'type' => 'horizontal', + ], + ] + ); + + $this->add_control( + 'horizontal_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-progress-border-color: {{VALUE}}', + ], + 'condition' => [ + 'horizontal_border_style!' => 'none', + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--progress-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_control( + 'heading_tracker_background_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Tracker Background', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'circular_background_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--circular-background-color: {{VALUE}}', + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_responsive_control( + 'circular_background_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 400, + ], + 'em' => [ + 'max' => 40, + ], + 'rem' => [ + 'max' => 40, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--circular-background-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'circular', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'horizontal_background_color', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-scrolling-tracker-horizontal', + 'fields_options' => [ + 'background' => [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + ], + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-height: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_control( + 'horizontal_tracker_border_style', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'none', + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-border-style: {{VALUE}};', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_tracker_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-border-top-width: {{TOP}}{{UNIT}}; --horizontal-border-right-width: {{RIGHT}}{{UNIT}}; --horizontal-border-bottom-width: {{BOTTOM}}{{UNIT}}; --horizontal-border-left-width: {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'horizontal_tracker_border_style!' => 'none', + 'type' => 'horizontal', + ], + ] + ); + + $this->add_control( + 'horizontal_tracker_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--horizontal-border-color: {{VALUE}}', + ], + 'condition' => [ + 'horizontal_tracker_border_style!' => 'none', + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_tracker_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}} .elementor-scrolling-tracker', + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->add_responsive_control( + 'horizontal_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tracker-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'type' => 'horizontal', + ], + ] + ); + + $this->end_controls_section(); + } + + private function register_content_style_controls() { + $this->start_controls_section( + 'section__content_style_scrolling_tracker', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'percentage' => 'yes', + ], + ] + ); + + $this->add_control( + 'heading_percentage_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Percentage', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'percentage_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--percentage-color: {{VALUE}}', + ], + 'frontend_available' => true, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'percentage_typography', + 'selector' => '{{WRAPPER}} .current-progress-percentage', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'percentage_text_shadow', + 'selector' => '{{WRAPPER}} .current-progress-percentage', + ] + ); + + $this->end_controls_section(); + } + + protected function register_controls() { + $this->register_content_controls(); + $this->register_tracker_style_controls(); + $this->register_content_style_controls(); + } + + public function render_plain_content() {} + + protected function render() { + $settings = $this->get_settings_for_display(); + $horizontal = 'horizontal' === $settings['type']; + $this->add_render_attribute( 'scrolling-percentage', 'class', 'current-progress-percentage' ); + $this->add_render_attribute( 'scrolling-tracker', 'class', [ + 'elementor-scrolling-tracker', + 'elementor-scrolling-tracker-' . $settings['type'], + 'elementor-scrolling-tracker-alignment-' . $settings['align'], + ] ); ?> + +
      print_render_attribute_string( 'scrolling-tracker' ); ?>> + +
      +
      print_render_attribute_string( 'scrolling-percentage' ); ?>>
      +
      + + + + + + +
      print_render_attribute_string( 'scrolling-percentage' ); ?>>
      + +
      + widget = $widget; + $this->prefix = $group_query_name . '_'; + $this->query_args = $query_args; + + $settings = $this->widget->get_settings_for_display(); + $defaults = $this->get_query_defaults(); + + $this->widget_settings = wp_parse_args( $settings, $defaults ); + } + + /** + * 1) build query args + * 2) invoke callback to fine-tune query-args + * 3) generate WP_Query object + * 4) if no results & fallback is set, generate a new WP_Query with fallback args + * 5) return WP_Query + * + * @return \WP_Query + */ + public function get_query() { + $this->get_query_args(); + + $offset_control = $this->get_widget_settings( 'offset' ); + + $query_id = $this->get_widget_settings( 'query_id' ); + if ( ! empty( $query_id ) ) { + add_action( 'pre_get_posts', [ $this, 'pre_get_posts_query_filter' ] ); + } + + if ( ! $this->is_manual_selection() && 0 < $offset_control ) { + /** + * @see https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination + */ + add_action( 'pre_get_posts', [ $this, 'fix_query_offset' ], 1 ); + add_filter( 'found_posts', [ $this, 'fix_query_found_posts' ], 1, 2 ); + } + + $query = new \WP_Query( $this->query_args );// SQL_CALC_FOUND_ROWS is used. + + remove_action( 'pre_get_posts', [ $this, 'pre_get_posts_query_filter' ] ); + remove_action( 'pre_get_posts', [ $this, 'fix_query_offset' ], 1 ); + remove_filter( 'found_posts', [ $this, 'fix_query_found_posts' ], 1 ); + + $ids = isset( $this->query_args['fields'] ) && 'ids' === $this->query_args['fields'] + ? $query->posts + : wp_list_pluck( $query->posts, 'ID' ); + + Module::add_to_avoid_list( $ids ); + + /** + * Elementor Pro query results. + * + * Fires before the actual query is run. This hook allows developers + * to alter individual query results. + * + * @param \WP_Query $query An instance of WordPress query. + * @param Widget_Base $widget An instance of Elementor widget. + */ + do_action( 'elementor/query/query_results', $query, $this->widget ); + + return $query; + } + + protected function get_query_defaults() { + $defaults = [ + $this->prefix . 'post_type' => 'post', + $this->prefix . 'posts_ids' => [], + $this->prefix . 'orderby' => 'date', + $this->prefix . 'order' => 'desc', + $this->prefix . 'offset' => 0, + $this->prefix . 'posts_per_page' => 3, + ]; + + return $defaults; + } + + public function get_query_args() { + $post_type = $this->get_widget_settings( 'post_type' ); + + if ( 'current_query' === $post_type ) { + $current_query_vars = $GLOBALS['wp_query']->query_vars; + + /** + * Add custom paged option support. It's necessary for ajax and individual pagination support + */ + if ( ! empty( $this->query_args['has_custom_pagination'] ) && true === $this->query_args['has_custom_pagination'] ) { + $current_query_vars['paged'] = $this->query_args['paged']; + } + + /** + * Current query variables. + * + * Filters the query variables for the current query. This hook allows + * developers to alter those variables. + * + * @since 1.0.0 + * + * @param array $current_query_vars Current query variables. + */ + $current_query_vars = apply_filters( 'elementor/query/get_query_args/current_query', $current_query_vars ); + $this->query_args = $current_query_vars; + return $current_query_vars; + } + + $this->set_common_args(); + $this->set_order_args(); + $this->set_pagination_args(); + $this->set_post_include_args(); + + if ( ! $this->is_manual_selection() ) { + + $this->set_post_exclude_args(); + $this->set_avoid_duplicates(); + $this->set_terms_args(); + $this->set_author_args(); + $this->set_date_args(); + } + + /** + * Current query arguments. + * + * Filters the query arguments for the current query. This hook allows + * developers to alter those arguments. + * + * @param array $query_args An array of WordPress query arguments. + * @param Widget_Base $widget An instance of Elementor widget. + */ + $this->query_args = apply_filters( 'elementor/query/query_args', $this->query_args, $this->widget ); + + return $this->query_args; + } + + protected function set_pagination_args() { + $this->set_query_arg( 'posts_per_page', $this->get_widget_settings( 'posts_per_page' ) ); + $sticky_post = $this->get_widget_settings( 'ignore_sticky_posts' ) ? true : false; + $this->set_query_arg( 'ignore_sticky_posts', $sticky_post ); + } + + protected function set_common_args() { + $this->query_args['post_status'] = 'publish'; // Hide drafts/private posts for admins + + if ( $this->is_manual_selection() ) { + $post_types = Utils::get_public_post_types(); + $this->query_args['post_type'] = array_keys( $post_types ); + } else { + $this->query_args['post_type'] = $this->get_widget_settings( 'post_type' ); + } + } + + protected function set_post_include_args() { + + if ( $this->is_manual_selection() ) { + + $this->set_query_arg( 'post__in', $this->get_widget_settings( 'posts_ids' ) ); + + if ( empty( $this->query_args['post__in'] ) ) { + // If no selection - return an empty query + $this->query_args['post__in'] = [ 0 ]; + } + + $this->set_query_arg( 'ignore_sticky_posts', true, true ); + } + } + + private function is_manual_selection(): bool { + return 'by_id' === $this->get_widget_settings( 'post_type' ); + } + + protected function set_post_exclude_args() { + + $exclude = $this->get_widget_settings( 'exclude' ); + + if ( empty( $exclude ) ) { + return; + } + + $post__not_in = []; + + if ( $this->maybe_in_array( 'current_post', $exclude ) ) { + if ( is_singular() ) { + $post__not_in[] = get_queried_object_id(); + } + } + + $exclude_ids = $this->get_widget_settings( 'exclude_ids' ); + if ( $this->maybe_in_array( 'manual_selection', $exclude ) && ! empty( $exclude_ids ) ) { + $post__not_in = array_merge( $post__not_in, $exclude_ids ); + } + + $this->set_query_arg( 'post__not_in', $post__not_in ); + } + + protected function set_avoid_duplicates() { + if ( 'yes' === $this->get_widget_settings( 'avoid_duplicates' ) ) { + $post__not_in = isset( $this->query_args['post__not_in'] ) ? $this->query_args['post__not_in'] : []; + $post__not_in = array_merge( $post__not_in, Module::$displayed_ids ); + $this->set_query_arg( 'post__not_in', $post__not_in, true ); + } + } + + protected function set_terms_args() { + if ( $this->is_manual_selection() ) { + return; + } + + $this->build_terms_query_include( 'include_term_ids' ); + $this->build_terms_query_exclude( 'exclude_term_ids' ); + } + + protected function build_terms_query_include( $control_id ) { + $this->build_terms_query( 'include', $control_id ); + } + + protected function build_terms_query_exclude( $control_id ) { + $this->build_terms_query( 'exclude', $control_id, true ); + } + + protected function build_terms_query( $tab_id, $control_id, $exclude = false ) { + $tab_id = $this->get_widget_settings( $tab_id ); + $settings_terms = $this->get_widget_settings( $control_id ); + if ( empty( $tab_id ) || empty( $settings_terms ) || ! $this->maybe_in_array( 'terms', $tab_id ) ) { + return; + } + + $terms = []; + + // Switch to term_id in order to get all term children (sub-categories): + foreach ( $settings_terms as $id ) { + $term_data = get_term_by( 'term_taxonomy_id', $id ); + if ( false !== $term_data ) { + $taxonomy = $term_data->taxonomy; + $terms[ $taxonomy ][] = $id; + } + } + $this->insert_tax_query( $terms, $exclude ); + } + + protected function insert_tax_query( $terms, $exclude ) { + $tax_query = []; + foreach ( $terms as $taxonomy => $ids ) { + $query = [ + 'taxonomy' => $taxonomy, + 'field' => 'term_taxonomy_id', + 'terms' => $ids, + ]; + + if ( $exclude ) { + $query['operator'] = 'NOT IN'; + } + + $tax_query[] = $query; + } + + if ( empty( $tax_query ) ) { + return; + } + + if ( empty( $this->query_args['tax_query'] ) ) { + $this->query_args['tax_query'] = $tax_query; + } else { + $this->query_args['tax_query']['relation'] = 'AND'; + $this->query_args['tax_query'][] = $tax_query; + } + } + + protected function set_author_args() { + + $include_authors = $this->get_widget_settings( 'include_authors' ); + if ( ! empty( $include_authors ) && $this->maybe_in_array( 'authors', $this->get_widget_settings( 'include' ) ) ) { + $this->set_query_arg( 'author__in', $include_authors ); + } + + $exclude_authors = $this->get_widget_settings( 'exclude_authors' ); + if ( ! empty( $exclude_authors ) && $this->maybe_in_array( 'authors', $this->get_widget_settings( 'exclude' ) ) ) { + //exclude only if not explicitly included + if ( empty( $this->query_args['author__in'] ) ) { + $this->set_query_arg( 'author__not_in', $exclude_authors ); + } + } + } + + protected function set_order_args() { + $order = $this->get_widget_settings( 'order' ); + if ( ! empty( $order ) ) { + $this->set_query_arg( 'orderby', $this->get_widget_settings( 'orderby' ) ); + $this->set_query_arg( 'order', $this->get_widget_settings( 'order' ) ); + } + } + + protected function set_date_args() { + + $select_date = $this->get_widget_settings( 'select_date' ); + if ( ! empty( $select_date ) ) { + $date_query = []; + switch ( $select_date ) { + case 'today': + $date_query['after'] = '-1 day'; + break; + case 'week': + $date_query['after'] = '-1 week'; + break; + case 'month': + $date_query['after'] = '-1 month'; + break; + case 'quarter': + $date_query['after'] = '-3 month'; + break; + case 'year': + $date_query['after'] = '-1 year'; + break; + case 'exact': + $after_date = $this->get_widget_settings( 'date_after' ); + if ( ! empty( $after_date ) ) { + $date_query['after'] = $after_date; + } + $before_date = $this->get_widget_settings( 'date_before' ); + if ( ! empty( $before_date ) ) { + $date_query['before'] = $before_date; + } + $date_query['inclusive'] = true; + break; + } + + $this->set_query_arg( 'date_query', $date_query ); + } + } + + /** + * @param string $control_name + * + * @return mixed|null + */ + protected function get_widget_settings( $control_name ) { + $control_name = $this->prefix . $control_name; + return isset( $this->widget_settings[ $control_name ] ) ? $this->widget_settings[ $control_name ] : null; + } + + /** + * @param $key + * @param $value + * @param false $override + */ + protected function set_query_arg( $key, $value, $override = false ) { + if ( ! isset( $this->query_args[ $key ] ) || $override ) { + $this->query_args[ $key ] = $value; + } + } + + /** + * @param string $value + * @param mixed $maybe_array + * + * @return bool + */ + protected function maybe_in_array( $value, $maybe_array ) { + return is_array( $maybe_array ) ? in_array( $value, $maybe_array, true ) : $value === $maybe_array; + } + + /** + * @param \WP_Query $wp_query + */ + public function pre_get_posts_query_filter( $wp_query ) { + if ( $this->widget ) { + $query_id = $this->get_widget_settings( 'query_id' ); + $widget_name = $this->widget->get_name(); + /** + * Elementor Pro query arguments. + * + * Fires before the actual query is run. This hook allows developers to + * alter individual queries by id. + * + * The dynamic portions of the hook name, `$widget_name` & `$query_id`, + * refers to the widget name and query id respectively. + * + * @since 2.1.0 + * + * @param \WP_Query $wp_query An instance of WordPress query. + * @param Widget_Base $widget An instance of Elementor widget + */ + do_action( "elementor/query/{$query_id}", $wp_query, $this->widget ); + } + } + + /** + * @param \WP_Query $query + */ + public function fix_query_offset( &$query ) { + $offset = $this->get_widget_settings( 'offset' ); + + if ( $offset && $query->is_paged ) { + $query->query_vars['offset'] = $offset + ( ( $query->query_vars['paged'] - 1 ) * $query->query_vars['posts_per_page'] ); + } else { + $query->query_vars['offset'] = $offset; + } + } + + /** + * @param int $found_posts + * @param \WP_Query $query + * + * @return int + */ + public function fix_query_found_posts( $found_posts, $query ) { + $offset = $this->get_widget_settings( 'offset' ); + + if ( $offset ) { + $found_posts -= $offset; + } + + return $found_posts; + } +} diff --git a/modules/query-control/classes/elementor-related-query.php b/modules/query-control/classes/elementor-related-query.php new file mode 100644 index 00000000..ba8e208a --- /dev/null +++ b/modules/query-control/classes/elementor-related-query.php @@ -0,0 +1,169 @@ +related_post_id = -1; + $this->fallback_args = $fallback_args; + } + + /** + * 1) build query args + * 2) invoke callback to fine-tune query-args + * 3) generate WP_Query object + * 4) if no results & fallback is set, generate a new WP_Query with fallback args + * 5) return WP_Query + * + * @return \WP_Query + */ + public function get_query() { + $query = parent::get_query(); + + if ( ! $query->post_count && $this->is_valid_fallback() ) { + $query = $this->get_fallback_query( $query ); + } + + return $query; + } + + protected function get_fallback_query( $original_query ) { + $this->set_fallback_query_args(); + $this->set_fallback_arg_by_settings( 'posts_per_page', $original_query->query_vars['posts_per_page'] ); + $this->set_fallback_arg_by_settings( 'post__not_in', $original_query->query_vars['post__not_in'] ); + + /** + * Fallback query arguments. + * + * Filters the query arguments for the fallback query. This hook allows + * developers to alter those arguments. + * + * @param array $fallback_args An array of WordPress query arguments. + * @param Widget_Base $widget An instance of Elementor widget. + */ + $this->fallback_args = apply_filters( 'elementor/query/fallback_query_args', $this->fallback_args, $this->widget ); + + return new \WP_Query( $this->fallback_args ); + } + + private function is_valid_fallback() { + $related_callback = $this->get_widget_settings( 'related_fallback' ); + if ( empty( $related_callback ) ) { + return false; + } + $valid = false; + switch ( $this->get_widget_settings( 'related_fallback' ) ) { + case 'fallback_recent': + $valid = true; + break; + case 'fallback_by_id': + $fallback_id = $this->get_widget_settings( 'fallback_ids' ); + if ( ! empty( $fallback_id ) ) { + $valid = true; + } + break; + } + + return $valid; + } + + protected function set_common_args() { + parent::set_common_args(); + $post_id = get_queried_object_id(); + $this->related_post_id = is_singular() && ( 0 !== $post_id ) ? $post_id : null; + $this->query_args['post_type'] = get_post_type( $this->related_post_id ); + } + + protected function set_post_exclude_args() { + parent::set_post_exclude_args(); + + if ( $this->related_post_id ) { + $post_not_in = isset( $this->query_args['post__not_in'] ) ? $this->query_args['post__not_in'] : []; + $post_not_in[] = $this->related_post_id; + $this->query_args['post__not_in'] = $post_not_in; + } + } + + protected function build_terms_query_include( $control_id ) { + /** + * Build tax_query for the "related posts" query: + * 1) find the list of taxonomies associated with the current-post + * 2) extract the ids for each taxonomy + * 3) build tax_query array accordingly + * + */ + if ( null === $this->get_widget_settings( 'include' ) || null === $this->get_widget_settings( 'related_taxonomies' ) || ! $this->maybe_in_array( 'terms', $this->get_widget_settings( 'include' ) ) ) { + return; + } + + $taxonomies = $this->get_widget_settings( 'related_taxonomies' ); + $terms = []; + if ( is_string( $taxonomies ) ) { + $terms[ $taxonomies ] = wp_get_post_terms( $this->related_post_id, $taxonomies, [ 'fields' => 'tt_ids' ] ); + } else { + foreach ( $taxonomies as $taxonomy ) { + $terms[ $taxonomy ] = wp_get_post_terms( $this->related_post_id, $taxonomy, [ 'fields' => 'tt_ids' ] ); + } + } + + $this->insert_tax_query( $terms, false ); + } + + protected function set_author_args() { + if ( ! $this->maybe_in_array( 'authors', $this->get_widget_settings( 'include' ) ) ) { + return; + } + + $this->query_args['author__in'] = get_post_field( 'post_author', $this->related_post_id ); + } + + /** + * @param string $key + * @param mixed $value + * @param string $control_name + */ + private function set_fallback_arg_by_settings( $key, $value, $control_name = '' ) { + if ( empty( $this->fallback_args[ $key ] ) ) { + $settings = $this->widget->get_settings(); + $this->fallback_args[ $key ] = ( '' === $control_name || empty( $settings[ $this->prefix . $control_name ] ) ) ? $value : $settings[ $this->prefix . $control_name ]; + } + } + + /** + * @return string|array + */ + public function get_post_types() { + $public_post_types = Utils::get_public_post_types(); + $active_post_type = get_post_type(); + + return ! empty( $active_post_type ) ? $active_post_type : array_keys( $public_post_types ); + } + + protected function set_fallback_query_args() { + $this->set_fallback_arg_by_settings( 'ignore_sticky_posts', true ); + $this->set_fallback_arg_by_settings( 'post_status', 'publish' ); + $this->set_fallback_arg_by_settings( 'post_type', $this->get_post_types() ); + + if ( 'fallback_by_id' === $this->get_widget_settings( 'related_fallback' ) ) { + $this->set_fallback_arg_by_settings( 'post__in', [ 0 ], 'fallback_ids' ); + $this->set_fallback_arg_by_settings( 'orderby', 'rand' ); + } else { //recent posts + $this->set_fallback_arg_by_settings( 'orderby', 'date' ); + $this->set_fallback_arg_by_settings( 'order', 'DESC' ); + } + } +} diff --git a/modules/query-control/controls/group-control-posts.php b/modules/query-control/controls/group-control-posts.php new file mode 100644 index 00000000..70ac162f --- /dev/null +++ b/modules/query-control/controls/group-control-posts.php @@ -0,0 +1,315 @@ + $label ) { + $taxonomy_filter_args = [ + 'show_in_nav_menus' => true, + 'object_type' => [ $post_type ], + ]; + + $taxonomies = get_taxonomies( $taxonomy_filter_args, 'objects' ); + + foreach ( $taxonomies as $taxonomy => $object ) { + unset( $element['settings'][ $control_id . '_' . $taxonomy . '_ids' ] ); + } + } + + return $element; + } + + protected function init_fields() { + $fields = []; + + $fields['post_type'] = [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + ]; + + $fields['posts_ids'] = [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Module::QUERY_CONTROL_ID, + 'post_type' => '', + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'filter_type' => 'by_id', + 'condition' => [ + 'post_type' => 'by_id', + ], + 'export' => false, + ]; + + $fields['authors'] = [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'label_block' => true, + 'type' => Module::QUERY_CONTROL_ID, + 'multiple' => true, + 'default' => [], + 'options' => [], + 'filter_type' => 'author', + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'export' => false, + ]; + + return $fields; + } + + protected function prepare_fields( $fields ) { + $args = $this->get_args(); + + $post_type_args = []; + if ( ! empty( $args['post_type'] ) ) { + $post_type_args['post_type'] = $args['post_type']; + } + + $post_types = Utils::get_public_post_types( $post_type_args ); + + $post_types_options = $post_types; + + $post_types_options['by_id'] = esc_html__( 'Manual Selection', 'elementor-pro' ); + $post_types_options['current_query'] = esc_html__( 'Current Query', 'elementor-pro' ); + + $fields['post_type']['options'] = $post_types_options; + + $fields['post_type']['default'] = key( $post_types ); + + $fields['posts_ids']['object_type'] = array_keys( $post_types ); + + $taxonomy_filter_args = [ + 'show_in_nav_menus' => true, + ]; + + $taxonomies = get_taxonomies( $taxonomy_filter_args, 'objects' ); + + // bypass bug in WP_List_Util::filter() causing wrong array comparison + // when a taxonomy belongs to several post-types (e.g. when using woocommerce-product-add-ons) + // ( using simple '==' rather than in_array() or array_intersect() ). + $filtered_taxonomies = []; + if ( ! empty( $args['post_type'] ) ) { + foreach ( $taxonomies as $taxonomy => $obj ) { + $tax_array = (array) $obj; + if ( in_array( $args['post_type'], $tax_array['object_type'] ) ) { + $filtered_taxonomies[ $taxonomy ] = $obj; + } + } + } else { + $filtered_taxonomies = $taxonomies; + } + + foreach ( $filtered_taxonomies as $taxonomy => $object ) { + $taxonomy_args = [ + 'label' => $object->label, + 'type' => Module::QUERY_CONTROL_ID, + 'label_block' => true, + 'multiple' => true, + 'object_type' => $taxonomy, + 'options' => [], + 'condition' => [ + 'post_type' => $object->object_type, + ], + 'export' => false, + ]; + + $count = wp_count_terms( $taxonomy ); + + $options = []; + + // For large websites, use Ajax to search + if ( $count > self::INLINE_MAX_RESULTS ) { + $taxonomy_args['type'] = Module::QUERY_CONTROL_ID; + + $taxonomy_args['filter_type'] = 'taxonomy'; + } else { + $taxonomy_args['type'] = Controls_Manager::SELECT2; + + $terms = get_terms( [ + 'taxonomy' => $taxonomy, + 'hide_empty' => false, + ] ); + + foreach ( $terms as $term ) { + $options[ $term->term_id ] = $term->name; + } + + $taxonomy_args['options'] = $options; + } + + $fields[ $taxonomy . '_ids' ] = $taxonomy_args; + } + + return parent::prepare_fields( $fields ); + } + + protected function get_default_options() { + return [ + 'popover' => false, + ]; + } + + protected function fix_offset( $query_args, $settings, $prefix = '' ) { + if ( 0 < $settings[ $prefix . 'offset' ] ) { + /** + * Due to a WordPress bug, the offset will be set later, in $this->fix_query_offset() + * @see https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination + */ + $query_args['offset_to_fix'] = $settings[ $prefix . 'offset' ]; + } + + return $query_args; + } + + protected function build_query_args( $settings, $control_id_prefix ) { + + $prefix = $control_id_prefix . '_'; + + $post_type = $settings[ $prefix . 'post_type' ]; + + $query_args = [ + 'orderby' => $settings['orderby'], + 'order' => $settings['order'], + 'ignore_sticky_posts' => 1, + 'post_status' => 'publish', // Hide drafts/private posts for admins + ]; + + if ( 'by_id' === $post_type ) { + $post_types = Utils::get_public_post_types(); + + $query_args['post_type'] = array_keys( $post_types ); + $query_args['posts_per_page'] = -1; + + $query_args['post__in'] = $settings[ $prefix . 'posts_ids' ]; + + if ( empty( $query_args['post__in'] ) ) { + // If no selection - return an empty query + $query_args['post__in'] = [ 0 ]; + } + } else { + $query_args['post_type'] = $post_type; + $query_args['posts_per_page'] = $settings['posts_per_page']; + $query_args['tax_query'] = []; + + $query_args = $this->fix_offset( $query_args, $settings ); + + $taxonomies = get_object_taxonomies( $post_type, 'objects' ); + + foreach ( $taxonomies as $object ) { + $setting_key = $prefix . $object->name . '_ids'; + + if ( ! empty( $settings[ $setting_key ] ) ) { + $query_args['tax_query'][] = [ + 'taxonomy' => $object->name, + 'field' => 'term_id', + 'terms' => $settings[ $setting_key ], + ]; + } + } + } + + if ( ! empty( $settings[ $prefix . 'authors' ] ) ) { + $query_args['author__in'] = $settings[ $prefix . 'authors' ]; + } + + $post__not_in = []; + if ( ! empty( $settings['exclude'] ) ) { + if ( in_array( 'current_post', $settings['exclude'], true ) ) { + $post_id = Utils::_unstable_get_super_global_value( $_REQUEST, 'post_id' ); + + if ( wp_doing_ajax() && $post_id ) { + $post__not_in[] = $post_id; + } elseif ( is_singular() ) { + $post__not_in[] = get_queried_object_id(); + } + } + + if ( in_array( 'manual_selection', $settings['exclude'], true ) && ! empty( $settings['exclude_ids'] ) ) { + $post__not_in = array_merge( $post__not_in, $settings['exclude_ids'] ); + } + } + + if ( ! empty( $settings['avoid_duplicates'] ) && 'yes' === $settings['avoid_duplicates'] ) { + $post__not_in = array_merge( $post__not_in, Module::$displayed_ids ); + } + + $query_args['post__not_in'] = $post__not_in; + + return $query_args; + } + + public function get_query_args( $control_id_prefix, $settings ) { + + $defaults = [ + $control_id_prefix . '_post_type' => 'post', + $control_id_prefix . '_posts_ids' => [], + 'orderby' => 'date', + 'order' => 'desc', + 'posts_per_page' => 3, + 'offset' => 0, + ]; + + $settings = wp_parse_args( $settings, $defaults ); + + $post_type = $settings[ $control_id_prefix . '_post_type' ]; + + if ( 'current_query' === $post_type ) { + $current_query_vars = $GLOBALS['wp_query']->query_vars; + + /** + * Current query variables. + * + * Filters the query variables for the current query. + * + * @since 1.0.0 + * + * @param array $current_query_vars Current query variables. + */ + $current_query_vars = apply_filters( 'elementor_pro/query_control/get_query_args/current_query', $current_query_vars ); + + return $current_query_vars; + } + + return $this->build_query_args( $settings, $control_id_prefix ); + } +} diff --git a/modules/query-control/controls/group-control-query.php b/modules/query-control/controls/group-control-query.php new file mode 100644 index 00000000..7d87025b --- /dev/null +++ b/modules/query-control/controls/group-control-query.php @@ -0,0 +1,568 @@ +get_args(); + static::$fields = $this->init_fields_by_name( $args['name'] ); + } + + protected function init_fields() { + $args = $this->get_args(); + + return $this->init_fields_by_name( $args['name'] ); + } + + protected function get_fields_array( $name ) { + $fields = []; + + $tab_keys = $this->get_tabs_keys( $name ); + $name .= '_'; + + $fields['post_type'] = [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'by_id' => esc_html__( 'Manual Selection', 'elementor-pro' ), + 'current_query' => esc_html__( 'Current Query', 'elementor-pro' ), + ], + ]; + + $fields['query_args'] = [ + 'type' => Controls_Manager::TABS, + ]; + + $tabs_wrapper = $tab_keys['tabs_wrapper']; + $include_wrapper = $tab_keys['include_wrapper']; + $exclude_wrapper = $tab_keys['exclude_wrapper']; + + $fields['query_include'] = [ + 'type' => Controls_Manager::TAB, + 'label' => esc_html__( 'Include', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'condition' => [ + 'post_type!' => [ + 'current_query', + 'by_id', + ], + ], + ]; + + $fields['posts_ids'] = [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_POST, + ], + 'condition' => [ + 'post_type' => 'by_id', + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_wrapper, + 'export' => false, + ]; + + $fields['include'] = [ + 'label' => esc_html__( 'Include By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'terms' => esc_html__( 'Term', 'elementor-pro' ), + 'authors' => esc_html__( 'Author', 'elementor-pro' ), + ], + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'label_block' => true, + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_wrapper, + ]; + + $fields['include_term_ids'] = [ + 'label' => esc_html__( 'Term', 'elementor-pro' ), + 'description' => esc_html__( 'Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_CPT_TAX, + 'display' => 'detailed', + ], + 'group_prefix' => $name, + 'condition' => [ + 'include' => 'terms', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_wrapper, + ]; + + $fields['include_authors'] = [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'label_block' => true, + 'type' => Query_Module::QUERY_CONTROL_ID, + 'multiple' => true, + 'default' => [], + 'options' => [], + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_AUTHOR, + ], + 'condition' => [ + 'include' => 'authors', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_wrapper, + 'export' => false, + ]; + + $fields['query_exclude'] = [ + 'type' => Controls_Manager::TAB, + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + ]; + + $fields['exclude'] = [ + 'label' => esc_html__( 'Exclude By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'current_post' => esc_html__( 'Current Post', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + 'terms' => esc_html__( 'Term', 'elementor-pro' ), + 'authors' => esc_html__( 'Author', 'elementor-pro' ), + ], + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'label_block' => true, + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + ]; + + $fields['exclude_ids'] = [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_POST, + ], + 'condition' => [ + 'exclude' => 'manual_selection', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + 'export' => false, + ]; + + $fields['exclude_term_ids'] = [ + 'label' => esc_html__( 'Term', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_CPT_TAX, + 'display' => 'detailed', + ], + 'group_prefix' => $name, + 'condition' => [ + 'exclude' => 'terms', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + 'export' => false, + ]; + + $fields['exclude_authors'] = [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_AUTHOR, + 'display' => 'detailed', + ], + 'condition' => [ + 'exclude' => 'authors', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + 'export' => false, + ]; + + $fields['avoid_duplicates'] = [ + 'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up. This only effects the frontend.', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + ]; + + $fields['offset'] = [ + 'label' => esc_html__( 'Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'description' => esc_html__( 'Use this setting to skip over posts (e.g. \'2\' to skip over 2 posts).', 'elementor-pro' ), + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $exclude_wrapper, + ]; + + $fields['select_date'] = [ + 'label' => esc_html__( 'Date', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'post_type' => '', + 'options' => [ + 'anytime' => esc_html__( 'All', 'elementor-pro' ), + 'today' => esc_html__( 'Past Day', 'elementor-pro' ), + 'week' => esc_html__( 'Past Week', 'elementor-pro' ), + 'month' => esc_html__( 'Past Month', 'elementor-pro' ), + 'quarter' => esc_html__( 'Past Quarter', 'elementor-pro' ), + 'year' => esc_html__( 'Past Year', 'elementor-pro' ), + 'exact' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'anytime', + 'multiple' => false, + 'condition' => [ + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'separator' => 'before', + ]; + + $fields['date_before'] = [ + 'label' => esc_html__( 'Before', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'post_type' => '', + 'label_block' => false, + 'multiple' => false, + 'placeholder' => esc_html__( 'Choose', 'elementor-pro' ), + 'condition' => [ + 'select_date' => 'exact', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'description' => esc_html__( 'Setting a ‘Before’ date will show all the posts published until the chosen date (inclusive).', 'elementor-pro' ), + ]; + + $fields['date_after'] = [ + 'label' => esc_html__( 'After', 'elementor-pro' ), + 'type' => Controls_Manager::DATE_TIME, + 'post_type' => '', + 'label_block' => false, + 'multiple' => false, + 'placeholder' => esc_html__( 'Choose', 'elementor-pro' ), + 'condition' => [ + 'select_date' => 'exact', + 'post_type!' => [ + 'by_id', + 'current_query', + ], + ], + 'description' => esc_html__( 'Setting an ‘After’ date will show all the posts published since the chosen date (inclusive).', 'elementor-pro' ), + ]; + + $fields['orderby'] = [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__( 'Date', 'elementor-pro' ), + 'post_title' => esc_html__( 'Title', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + 'modified' => esc_html__( 'Last Modified', 'elementor-pro' ), + 'comment_count' => esc_html__( 'Comment Count', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + ], + 'condition' => [ + 'post_type!' => 'current_query', + ], + ]; + + $fields['order'] = [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + 'condition' => [ + 'post_type!' => 'current_query', + ], + ]; + + $fields['posts_per_page'] = [ + 'label' => esc_html__( 'Posts Per Page', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 3, + 'condition' => [ + 'post_type!' => 'current_query', + ], + ]; + + $fields['ignore_sticky_posts'] = [ + 'label' => esc_html__( 'Ignore Sticky Posts', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'post_type' => 'post', + ], + 'description' => esc_html__( 'Sticky-posts ordering is visible on frontend only', 'elementor-pro' ), + ]; + + $fields['query_id'] = [ + 'label' => esc_html__( 'Query ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'description' => esc_html__( 'Give your Query a custom unique id to allow server side filtering', 'elementor-pro' ), + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + ]; + + return $fields; + } + + /** + * Build the group-controls array + * Note: this method completely overrides any settings done in Group_Control_Posts + * @param string $name + * + * @return array + */ + protected function init_fields_by_name( $name ) { + $fields = $this->get_fields_array( $name ); + + static::init_presets(); + + return $fields; + } + + /** + * Presets: filter controls subsets to be be used by the specific Group_Control_Query instance. + * + * Possible values: + * 'full' : (default) all presets + * 'include' : the 'include' tab - by id, by taxonomy, by author + * 'exclude': the 'exclude' tab - by id, by taxonomy, by author + * 'advanced_exclude': extend the 'exclude' preset with 'avoid-duplicates' & 'offset' + * 'date': date query controls + * 'pagination': posts per-page + * 'order': sort & ordering controls + * 'query_id': allow saving a specific query for future usage. + * + * Usage: + * full: build a Group_Controls_Query with all possible controls, + * when 'full' is passed, the Group_Controls_Query will ignore all other preset values. + * $this->add_group_control( + * Group_Control_Query::get_type(), + * [ + * ... + * 'presets' => [ 'full' ], + * ... + * ] ); + * + * Subset: build a Group_Controls_Query with subset of the controls, + * in the following example, the Query controls will set only the 'include' & 'date' query args. + * $this->add_group_control( + * Group_Control_Query::get_type(), + * [ + * ... + * 'presets' => [ 'include', 'date' ], + * ... + * ] ); + */ + protected static function init_presets() { + + $tabs = [ + 'query_args', + 'query_include', + 'query_exclude', + ]; + + static::$presets['include'] = array_merge( $tabs, [ + 'include', + 'include_ids', + 'include_term_ids', + 'include_authors', + ] ); + + static::$presets['exclude'] = array_merge( $tabs, [ + 'exclude', + 'exclude_ids', + 'exclude_term_ids', + 'exclude_authors', + ] ); + + static::$presets['advanced_exclude'] = array_merge( static::$presets['exclude'], [ + 'avoid_duplicates', + 'offset', + ] ); + + static::$presets['date'] = [ + 'select_date', + 'date_before', + 'date_after', + ]; + + static::$presets['pagination'] = [ + 'posts_per_page', + 'ignore_sticky_posts', + ]; + + static::$presets['order'] = [ + 'orderby', + 'order', + ]; + + static::$presets['query_id'] = [ + 'query_id', + ]; + } + + private function filter_by_presets( $presets, $fields ) { + + if ( in_array( 'full', $presets, true ) ) { + return $fields; + } + + $control_ids = []; + foreach ( static::$presets as $key => $preset ) { + $control_ids = array_merge( $control_ids, $preset ); + } + + foreach ( $presets as $preset ) { + if ( array_key_exists( $preset, static::$presets ) ) { + $control_ids = array_diff( $control_ids, static::$presets[ $preset ] ); + } + } + + foreach ( $control_ids as $remove ) { + unset( $fields[ $remove ] ); + } + + return $fields; + + } + + protected function prepare_fields( $fields ) { + + $args = $this->get_args(); + + if ( ! empty( $args['presets'] ) ) { + $fields = $this->filter_by_presets( $args['presets'], $fields ); + } + + $post_type_args = []; + if ( ! empty( $args['post_type'] ) ) { + $post_type_args['post_type'] = $args['post_type']; + } + + $post_types = Utils::get_public_post_types( $post_type_args ); + + $fields['post_type']['options'] = array_merge( $post_types, $fields['post_type']['options'] ); + $fields['post_type']['default'] = key( $post_types ); + $fields['posts_ids']['object_type'] = array_keys( $post_types ); + + //skip parent, go directly to grandparent + return Group_Control_Base::prepare_fields( $fields ); + } + + protected function get_child_default_args() { + $args = parent::get_child_default_args(); + $args['presets'] = [ 'full' ]; + + return $args; + } + + protected function get_default_options() { + return [ + 'popover' => false, + ]; + } + + protected function get_tabs_keys( $name ) { + return [ + 'tabs_wrapper' => $name . '_query_args', + 'include_wrapper' => $name . '_query_include', + 'exclude_wrapper' => $name . '_query_exclude', + ]; + } +} diff --git a/modules/query-control/controls/group-control-related.php b/modules/query-control/controls/group-control-related.php new file mode 100644 index 00000000..0cc9c119 --- /dev/null +++ b/modules/query-control/controls/group-control-related.php @@ -0,0 +1,122 @@ + esc_html__( 'Term', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_supported_taxonomies(), + 'label_block' => true, + 'multiple' => true, + 'condition' => [ + 'include' => 'terms', + 'post_type' => [ + 'related', + ], + ], + 'tabs_wrapper' => $tabs_wrapper, + 'inner_tab' => $include_wrapper, + ]; + + $related_fallback = [ + 'label' => esc_html__( 'Fallback', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'fallback_none' => esc_html__( 'None', 'elementor-pro' ), + 'fallback_by_id' => esc_html__( 'Manual Selection', 'elementor-pro' ), + 'fallback_recent' => esc_html__( 'Recent Posts', 'elementor-pro' ), + ], + 'default' => 'fallback_none', + 'description' => esc_html__( 'Displayed if no relevant results are found. Manual selection display order is random', 'elementor-pro' ), + 'condition' => [ + 'post_type' => 'related', + ], + 'separator' => 'before', + ]; + + $fallback_ids = [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_POST, + ], + 'condition' => [ + 'post_type' => 'related', + 'related_fallback' => 'fallback_by_id', + ], + 'export' => false, + ]; + + $fields = \Elementor\Utils::array_inject( $fields, 'include_term_ids', [ 'related_taxonomies' => $related_taxonomies ] ); + $fields = \Elementor\Utils::array_inject( $fields, 'offset', [ 'related_fallback' => $related_fallback ] ); + $fields = \Elementor\Utils::array_inject( $fields, 'related_fallback', [ 'fallback_ids' => $fallback_ids ] ); + + return $fields; + } + + protected function get_supported_taxonomies() { + $supported_taxonomies = []; + + $public_types = Utils::get_public_post_types(); + + foreach ( $public_types as $type => $title ) { + $taxonomies = get_object_taxonomies( $type, 'objects' ); + foreach ( $taxonomies as $key => $tax ) { + if ( ! array_key_exists( $key, $supported_taxonomies ) ) { + $label = $tax->label; + if ( in_array( $tax->label, $supported_taxonomies ) ) { + $label = $tax->label . ' (' . $tax->name . ')'; + } + $supported_taxonomies[ $key ] = $label; + } + } + } + + return $supported_taxonomies; + } + + protected static function init_presets() { + parent::init_presets(); + static::$presets['related'] = [ + 'related_fallback', + 'fallback_ids', + ]; + } +} diff --git a/modules/query-control/controls/group-control-taxonomy.php b/modules/query-control/controls/group-control-taxonomy.php new file mode 100644 index 00000000..c77bd063 --- /dev/null +++ b/modules/query-control/controls/group-control-taxonomy.php @@ -0,0 +1,38 @@ +get_tabs_keys( $name . '_' ); + $fields = parent::get_fields_array( $name ); + $new_fields = []; + + foreach ( $fields as $key => $field ) { + if ( 'query_args' === $key ) { + $new_fields['filter_by'] = [ + 'label' => esc_html__( 'Filter By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'show_all', + 'options' => [ + 'show_all' => esc_html__( 'Show All', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + 'tabs_wrapper' => $tab_keys['tabs_wrapper'], + 'inner_tab' => $tab_keys['include_wrapper'], + ]; + } + + $new_fields[ $key ] = $field; + } + + return $new_fields; + } +} diff --git a/modules/query-control/controls/query.php b/modules/query-control/controls/query.php new file mode 100644 index 00000000..e16477b3 --- /dev/null +++ b/modules/query-control/controls/query.php @@ -0,0 +1,63 @@ + '', + ] + ); + } + + /** + * Update control settings using mapping config + * + * @param $value + * @param array $control_args + * @param array $config + * + * @return mixed + */ + public function on_import_update_settings( $value, array $control_args, array $config ) { + switch ( $control_args['autocomplete']['object'] ) { + case Module::QUERY_OBJECT_POST: + case Module::QUERY_OBJECT_LIBRARY_TEMPLATE: + return $this->replace_id_from_mapping( $value, $config['post_ids'] ); + case Module::QUERY_OBJECT_TAX: + return $this->replace_id_from_mapping( $value, $config['term_ids'] ); + default: + return $value; + } + } + + /** + * replace id from config + * + * @param mixed $value + * @param array $mapping + * + * @return string + */ + private function replace_id_from_mapping( $value, array $mapping ): string { + return $mapping[ $value ] ?? $value; + } + +} diff --git a/modules/query-control/controls/template-query.php b/modules/query-control/controls/template-query.php new file mode 100644 index 00000000..96f69edb --- /dev/null +++ b/modules/query-control/controls/template-query.php @@ -0,0 +1,75 @@ + +
      + <# if ( data.actions.new.visible ) { #> + + <# } #> + <# if ( data.actions.edit.visible ) { #> + + <# } #> +
      + '', + 'actions' => [ + 'new' => [ + 'visible' => false, + 'label' => __( 'Create template', 'elementor-pro' ), + 'document_config' => [ + 'type' => null, + ], + 'after_action' => 'switch_document', + ], + 'edit' => [ + 'visible' => false, + 'label' => __( 'Edit template', 'elementor-pro' ), + 'after_action' => 'switch_document', + ], + ], + ] + ); + } +} diff --git a/modules/query-control/module.php b/modules/query-control/module.php new file mode 100644 index 00000000..4c766c8c --- /dev/null +++ b/modules/query-control/module.php @@ -0,0 +1,1045 @@ +add_actions(); + } + + public static function add_to_avoid_list( $ids ) { + if ( ! self::$ignore_avoid_list ) { + self::$displayed_ids = array_unique( array_merge( self::$displayed_ids, $ids ) ); + } + } + + public static function get_avoid_list_ids() { + return self::$displayed_ids; + } + + public function get_query_ignoring_avoid_list( $loop_widget, $query_name, $query_args ) { + $original_ignore = self::$ignore_avoid_list; + self::$ignore_avoid_list = true; + + try { + return $this->get_query( $loop_widget, $query_name, $query_args ); + } finally { + self::$ignore_avoid_list = $original_ignore; + } + } + + /** + * @deprecated 2.5.0 Use `Group_Control_Query` class capabilities instead. + * + * @param Widget_Base $widget + */ + public static function add_exclude_controls( $widget ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.5.0', 'class Group_Control_Query' ); + + $widget->add_control( + 'exclude', + [ + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'current_post' => esc_html__( 'Current Post', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + 'label_block' => true, + ] + ); + + $widget->add_control( + 'exclude_ids', + [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => self::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => self::QUERY_OBJECT_POST, + ], + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'condition' => [ + 'exclude' => 'manual_selection', + ], + ] + ); + + $widget->add_control( + 'avoid_duplicates', + [ + 'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up on the page. This only affects the frontend.', 'elementor-pro' ), + ] + ); + + } + + public function get_name() { + return 'query-control'; + } + + private function search_taxonomies( $query_params, $query_data, $data ) { + $by_field = $query_data['query']['by_field']; + $terms = get_terms( $query_params ); + + $results = []; + + foreach ( $terms as $term ) { + $results[] = [ + 'id' => $term->{$by_field}, + 'text' => $this->get_term_name( $term, $query_data['display'], $data ), + ]; + } + + return $results; + + } + + /** + * 'autocomplete' => [ + * 'object' => 'post|tax|user|library_template|attachment|js', // required + * 'display' => 'minimal(default)|detailed|custom_filter_name', + * 'by_field' => 'term_taxonomy_id(default)|term_id', // relevant only if `object` is tax|cpt_tax + * 'query' => [ + * 'post_type' => 'any|post|page|custom-post-type', // can be an array for multiple post types. + * // 'any' should not be used if 'object' is 'tax' or 'cpt_tax'. + * ... + * ], + * ], + * + * 'object' (required): the queried object. + * supported values: + * 'post' : will use WP_Query(), if query['post_type'] is empty or missing, will default to 'any'. + * 'tax' : will use get_terms(). + * When 'post_type' is provided, will first use get_object_taxonomies() to build 'taxonomy' + * args then invoke get_terms(). + * When both 'taxonomy' and 'post_type' are provided, 'post_type' is ignored. + * 'cpt_tax' : Used in frontend only, will be replaced to 'tax' by js. + * Will use get_object_taxonomies() to build 'taxonomy' args then use get_terms(). + * 'user' : will use WP_User_Query() with the args defined in 'query'. + * 'author' : will use WP_User_Query() with pre-defined args. + * 'library_template' : will use WP_Query() with post_type = Source_Local::CPT. + * 'attachment' : will use WP_Query() with post_type = attachment. + * 'js' : Query data is populated by JavaScript. + * By the time the data is sent to the server, + * the 'object' value should be replaced with one of the other valid 'object' values and + * the Query array populated accordingly. + * user_defined : will invoke apply_filters() using the user_defined value as filter name, + * `elementor/query/[get_value_titles|get_autocomplete]/{user_defined}`. + * + * 'display': output format + * supported values: + * 'minimal' (default) : name only + * 'detailed' : for Post & Taxonomies -> `[Taxonomy|Post-Type] : [parent] ... [parent] > name` + * for Users & Authors -> `name [email]` + * user_defined : will invoke apply_filters using the user_defined value as filter name, + * `elementor/query/[get_value_titles|get_autocomplete]/display/{user_defined}` + * + * `by_field`: value of 'id' field in taxonomy query. Relevant only if `object` is tax|cpt_tax + * supported values: + * 'term_taxonomy_id'(default) + * 'term_id' + * + * 'query': array of args to be passed "as-is" to the relevant query function (see 'object'). + * + ** + * + * @param array $data + * + * @return array | \WP_Error + */ + private function autocomplete_query_data( $data ) { + if ( empty( $data['autocomplete'] ) || empty( $data['q'] ) || empty( $data['autocomplete']['object'] ) ) { + return new \WP_Error( self::AUTOCOMPLETE_ERROR_CODE, 'Empty or incomplete data' ); + } + + $autocomplete = $data['autocomplete']; + + if ( in_array( $autocomplete['object'], self::$supported_objects_for_query, true ) ) { + $method_name = 'autocomplete_query_for_' . $autocomplete['object']; + if ( empty( $autocomplete['display'] ) ) { + $autocomplete['display'] = 'minimal'; + $data['autocomplete'] = $autocomplete; + } + $query = $this->$method_name( $data ); + if ( is_wp_error( $query ) ) { + return $query; + } + $autocomplete['query'] = $query; + } + + return $autocomplete; + } + + private function autocomplete_query_for_post( $data ) { + if ( ! isset( $data['autocomplete']['query'] ) ) { + return new \WP_Error( self::AUTOCOMPLETE_ERROR_CODE, 'Missing autocomplete[`query`] data' ); + } + $query = $data['autocomplete']['query']; + if ( empty( $query['post_type'] ) ) { + $query['post_type'] = 'any'; + } + $query['posts_per_page'] = -1; + $query['s'] = $data['q']; + + return $query; + } + + private function autocomplete_query_for_library_template( $data ) { + $query = $data['autocomplete']['query']; + + $query['post_type'] = Source_Local::CPT; + $query['orderby'] = 'meta_value'; + $query['order'] = 'ASC'; + + if ( empty( $query['posts_per_page'] ) ) { + $query['posts_per_page'] = -1; + } + $query['s'] = $data['q']; + + return $query; + } + + private function autocomplete_query_for_attachment( $data ) { + $query = $this->autocomplete_query_for_post( $data ); + if ( is_wp_error( $query ) ) { + return $query; + } + $query['post_type'] = 'attachment'; + $query['post_status'] = 'inherit'; + + return $query; + } + + private function autocomplete_query_for_tax( $data ) { + $query = $data['autocomplete']['query']; + + if ( empty( $query['taxonomy'] ) && ! empty( $query['post_type'] ) ) { + $query['taxonomy'] = get_object_taxonomies( $query['post_type'] ); + } + $query['search'] = $data['q']; + $query['hide_empty'] = false; + return $query; + } + + private function autocomplete_query_for_author( $data ) { + $query = $this->autocomplete_query_for_user( $data ); + if ( is_wp_error( $query ) ) { + return $query; + } + + return $this->add_edit_capability_to_user_query( $query ); + } + + private function autocomplete_query_for_user( $data ) { + $query = $data['autocomplete']['query']; + if ( ! empty( $query ) ) { + return $query; + } + + $query = [ + 'fields' => [ + 'ID', + 'display_name', + ], + 'search' => '*' . $data['q'] . '*', + 'search_columns' => [ + 'user_login', + 'user_nicename', + ], + ]; + if ( 'detailed' === $data['autocomplete']['display'] && Access_Control::user_can_access_private_posts() ) { + $query['fields'][] = 'user_email'; + } + return $query; + } + + private function get_titles_query_data( $data ) { + if ( empty( $data['get_titles'] ) || empty( $data['id'] ) || empty( $data['get_titles']['object'] ) ) { + return new \WP_Error( self::GET_TITLES_ERROR_CODE, 'Empty or incomplete data' ); + } + + $get_titles = $data['get_titles']; + if ( empty( $get_titles['query'] ) ) { + $get_titles['query'] = []; + } + + if ( in_array( $get_titles['object'], self::$supported_objects_for_query, true ) ) { + $method_name = 'get_titles_query_for_' . $get_titles['object']; + $query = $this->$method_name( $data ); + if ( is_wp_error( $query ) ) { + return $query; + } + $get_titles['query'] = $query; + } + + if ( empty( $get_titles['display'] ) ) { + $get_titles['display'] = 'minimal'; + } + + return $get_titles; + } + + private function get_titles_query_for_post( $data ) { + $query = $data['get_titles']['query']; + if ( empty( $query['post_type'] ) ) { + $query['post_type'] = 'any'; + } + $query['posts_per_page'] = -1; + $query['post__in'] = (array) $data['id']; + + return $query; + } + + private function get_titles_query_for_attachment( $data ) { + $query = $this->get_titles_query_for_post( $data ); + $query['post_type'] = 'attachment'; + $query['post_status'] = 'inherit'; + + return $query; + } + + private function get_titles_query_for_tax( $data ) { + $by_field = empty( $data['get_titles']['by_field'] ) ? 'term_taxonomy_id' : $data['get_titles']['by_field']; + return [ + $by_field => (array) $data['id'], + 'hide_empty' => false, + ]; + } + + + private function get_titles_query_for_library_template( $data ) { + $query = $data['get_titles']['query']; + + $query['post_type'] = Source_Local::CPT; + $query['orderby'] = 'meta_value'; + $query['order'] = 'ASC'; + + if ( empty( $query['posts_per_page'] ) ) { + $query['posts_per_page'] = -1; + } + + return $query; + } + + private function get_titles_query_for_author( $data ) { + $query = $this->get_titles_query_for_user( $data ); + + $query['has_published_posts'] = true; + + return $this->add_edit_capability_to_user_query( $query ); + } + + private function get_titles_query_for_user( $data ) { + $query = $data['get_titles']['query']; + if ( ! empty( $query ) ) { + return $query; + } + $query = [ + 'fields' => [ + 'ID', + 'display_name', + ], + 'include' => (array) $data['id'], + ]; + if ( 'detailed' === $data['get_titles']['display'] && Access_Control::user_can_access_private_posts() ) { + $query['fields'][] = 'user_email'; + } + return $query; + } + + /** + * @deprecated 2.6.0 use new `autocomplete` format + * + * @param $data + * + * @return mixed + */ + private function extract_post_type( $data ) { + + if ( ! empty( $data['query'] ) && ! empty( $data['query']['post_type'] ) ) { + return $data['query']['post_type']; + } + + return $data['object_type']; + } + + /** + * @deprecated 2.6.0 use new `autocomplete` format + * + * @param $data + * + * @return array + * @throws \Exception + */ + public function ajax_posts_filter_autocomplete_deprecated( $data ) { + $document = Utils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + if ( empty( $data['filter_type'] ) || empty( $data['q'] ) ) { + throw new \Exception( 'Bad request.' ); + } + + $results = []; + + switch ( $data['filter_type'] ) { + case 'taxonomy': + $query_params = [ + 'taxonomy' => $this->extract_post_type( $data ), + 'search' => $data['q'], + 'hide_empty' => false, + ]; + + $terms = get_terms( $query_params ); + if ( is_wp_error( $terms ) ) { + break; + } + + global $wp_taxonomies; + + foreach ( $terms as $term ) { + $term_name = $this->get_term_name_with_parents( $term ); + if ( ! empty( $data['include_type'] ) ) { + $text = $wp_taxonomies[ $term->taxonomy ]->labels->name . ': ' . $term_name; + } else { + $text = $term_name; + } + + $results[] = [ + 'id' => $term->term_taxonomy_id, + 'text' => $text, + ]; + } + + break; + + case 'by_id': + case 'post': + $query_params = [ + 'post_type' => $this->extract_post_type( $data ), + 's' => $data['q'], + 'posts_per_page' => -1, + ]; + + if ( 'attachment' === $query_params['post_type'] ) { + $query_params['post_status'] = 'inherit'; + } + + $query = new \WP_Query( $query_params ); + + foreach ( $query->posts as $post ) { + $post_type_obj = get_post_type_object( $post->post_type ); + if ( ! empty( $data['include_type'] ) ) { + $text = $post_type_obj->labels->name . ': ' . $post->post_title; + } else { + $text = ( $post_type_obj->hierarchical ) ? $this->get_post_name_with_parents( $post ) : $post->post_title; + } + + $results[] = [ + 'id' => $post->ID, + 'text' => esc_html( $text ), + ]; + } + break; + + case 'author': + $query_params = [ + 'has_published_posts' => true, + 'fields' => [ + 'ID', + 'display_name', + ], + 'search' => '*' . $data['q'] . '*', + 'search_columns' => [ + 'user_login', + 'user_nicename', + ], + ]; + + $query_params = $this->add_edit_capability_to_user_query( $query_params ); + + $user_query = new \WP_User_Query( $query_params ); + + foreach ( $user_query->get_results() as $author ) { + $results[] = [ + 'id' => $author->ID, + 'text' => $author->display_name, + ]; + } + break; + default: + $results = apply_filters( 'elementor/query/get_autocomplete/' . $data['filter_type'], [], $data ); + } + + return [ + 'results' => $results, + ]; + } + + /** + * @throws \Exception + */ + public static function verify_user_access_for_editing( array $data ): void { + Access_Control::verify_user_editing_capability(); + + if ( isset( $data['editor_post_id'] ) ) { + Access_Control::verify_post_edit_access( (int) $data['editor_post_id'] ); + } + } + + /** + * @param array $data + * + * @return array + * @throws \Exception + */ + public function ajax_posts_filter_autocomplete( array $data ) { + $this->verify_user_access_for_editing( $data ); + + $query_data = $this->autocomplete_query_data( $data ); + if ( is_wp_error( $query_data ) ) { + /** @var \WP_Error $query_data */ + throw new \Exception( $query_data->get_error_code() . ':' . $query_data->get_error_message() ); + } + + $results = []; + $display = $query_data['display']; + $query_args = $query_data['query']; + $query_args['no_found_rows'] = true; + + switch ( $query_data['object'] ) { + case self::QUERY_OBJECT_TAX: + $by_field = ! empty( $query_data['by_field'] ) ? $query_data['by_field'] : 'term_taxonomy_id'; + $terms = get_terms( $query_args ); + if ( is_wp_error( $terms ) ) { + break; + } + foreach ( $terms as $term ) { + if ( apply_filters( "elementor/query/get_autocomplete/tax/{$display}", true, $term, $data ) ) { + $results[] = [ + 'id' => $term->{$by_field}, + 'text' => $this->get_term_name( $term, $display, $data ), + ]; + } + } + break; + case self::QUERY_OBJECT_ATTACHMENT: + case self::QUERY_OBJECT_POST: + $query = new \WP_Query( $query_args ); + + foreach ( $query->posts as $post ) { + if ( ! Access_Control::user_can_edit( $post->ID ) ) { + continue; + } + + if ( apply_filters( "elementor/query/get_autocomplete/custom/{$display}", true, $post, $data ) ) { + $text = $this->format_post_for_display( $post, $display, $data ); + $results[] = [ + 'id' => $post->ID, + 'text' => $text, + ]; + } + } + break; + case self::QUERY_OBJECT_LIBRARY_TEMPLATE: + $query = new \WP_Query( $query_args ); + + foreach ( $query->posts as $post ) { + if ( ! Access_Control::user_can_edit( $post->ID ) ) { + continue; + } + + $document = Plugin::elementor()->documents->get( $post->ID ); + if ( $document ) { + $text = esc_html( $post->post_title ) . ' (' . $document->get_post_type_title() . ')'; + $results[] = [ + 'id' => $post->ID, + 'text' => $text, + ]; + } + } + break; + case self::QUERY_OBJECT_USER: + case self::QUERY_OBJECT_AUTHOR: + $user_query = new \WP_User_Query( $query_args ); + + foreach ( $user_query->get_results() as $user ) { + if ( apply_filters( "elementor/query/get_autocomplete/user/{$display}", true, $user, $data ) ) { + $results[] = [ + 'id' => $user->ID, + 'text' => $this->format_user_for_display( $user, $display, $data ), + ]; + } + } + break; + default: + $results = apply_filters( 'elementor/query/get_autocomplete/' . $query_data['filter_type'], $results, $data ); + } + + return [ + 'results' => $results, + ]; + } + + /** + * @param $request + * + * @return array + * @throws \Exception + * @deprecated 2.6.0 use new `autocomplete` format + * + */ + public function ajax_posts_control_value_titles_deprecated( $request ) { + $document = Utils::_unstable_get_document_for_edit( $request['editor_post_id'] ); + + $ids = (array) $request['id']; + + $results = []; + + switch ( $request['filter_type'] ) { + case 'taxonomy': + $terms = get_terms( + [ + 'term_taxonomy_id' => $ids, + 'hide_empty' => false, + ] + ); + if ( is_wp_error( $terms ) ) { + break; + } + + global $wp_taxonomies; + foreach ( $terms as $term ) { + $term_name = $this->get_term_name_with_parents( $term ); + if ( ! empty( $request['include_type'] ) ) { + $text = $wp_taxonomies[ $term->taxonomy ]->labels->name . ': ' . $term_name; + } else { + $text = $term_name; + } + $results[ $term->{$by_field} ] = $text; + } + break; + + case 'by_id': + case 'post': + $query = new \WP_Query( + [ + 'post_type' => 'any', + 'post__in' => $ids, + 'posts_per_page' => -1, + ] + ); + + foreach ( $query->posts as $post ) { + $results[ $post->ID ] = esc_html( $post->post_title ); + } + break; + + case 'author': + $query_params = [ + 'has_published_posts' => true, + 'fields' => [ + 'ID', + 'display_name', + ], + 'include' => $ids, + ]; + + $query_params = $this->add_edit_capability_to_user_query( $query_params ); + + $user_query = new \WP_User_Query( $query_params ); + + foreach ( $user_query->get_results() as $author ) { + $results[ $author->ID ] = $author->display_name; + } + break; + default: + $results = apply_filters( 'elementor/query/get_value_titles/' . $request['filter_type'], [], $request ); + } + + return $results; + } + + /** + * @throws \Exception + */ + public function ajax_posts_control_value_titles( $request ) { + $this->verify_user_access_for_editing( $request ); + + $query_data = $this->get_titles_query_data( $request ); + if ( is_wp_error( $query_data ) ) { + return []; + } + $display = $query_data['display']; + $query_args = $query_data['query']; + $query_args['no_found_rows'] = true; + + $results = []; + switch ( $query_data['object'] ) { + case self::QUERY_OBJECT_TAX: + $by_field = ! empty( $query_data['by_field'] ) ? $query_data['by_field'] : 'term_taxonomy_id'; + + // The term_id is not working in 2022-01-18, this is a hack to replace the term id with + // `include`, the code is a legacy code so the solution is minimal as possible. + if ( isset( $query_args['term_id'] ) ) { + $query_args['include'] = array_map( 'intval', $query_args['term_id'] ); + } + + $terms = get_terms( $query_args ); + + if ( is_wp_error( $terms ) ) { + break; + } + foreach ( $terms as $term ) { + if ( apply_filters( "elementor/query/get_value_titles/tax/{$display}", true, $term, $request ) ) { + $results[ $term->{$by_field} ] = $this->get_term_name( $term, $display, $request, 'get_value_titles' ); + } + } + break; + + case self::QUERY_OBJECT_ATTACHMENT: + case self::QUERY_OBJECT_POST: + $query = new \WP_Query( $query_args ); + + foreach ( $query->posts as $post ) { + if ( ! Access_Control::user_can_edit( $post->ID ) ) { + continue; + } + + if ( apply_filters( "elementor/query/get_value_titles/custom/{$display}", true, $post, $request ) ) { + $results[ $post->ID ] = $this->format_post_for_display( $post, $display, $request, 'get_value_titles' ); + } + } + break; + case self::QUERY_OBJECT_LIBRARY_TEMPLATE: + $query = new \WP_Query( $query_args ); + + foreach ( $query->posts as $post ) { + if ( ! Access_Control::user_can_edit( $post->ID ) ) { + continue; + } + + $document = Plugin::elementor()->documents->get( $post->ID ); + if ( $document ) { + $results[ $post->ID ] = htmlentities( esc_html( $post->post_title ) ) . ' (' . $document->get_post_type_title() . ')'; + } + } + break; + case self::QUERY_OBJECT_AUTHOR: + case self::QUERY_OBJECT_USER: + $user_query = new \WP_User_Query( $query_args ); + + foreach ( $user_query->get_results() as $user ) { + if ( apply_filters( "elementor/query/get_value_titles/user/{$display}", true, $user, $request ) ) { + $results[ $user->ID ] = $this->format_user_for_display( $user, $display, $request, 'get_value_titles' ); + } + } + break; + default: + $results = apply_filters( "elementor/query/get_value_titles/{$query_data['filter_type']}", $results, $request ); + } + + return $results; + } + + private function get_term_name( $term, $display, $request, $filter_name = 'get_autocomplete' ) { + global $wp_taxonomies; + $term_name = $this->get_term_name_with_parents( $term ); + switch ( $display ) { + case 'detailed': + $text = $wp_taxonomies[ $term->taxonomy ]->labels->name . ': ' . $term_name; + break; + case 'minimal': + $text = $term_name; + break; + default: + $text = apply_filters( "elementor/query/{$filter_name}/display/{$display}", $term_name, $request ); + break; + } + return $text; + } + + /** + * @param \WP_Post $post + * @param string $display + * @param array $data + * @param string $filter_name + * + * @return mixed|string|void + */ + private function format_post_for_display( $post, $display, $data, $filter_name = 'get_autocomplete' ) { + $post_type_obj = get_post_type_object( $post->post_type ); + switch ( $display ) { + case 'minimal': + $text = ( $post_type_obj->hierarchical ) ? $this->get_post_name_with_parents( $post ) : $post->post_title; + break; + case 'detailed': + $text = $post_type_obj->labels->name . ': ' . ( $post_type_obj->hierarchical ) ? $this->get_post_name_with_parents( $post ) : $post->post_title; + break; + default: + $text = apply_filters( "elementor/query/{$filter_name}/display/{$display}", $post->post_title, $post->ID, $data ); + break; + } + + return esc_html( $text ); + } + + /** + * @param \WP_User $user + * @param string $display + * @param array $data + * @param string $filter_name + * + * @return string + */ + private function format_user_for_display( $user, $display, $data, $filter_name = 'get_autocomplete' ) { + switch ( $display ) { + case 'minimal': + $text = $user->display_name; + break; + case 'detailed': + if ( Access_Control::user_can_access_private_posts() ) { + $text = sprintf( '%s (%s)', $user->display_name, $user->user_email ); + } else { + $text = $user->display_name; + } + break; + default: + $text = apply_filters( "elementor/query/{$filter_name}/display/{$display}", $user, $data ); + break; + } + + return $text; + } + + private function query_data_compatibility( $data ) { + if ( isset( $data['query']['filter_type'] ) ) { + $data['filter_type'] = $data['query']['filter_type']; + } + if ( isset( $data['query']['object_type'] ) ) { + $data['object_type'] = $data['query']['object_type']; + } + if ( isset( $data['query']['include_type'] ) ) { + $data['include_type'] = $data['query']['include_type']; + } + if ( isset( $data['query']['post_type'] ) ) { + $data['post_type'] = $data['query']['post_type']; + } + return $data; + } + + public function register_controls( Controls_Manager $controls_manager ) { + $controls_manager->add_group_control( Group_Control_Posts::get_type(), new Group_Control_Posts() ); + + $controls_manager->add_group_control( Group_Control_Query::get_type(), new Group_Control_Query() ); + + $controls_manager->add_group_control( Group_Control_Related::get_type(), new Group_Control_Related() ); + + $controls_manager->add_group_control( Group_Control_Taxonomy::get_type(), new Group_Control_Taxonomy() ); + + $controls_manager->register( new Query() ); + + $controls_manager->register( new Template_Query() ); + } + + /** + * get_term_name_with_parents + * @param \WP_Term $term + * @param int $max + * + * @return string + */ + private function get_term_name_with_parents( \WP_Term $term, $max = 3 ) { + if ( 0 === $term->parent ) { + return $term->name; + } + $separator = is_rtl() ? ' < ' : ' > '; + $test_term = $term; + $names = []; + while ( $test_term->parent > 0 ) { + $test_term = get_term( $test_term->parent ); + if ( ! $test_term ) { + break; + } + $names[] = $test_term->name; + } + + $names = array_reverse( $names ); + if ( count( $names ) < ( $max ) ) { + return implode( $separator, $names ) . $separator . $term->name; + } + + $name_string = ''; + for ( $i = 0; $i < ( $max - 1 ); $i++ ) { + $name_string .= $names[ $i ] . $separator; + } + return $name_string . '...' . $separator . $term->name; + } + + /** + * get post name with parents + * @param \WP_Post $post + * @param int $max + * + * @return string + */ + private function get_post_name_with_parents( $post, $max = 3 ) { + if ( 0 === $post->post_parent ) { + return $post->post_title; + } + $separator = is_rtl() ? ' < ' : ' > '; + $test_post = $post; + $names = []; + while ( $test_post->post_parent > 0 ) { + $test_post = get_post( $test_post->post_parent ); + if ( ! $test_post ) { + break; + } + $names[] = $test_post->post_title; + } + + $names = array_reverse( $names ); + if ( count( $names ) < ( $max ) ) { + return implode( $separator, $names ) . $separator . $post->post_title; + } + + $name_string = ''; + for ( $i = 0; $i < ( $max - 1 ); $i++ ) { + $name_string .= $names[ $i ] . $separator; + } + return $name_string . '...' . $separator . $post->post_title; + } + + /** + * @deprecated 2.5.0 Use `Elementor_Post_Query` class capabilities instead. + * + * @param string $control_id + * @param array $settings + * + * @return array + */ + public function get_query_args( $control_id, $settings ) { + Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '2.5.0', 'class Elementor_Post_Query' ); + + $controls_manager = Plugin::elementor()->controls_manager; + + /** @var Group_Control_Posts $posts_query */ + $posts_query = $controls_manager->get_control_groups( Group_Control_Posts::get_type() ); + + return $posts_query->get_query_args( $control_id, $settings ); + } + + /** + * @param \Elementor\Widget_Base $widget + * @param string $name + * @param array $query_args + * @param array $fallback_args + * + * @return \WP_Query + */ + public function get_query( $widget, $name, $query_args = [], $fallback_args = [] ) { + $prefix = $name . '_'; + $post_type = $widget->get_settings( $prefix . 'post_type' ); + if ( 'related' === $post_type ) { + $elementor_query = new Elementor_Related_Query( $widget, $name, $query_args, $fallback_args ); + } else { + $elementor_query = new Elementor_Post_Query( $widget, $name, $query_args ); + } + return $elementor_query->get_query(); + } + + /** + * @param Ajax $ajax_manager + */ + public function register_ajax_actions( $ajax_manager ) { + $ajax_manager->register_ajax_action( 'query_control_value_titles', [ $this, 'ajax_posts_control_value_titles' ] ); + $ajax_manager->register_ajax_action( 'pro_panel_posts_control_filter_autocomplete', [ $this, 'ajax_posts_filter_autocomplete' ] ); + /** + * @deprecated 2.6.0 use new `autocomplete` format + */ + $ajax_manager->register_ajax_action( 'query_control_value_titles_deprecated', [ $this, 'ajax_posts_control_value_titles_deprecated' ] ); + $ajax_manager->register_ajax_action( 'pro_panel_posts_control_filter_autocomplete_deprecated', [ $this, 'ajax_posts_filter_autocomplete_deprecated' ] ); + } + + protected function add_actions() { + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + add_action( 'elementor/controls/register', [ $this, 'register_controls' ] ); + } + + /** + * In WordPress 5.9 the 'who' query param was deprecated, this method + * adding the new `capability` query param to the query and still support old versions of WordPress. + * + * @param $query + * + * @return mixed + */ + private function add_edit_capability_to_user_query( $query ) { + // Capability queries were only introduced in WP 5.9. + if ( version_compare( $GLOBALS['wp_version'], '5.9-alpha', '>=' ) ) { + $query['capability'] = [ 'edit_posts' ]; + } else { + $query['who'] = 'authors'; + } + + return $query; + } +} diff --git a/modules/role-manager/module.php b/modules/role-manager/module.php new file mode 100644 index 00000000..1066b442 --- /dev/null +++ b/modules/role-manager/module.php @@ -0,0 +1,133 @@ +get_role_manager_options(); + } + + public function display_role_controls( $role_slug, $role_data ) { + static $options = false; + + if ( ! API::is_license_active() || ! API::is_licence_has_feature( static::ROLE_MANAGER_OPTION_NAME, API::BC_VALIDATION_CALLBACK ) ) { + // Promotions for PRO when the license not active. + $this->print_role_controls_promotion(); + + return; + } + + if ( ! $options ) { + $options = [ + 'excluded_options' => Plugin::elementor()->role_manager->get_role_manager_options(), + 'advanced_options' => $this->get_role_manager_options(), + ]; + } + $id = self::ROLE_MANAGER_OPTION_NAME . '_' . $role_slug . '_design'; + $name = 'elementor_' . self::ROLE_MANAGER_OPTION_NAME . '[' . $role_slug . '][]'; + $checked = isset( $options['advanced_options'][ $role_slug ] ) ? $options['advanced_options'][ $role_slug ] : []; + + ?> + + add_section( 'general', 'advanced-role-manager', [ + 'fields' => [ + self::ROLE_MANAGER_OPTION_NAME => [ + 'field_args' => [ + 'type' => 'raw_html', + 'html' => '', + ], + 'setting_args' => [ + 'sanitize_callback' => [ $this, 'save_advanced_options' ], + ], + ], + ], + ] ); + } + + private function print_role_controls_promotion() { + ?> + + get_connect_url(); + } + + private function get_connect_url() { + return Plugin::instance()->license_admin->get_connect_url( [ + 'utm_source' => 'wp-role-manager', + 'utm_medium' => 'wp-dash', + 'utm_campaign' => 'connect-and-activate-license', + ] ); + } + + public function __construct() { + parent::__construct(); + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . RoleManagerBase::PAGE_ID, [ $this, 'register_admin_fields' ], 100 ); + } + remove_action( 'elementor/role/restrictions/controls', [ Plugin::elementor()->role_manager, 'get_go_pro_link_html' ] ); + add_action( 'elementor/role/restrictions/controls', [ $this, 'display_role_controls' ], 10, 2 ); + add_filter( 'elementor/editor/user/restrictions', [ $this, 'get_user_restrictions' ] ); + } +} diff --git a/modules/screenshots/module.php b/modules/screenshots/module.php new file mode 100644 index 00000000..219efc64 --- /dev/null +++ b/modules/screenshots/module.php @@ -0,0 +1,275 @@ +offsetGet( 'content-type' ); + + header( 'content-type: ' . $content_type ); + + return wp_remote_retrieve_body( $response ); + } + + /** + * Save screenshot and attached it to the post. + * + * @param $data + * + * @return bool|string + * @throws \Exception + */ + public function ajax_save( $data ) { + if ( empty( $data['screenshot'] ) || empty( $data['post_id'] ) ) { + return false; + } + + if ( ! $this->can_user_manage_screenshots( $data['post_id'] ) ) { + return false; + } + + $screenshot = new Screenshot( $data['post_id'], $data['screenshot'] ); + + $screenshot + ->create_dir() + ->upload() + ->remove_old_attachment() + ->create_new_attachment() + ->unmark_as_failed(); + + return $screenshot->get_screenshot_url(); + } + + /** + * Remove the screenshot image and the attachment data. + * + * @param $data + * + * @return bool + */ + public function ajax_delete( $data ) { + if ( empty( $data['post_id'] ) ) { + return false; + } + + if ( ! $this->can_user_manage_screenshots( $data['post_id'] ) ) { + return false; + } + + $screenshot = new Screenshot( $data['post_id'] ); + + $screenshot + ->remove_old_attachment() + ->remove_old_post_meta() + ->unmark_as_failed(); + + return true; + } + + /** + * Mark screenshot as failed. + * + * @param $data + * + * @return bool + */ + public function ajax_screenshot_failed( $data ) { + if ( empty( $data['post_id'] ) ) { + return false; + } + + if ( ! $this->can_user_manage_screenshots( $data['post_id'] ) ) { + return false; + } + + $screenshot = new Screenshot( $data['post_id'] ); + + $screenshot->mark_as_failed(); + + return true; + } + + /** + * Extends the json of the templates. + * sets a screenshot as a thumbnail if exists, and if not will add a url to generate screenshot for + * the specific template. + * + * @param array $template + * + * @return array + */ + public function extend_templates_json_structure( $template ) { + + if ( ! empty( $template['thumbnail'] ) ) { + return $template; + } + + $attachment_data = get_post_meta( $template['id'], Screenshot::POST_META_KEY, true ); + + if ( isset( $attachment_data['url'] ) ) { + $template['thumbnail'] = $attachment_data['url']; + + return $template; + } + + $failed_to_create_screenshot = get_post_meta( $template['id'], Screenshot::FAILED_POST_META_KEY, true ); + + // If it failed to create screenshot before, it should not set screenshot_url, and should not try + // to create another screenshot until the next edit of the template. + if ( ! $failed_to_create_screenshot ) { + $template['screenshot_url'] = Render_Mode_Screenshot::get_url( $template['id'] ); + } + + return $template; + } + + /** + * @param \WP_Query $query + */ + public function filter_screenshots_from_attachments_query( \WP_Query $query ) { + global $pagenow, $typenow; + + if ( 'upload.php' !== $pagenow || 'attachment' !== $typenow ) { + return; + } + + if ( empty( $query->query_vars['meta_query'] ) ) { + $query->query_vars['meta_query'] = []; + } + + $query->query_vars['meta_query'][] = [ + 'key' => Screenshot::IS_SCREENSHOT_POST_META_KEY, + 'compare' => 'NOT EXISTS', + ]; + } + + public function filter_screenshots_from_ajax_attachments_query( $query ) { + if ( empty( $query['meta_query'] ) ) { + $query['meta_query'] = []; + } + + $query['meta_query'][] = [ + 'key' => Screenshot::IS_SCREENSHOT_POST_META_KEY, + 'compare' => 'NOT EXISTS', + ]; + + return $query; + } + + /** + * Register screenshots action. + * + * @param \Elementor\Core\Common\Modules\Ajax\Module $ajax_manager + */ + public function register_ajax_actions( $ajax_manager ) { + $ajax_manager->register_ajax_action( 'screenshot_save', [ $this, 'ajax_save' ] ); + $ajax_manager->register_ajax_action( 'screenshot_delete', [ $this, 'ajax_delete' ] ); + $ajax_manager->register_ajax_action( 'screenshot_failed', [ $this, 'ajax_screenshot_failed' ] ); + } + + /** + * @param Render_Mode_Manager $manager + * + * @throws \Exception + */ + public function register_render_mode( Render_Mode_Manager $manager ) { + $manager->register_render_mode( Render_Mode_Screenshot::class ); + } + + /** + * Check and validate proxy mode. + * + * @param array $query_params + * + * @return bool + * @throws \Requests_Exception_HTTP_400 + * @throws \Requests_Exception_HTTP_403 + * @throws Status400 + * @throws Status403 + */ + protected function is_screenshot_proxy_mode( array $query_params ) { + $is_proxy = isset( $query_params['screenshot_proxy'] ); + + if ( $is_proxy ) { + if ( ! wp_verify_nonce( $query_params['nonce'], self::SCREENSHOT_PROXY_NONCE_ACTION ) ) { + // WP >= 6.2-alpha + if ( class_exists( '\WpOrg\Requests\Exception\Http\Status403' ) ) { + throw new \WpOrg\Requests\Exception\Http\Status403(); + } else { + throw new \Requests_Exception_HTTP_403(); + } + } + + if ( ! $query_params['href'] ) { + // WP >= 6.2-alpha + if ( class_exists( '\WpOrg\Requests\Exception\Http\Status400' ) ) { + throw new \WpOrg\Requests\Exception\Http\Status400(); + } else { + throw new \Requests_Exception_HTTP_400(); + } + } + } + + return $is_proxy; + } + + /** + * @param $post_id + * + * @return bool + * @throws \Exception + */ + private function can_user_manage_screenshots( $post_id ) { + return Utils::_unstable_get_document_for_edit( $post_id ) && current_user_can( 'upload_files' ); + } + + /** + * Module constructor. + */ + public function __construct() { + parent::__construct(); + + if ( $this->is_screenshot_proxy_mode( $_GET ) ) { // phpcs:ignore -- Checking nonce inside the method. + echo $this->get_proxy_data( htmlspecialchars( $_GET['href'] ) ); // phpcs:ignore -- Nonce was checked on the above method + die; + } + + add_action( 'elementor/frontend/render_mode/register', [ $this, 'register_render_mode' ] ); + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + add_action( 'parse_query', [ $this, 'filter_screenshots_from_attachments_query' ] ); + add_filter( 'ajax_query_attachments_args', [ $this, 'filter_screenshots_from_ajax_attachments_query' ] ); + add_filter( 'elementor-pro/site-editor/data/template', [ $this, 'extend_templates_json_structure' ] ); + } +} diff --git a/modules/screenshots/render-mode-screenshot.php b/modules/screenshots/render-mode-screenshot.php new file mode 100644 index 00000000..e51e5c3e --- /dev/null +++ b/modules/screenshots/render-mode-screenshot.php @@ -0,0 +1,76 @@ +get_locations_manager(), 'builder_wrapper' ], + 9999999 + ); + + add_filter( 'template_include', [ $this, 'filter_template' ] ); + } + + public function filter_template() { + return ELEMENTOR_PATH . 'modules/page-templates/templates/canvas.php'; + } + + public function is_static() { + return true; + } + + public function enqueue_scripts() { + $suffix = ( Utils::is_script_debug() || Utils::is_elementor_tests() && ELEMENTOR_PRO_TESTS ) ? '' : '.min'; + + wp_enqueue_script( + 'dom-to-image', + ELEMENTOR_PRO_ASSETS_URL . "/lib/dom-to-image/js/dom-to-image{$suffix}.js", + [], + '2.6.0', + true + ); + + wp_enqueue_script( + 'html2canvas', + ELEMENTOR_PRO_ASSETS_URL . "/lib/html2canvas/js/html2canvas{$suffix}.js", + [], + '1.0.0-rc.5', + true + ); + + wp_enqueue_script( + 'elementor-screenshot', + ELEMENTOR_PRO_ASSETS_URL . "/js/screenshot{$suffix}.js", + [ 'dom-to-image', 'html2canvas' ], + ELEMENTOR_PRO_VERSION, + true + ); + + $config = [ + 'selector' => '.elementor-' . $this->post_id, + 'nonce' => wp_create_nonce( Module::SCREENSHOT_PROXY_NONCE_ACTION ), + 'home_url' => home_url(), + 'post_id' => $this->post_id, + ]; + + wp_add_inline_script( 'elementor-screenshot', 'var ElementorScreenshotConfig = ' . wp_json_encode( $config ) . ';' ); + } +} diff --git a/modules/screenshots/screenshot.php b/modules/screenshots/screenshot.php new file mode 100644 index 00000000..85264dcf --- /dev/null +++ b/modules/screenshots/screenshot.php @@ -0,0 +1,251 @@ +post_id = $post_id; + $this->base64_image = $base64_image; + } + + /** + * Creates the directory if needed + add index.html file for security reasons. + * + * @return $this + */ + public function create_dir() { + $dir = wp_upload_dir()['basedir'] . '/' . self::SCREENSHOT_DIR; + $html_file = $dir . '/index.html'; + + if ( file_exists( $html_file ) ) { + return $this; + }; + + if ( ! file_exists( $dir ) ) { + wp_mkdir_p( $dir ); + } + + touch( $html_file ); + + return $this; + } + + /** + * Uploads the base64 image it self. + * + * TODO: Use Upload Manager when ready. + * + * @return $this + * @throws \Exception + */ + public function upload() { + if ( ! $this->base64_image ) { + throw new \Exception( 'Cannot upload an image with out base64_image.' ); + } + + $file_content = substr( $this->base64_image, strlen( 'data:image/png;base64,' ) ); + + add_filter( 'wp_unique_filename', [ $this, 'get_file_name' ] ); + add_filter( 'upload_dir', [ $this, 'extend_upload_dirs_array' ] ); + + $this->upload_bits = wp_upload_bits( + $this->get_file_name(), + null, + base64_decode( $file_content ) + ); + + remove_filter( 'wp_unique_filename', [ $this, 'get_file_name' ] ); + remove_filter( 'upload_dir', [ $this, 'extend_upload_dirs_array' ] ); + + return $this; + } + + /** + * Removes the old attachment if there is an old screenshot image. + * + * @return $this + */ + public function remove_old_attachment() { + $post_meta = get_post_meta( $this->post_id, self::POST_META_KEY, true ); + + if ( ! $post_meta ) { + return $this; + } + + wp_delete_attachment( $post_meta['id'] ); + + return $this; + } + + /** + * Removes the old post meta of the current post. + * + * @return $this + */ + public function remove_old_post_meta() { + delete_post_meta( $this->post_id, self::POST_META_KEY ); + + return $this; + } + + /** + * Creates an attachment to the new screenshot and attach it to the original post + * via post_meta. + * + * @return $this + * @throws \Exception + */ + public function create_new_attachment() { + $upload_bits = $this->get_upload_bits(); + + $info = wp_check_filetype( $upload_bits['file'] ); + $post_mime_type = null; + + if ( $info ) { + $post_mime_type = $info['type']; + } + + $attachment_id = wp_insert_attachment( + [ + 'post_title' => $this->get_file_name(), + 'guid' => $upload_bits['url'], + 'post_mime_type' => $post_mime_type, + 'meta_input' => [ + self::IS_SCREENSHOT_POST_META_KEY => true, + ], + ], + $upload_bits['file'], + $this->post_id + ); + + update_post_meta( $this->post_id, self::POST_META_KEY, [ + 'id' => $attachment_id, + 'url' => $upload_bits['url'], + ] ); + + return $this; + } + + /** + * Mark the post that the screenshot capture was failed. + * + * @return $this + */ + public function mark_as_failed() { + update_post_meta( + $this->post_id, + self::FAILED_POST_META_KEY, + ( new \DateTime() )->format( 'Y-m-d H:i:s' ) + ); + + return $this; + } + + /** + * Remove the failed_screenshot post meta. + * + * @return $this + */ + public function unmark_as_failed() { + delete_post_meta( $this->post_id, self::FAILED_POST_META_KEY ); + + return $this; + } + + /** + * Get the file name, + * if not exists will generate it. + * + * @return string + */ + public function get_file_name() { + if ( ! $this->file_name ) { + $now = ( new \DateTime() )->format( 'Y-m-d-H-i-s' ); + $random_str = Utils::generate_random_string(); + + $this->file_name = "Elementor-post-screenshot_{$this->post_id}_{$now}_{$random_str}.png"; + } + + return $this->file_name; + } + + /** + * Extend and change the upload_dirs original method + * to update the current screenshot to custom directory. + * + * @param $upload_dirs + * + * @return array + */ + public function extend_upload_dirs_array( $upload_dirs ) { + return array_merge( $upload_dirs, [ + 'subdir' => $subdir = self::SCREENSHOT_DIR, + 'path' => "{$upload_dirs['basedir']}/{$subdir}", + 'url' => "{$upload_dirs['baseurl']}/{$subdir}", + ] ); + } + + /** + * Get wp_upload_bits result. + * + * This method will be throw an exception if was called before actually upload a screenshot. + * + * @return array + * @throws \Exception + */ + protected function get_upload_bits() { + if ( ! $this->upload_bits ) { + throw new \Exception( 'File was not uploaded yet.' ); + } + + return $this->upload_bits; + } + + /** + * Get the url of the screenshot. + * + * @return string + * @throws \Exception + */ + public function get_screenshot_url() { + return $this->get_upload_bits()['url']; + } +} diff --git a/modules/scroll-snap/module.php b/modules/scroll-snap/module.php new file mode 100644 index 00000000..8bb870d8 --- /dev/null +++ b/modules/scroll-snap/module.php @@ -0,0 +1,133 @@ +add_actions(); + } + + public function get_name() { + return 'scroll-snap'; + } + + public function register_controls( Controls_Stack $controls_stack, $section_id ) { + + if ( ( ! $controls_stack instanceof Theme_Page_Document && ! $controls_stack instanceof PageBase ) || 'section_custom_css_pro' !== $section_id ) { + return; + } + + $scroll_snap_children = '.elementor-section:not(.elementor-inner-section), .elementor-location-header, .elementor-location-footer, .page-header, .site-header, .elementor-add-section, .e-con:not(.e-child)'; + + $controls_stack->start_controls_section( + 'section_scroll_snap', + [ + 'label' => esc_html__( 'Scroll Snap', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_ADVANCED, + ] + ); + + $controls_stack->add_control( + 'scroll_snap', + [ + 'label' => esc_html__( 'Scroll Snap', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'description' => sprintf( esc_html__( 'Scroll Snap makes the viewport stop on a specific position of a section when scrolling ends.%sTo avoid glitches and conflicts, we recommend not to use Scroll Snap together with animations or Motion effects.', 'elementor-pro' ), '

      ' ), + 'selectors' => [ + 'html' => 'height: 100vh; margin: 0; overflow: hidden;', + 'body' => 'height: 100vh; overflow: auto; scroll-snap-type: y mandatory;', + ], + 'frontend_available' => true, + ] + ); + + $controls_stack->add_responsive_control( + 'scroll_snap_position', + [ + 'label' => esc_html__( 'Snap Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Top', 'elementor-pro' ), + 'center' => esc_html__( 'Center', 'elementor-pro' ), + 'end' => esc_html__( 'Bottom', 'elementor-pro' ), + ], + 'selectors_dictionary' => [ + '' => 'start', + ], + 'condition' => [ + 'scroll_snap!' => '', + ], + 'selectors' => [ + $scroll_snap_children => 'scroll-snap-align: {{VALUE}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + 'scroll_snap_padding', + [ + 'label' => esc_html__( 'Scroll Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'condition' => [ + 'scroll_snap!' => '', + ], + 'selectors' => [ + 'body' => 'scroll-padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $controls_stack->add_responsive_control( + 'force_stop', + [ + 'label' => esc_html__( 'Scroll Snap Stop', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'always' => esc_html__( 'Always', 'elementor-pro' ), + ], + 'selectors_dictionary' => [ + '' => 'normal', + ], + 'condition' => [ + 'scroll_snap!' => '', + ], + 'selectors' => [ + $scroll_snap_children => 'scroll-snap-stop: {{VALUE}}', + ], + ] + ); + + $controls_stack->end_controls_section(); + } + + private function add_actions() { + add_action( 'elementor/element/after_section_end', [ $this, 'register_controls' ], 10, 2 ); + } +} diff --git a/modules/search/data/controller.php b/modules/search/data/controller.php new file mode 100644 index 00000000..02cabf25 --- /dev/null +++ b/modules/search/data/controller.php @@ -0,0 +1,19 @@ +register_endpoint( Endpoints\Refresh_Search::class ); + } +} diff --git a/modules/search/data/endpoints/refresh-search.php b/modules/search/data/endpoints/refresh-search.php new file mode 100644 index 00000000..1c234089 --- /dev/null +++ b/modules/search/data/endpoints/refresh-search.php @@ -0,0 +1,102 @@ +get_params(); + + /** @var Module $search_module */ + $search_module = Plugin::instance()->modules_manager->get_modules( 'search' ); + + if ( $this->is_edit_mode( $data['post_id'] ) ) { + $widget_instance = Plugin::elementor()->elements_manager->create_element_instance( $data['widget_model'] ); + } else { + $widget_instance = $this->create_widget_instance_from_db( $data['post_id'], $data['widget_id'] ); + } + + ob_start(); + + /** @var Widget_Base $widget_instance */ + $widget_instance->set_search_term( $data['search_term'] ); + $widget_instance->set_page_number( $data['page_number'] ?? 1 ); + $widget_instance->render_results(); + + $markup = ob_get_clean(); + + $widget_instance->set_search_term( '' ); + + ob_start(); + + $widget_instance->render_pagination(); + + $pagination = ob_get_clean(); + + return [ + 'data' => $markup, + 'pagination' => $pagination, + ]; + } + + protected function register() { + register_rest_route( $this->controller->get_namespace(), $this->get_route(), [ + [ + 'args' => [ + 'post_id' => [ + 'description' => 'The post ID of the page containing the loop.', + 'type' => 'integer', + 'required' => true, + 'validate_callback' => function ( $param ) { + return ! empty( $param ) && is_numeric( $param ); + }, + ], + 'widget_id' => [ + 'description' => 'The ID of the loop widget.', + 'type' => 'string', + 'required' => true, + 'validate_callback' => function ( $param ) { + return $this->is_widget_id_valid( $param ); + }, + ], + 'widget_model' => [ + 'description' => 'The model of the loop widget. In Editor mode only.', + 'type' => 'object', + 'required' => false, + 'validate_callback' => function ( $param, $request ) { + $params = $request->get_params(); + + if ( ! $this->is_edit_mode( $params['post_id'] ) ) { + return false; + } + + return $this->is_widget_model_valid( $param ); + }, + ], + ], + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_updated_search_widget_markup' ], + 'permission_callback' => function ( $request ) { + return $this->permission_callback( $request, Search_Module::FEATURE_ID ); + }, + ], + ] ); + } +} diff --git a/modules/search/module.php b/modules/search/module.php new file mode 100644 index 00000000..161923fe --- /dev/null +++ b/modules/search/module.php @@ -0,0 +1,103 @@ +get_css_assets_url( 'widget-search', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + public function add_localize_data( $config ) { + + $config['eSearch'] = [ + 'nonce' => wp_create_nonce( 'wp_rest' ), + ]; + + return $config; + } + + public function set_query( $query ) { + $e_search_props = Utils::get_super_global_value( $_GET, 'e_search_props' ); + $search_term = Utils::get_super_global_value( $_GET, 's' ); + + if ( empty( $e_search_props ) || ! isset( $search_term ) || is_admin() || ! $query->is_main_query() ) { + return; + } + + $formatted_query_vars = $this->get_query_based_on_widget_props( $e_search_props ); + + if ( ! $formatted_query_vars ) { + return; + } + + foreach ( $formatted_query_vars as $key => $value ) { + $query->set( $key, $value ); + } + } + + private function get_query_based_on_widget_props( $e_search_props ) { + list( $widget_id, $post_id ) = explode( '-', $e_search_props ); + $widget_instance = Pro_Utils::create_widget_instance_from_db( $post_id, $widget_id ); + + if ( ! $widget_instance ) { + return null; + } + + $query_vars = ( new Elementor_Post_Query( $widget_instance, 'search_query' ) )->get_query_args(); + $query_vars['posts_per_page'] = -1; + + return $query_vars; + } +} diff --git a/modules/search/widgets/search.php b/modules/search/widgets/search.php new file mode 100644 index 00000000..10b36ae1 --- /dev/null +++ b/modules/search/widgets/search.php @@ -0,0 +1,2214 @@ + 'search_wrapper', + 'form' => 'form', + 'label' => 'label', + 'label_text' => 'label_text', + 'input' => 'input', + 'input_wrapper' => 'input_wrapper', + 'submit_button' => 'submit_button', + 'submit_text' => 'submit_text', + 'results_wrapper' => 'results_wrapper', + 'widget_props' => 'widget_props', + 'pagination' => 'pagination', + 'nav' => 'nav', + ]; + + public function set_search_term( string $search_term ) { + $this->search_term = $search_term; + } + + public function set_page_number( int $page_number ) { + $this->page_number = $page_number; + } + + public function get_name() { + return 'search'; + } + + public function get_title() { + return esc_html__( 'Search', 'elementor-pro' ); + } + + public function get_icon() { + return 'eicon-site-search'; + } + + public function get_keywords() { + return [ 'search' ]; + } + + public function get_categories() { + return [ 'pro-elements' ]; + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-search' ]; + } + + public function get_query() { + if ( null === $this->query ) { + $this->query_posts(); + } + + return $this->query; + } + + public function get_query_args() { + /** @var Module_Query $elementor_query */ + $elementor_query = Module_Query::instance(); + $settings = $this->get_settings_for_display(); + $query_args = [ + 'posts_per_page' => $settings['number_of_items'] ?? -1, + 'paged' => $this->page_number, + ]; + + if ( ! empty( $this->search_term ) ) { + $query_args['s'] = $this->search_term; + } + + return $elementor_query->get_query( $this, $this->get_property_key_prefix(), $query_args, [] ); + } + + protected function register_controls() { + $this->register_content_tab(); + $this->register_style_tab(); + } + + protected function register_content_tab() { + $this->register_content_section_search_field(); + $this->register_content_section_results(); + $this->register_content_section_query(); + $this->register_content_section_additional_settings(); + } + + protected function register_content_section_search_field() { + $this->start_controls_section( + 'content_section_search_field', + [ + 'label' => esc_html__( 'Search Field', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_input', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Input', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'search_input_placeholder_text', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'label_block' => true, + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Type to start searching...', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'icon_search', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + ] + ); + + $this->add_control( + 'autocomplete', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Autocomplete', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'separator' => 'before', + 'return_value' => 'yes', + ] + ); + + $this->add_control( + 'heading_clear', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Clear', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'icon_clear', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'skin_settings' => [ + 'inline' => [ + 'icon' => [ + 'icon' => 'eicon-close', + ], + ], + ], + 'label_block' => false, + 'default' => [ + 'value' => 'fas fa-times', + 'library' => 'fa-solid', + ], + ] + ); + + $this->add_control( + 'heading_submit', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Submit', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'submit_trigger', + [ + 'label' => esc_html__( 'Trigger', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'click_submit' => esc_html__( 'Submit button', 'elementor-pro' ), + 'key_enter' => esc_html__( 'Enter key', 'elementor-pro' ), + 'both' => esc_html__( 'Both', 'elementor-pro' ), + ], + 'default' => 'click_submit', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'submit_button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Search', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Search', 'elementor-pro' ), + 'condition' => [ + 'submit_trigger!' => 'key_enter', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'icon_submit', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'submit_trigger!' => 'key_enter', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_content_section_results() { + $this->start_controls_section( + 'content_section_results', + [ + 'label' => esc_html__( 'Results', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'live_results', + [ + 'label' => esc_html__( 'Live Results', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => '', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'template_id', + [ + 'label' => esc_html__( 'Choose a template', 'elementor-pro' ), + 'type' => Template_Query::CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'post_status' => Document::STATUS_PUBLISH, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => LoopDocument::get_type(), + 'compare' => 'IN', + ], + ], + ], + ], + 'actions' => [ + 'new' => [ + 'visible' => true, + 'document_config' => [ + 'type' => LoopDocument::get_type(), + ], + 'after_action' => 'redirect', + ], + 'edit' => [ + 'visible' => true, + 'after_action' => 'redirect', + ], + ], + 'condition' => [ + 'live_results' => 'yes', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'minimum_search_characters', + [ + 'label' => esc_html__( 'Minimum search characters', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 3, + 'min' => 1, + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_responsive_control( + 'number_of_columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 1, + 'min' => 1, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-columns: {{VALUE}}', + ], + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'number_of_items', + [ + 'label' => esc_html__( 'Items', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + 'min' => 1, + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + ] + ); + + $this->add_control( + 'equal_height', + [ + 'label' => esc_html__( 'Equal Height', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'default' => '', + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-grid-auto-rows: 1fr; --e-search-loop-item-equal-height: 100%', + ], + ] + ); + + $this->add_control( + 'enable_loader', + [ + 'label' => esc_html__( 'Loader', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'enable_nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'nothing_found_message_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'This appears when the search yields no results.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => $this->get_nothing_found_conditions(), + ] + ); + + $this->add_control( + 'nothing_found_message_text', + [ + 'type' => Controls_Manager::TEXTAREA, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => $this->get_nothing_found_conditions(), + 'default' => esc_html__( 'It seems we can’t find what you’re looking for.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'nothing_found_message_html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'div', + 'condition' => $this->get_nothing_found_conditions(), + ] + ); + + $this->end_controls_section(); + } + + protected function register_content_section_query() { + $this->start_controls_section( + 'content_section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Query::get_type(), + [ + 'name' => 'search_query', + 'presets' => [ 'full' ], + 'fields_options' => [ + 'post_type' => [ + 'default' => 'any', + 'options' => $this->get_supported_post_types(), + ], + 'exclude' => [ + 'options' => [ + 'terms' => esc_html__( 'Term', 'elementor-pro' ), + 'authors' => esc_html__( 'Author', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + ], + ], + 'exclude' => [ + 'avoid_duplicates', + 'offset', + 'posts_per_page', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_content_section_additional_settings() { + $this->start_controls_section( + 'content_section_additional_settings', + [ + 'label' => esc_html__( 'Additional Settings', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_pagination', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_type_options', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'numbers' => esc_html__( 'Numbers', 'elementor-pro' ), + 'previous_next' => esc_html__( 'Previous/Next', 'elementor-pro' ), + 'numbers_previous_next' => esc_html__( 'Numbers + Previous/Next', 'elementor-pro' ), + ], + 'default' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pagination_prev_label', + [ + 'label' => esc_html__( 'Previous Label', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Previous', 'elementor-pro' ), + 'condition' => [ + 'pagination_type_options' => [ + 'previous_next', + 'numbers_previous_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_next_label', + [ + 'label' => esc_html__( 'Next Label', 'elementor-pro' ), + 'default' => esc_html__( 'Next', 'elementor-pro' ), + 'condition' => [ + 'pagination_type_options' => [ + 'previous_next', + 'numbers_previous_next', + ], + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'page_limit_settings', + [ + 'label' => esc_html__( 'Page Limit', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5, + 'frontend_available' => true, + 'condition' => [ + 'pagination_type_options' => [ + 'numbers_previous_next', + 'numbers', + 'previous_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_shorten_settings', + [ + 'type' => Controls_Manager::SWITCHER, + 'label' => esc_html__( 'Shorten', 'elementor-pro' ), + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'condition' => [ + 'pagination_type_options' => [ + 'numbers_previous_next', + 'numbers', + ], + ], + ] + ); + + $this->end_controls_section(); + } + protected function get_nothing_found_conditions() { + return [ + 'enable_nothing_found_message' => 'yes', + 'live_results' => 'yes', + 'template_id!' => '', + ]; + } + + protected function register_style_tab() { + $this->register_style_section_search_field(); + $this->register_style_section_clear(); + $this->register_style_section_submit(); + $this->register_style_section_results(); + $this->register_style_section_additional_settings(); + $this->register_style_section_nothing_found_message(); + } + + protected function register_style_section_search_field() { + $this->start_controls_section( + 'section_search_field_style', + [ + 'label' => esc_html__( 'Search Field', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'search_field_typography', + 'selector' => '{{WRAPPER}} .e-search-input', + ] + ); + + $this->add_control( + 'placeholder_color', + [ + 'label' => esc_html__( 'Placeholder Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-placeholder-color: {{VALUE}};', + ], + ] + ); + + $this->start_controls_tabs( 'search_field_tabs' ); + + $this->start_controls_tab( + 'search_field_tab_input_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->register_search_field_style_tabs( 'normal' ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'search_field_tab_input_focus', + [ + 'label' => esc_html__( 'Focus', 'elementor-pro' ), + ] + ); + + $this->register_search_field_style_tabs( 'focus' ); + + $this->add_control( + 'search_field_search_input_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-input-transition: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'search_field_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-search-input' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'search_field_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-input-padding-block-start: {{TOP}}{{UNIT}}; --e-search-input-padding-inline-start: {{LEFT}}{{UNIT}}; --e-search-input-padding-block-end: {{BOTTOM}}{{UNIT}}; --e-search-input-padding-inline-end: {{RIGHT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'search_field_icon_label_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-icon-label-size: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + 'condition' => [ + 'icon_search[value]!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'search_field_icon_gap', + [ + 'label' => esc_html__( 'Gap between text and icon', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-input-gap: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'icon_search[value]!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'search_field_submit_gap', + [ + 'label' => esc_html__( 'Gap between input and button', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-submit-margin-inline-start: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_search_field_style_tabs( $tab_id ) { + $is_normal = 'normal' === $tab_id; + $selector_suffix = $is_normal ? '' : '.e-focus'; + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => "search_field_background_$tab_id", + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{{WRAPPER}}$selector_suffix .e-search-input", + 'fields_options' => [ + 'color' => [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + ], + ], + ] + ); + + $this->add_control( + "search_field_input_text_color_$tab_id", + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + "{{WRAPPER}}$selector_suffix" => '--e-search-input-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + "search_field_icon_search_normal_color_$tab_id", + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + "{{WRAPPER}}$selector_suffix" => '--e-search-icon-label-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => "search_field_border_$tab_id", + 'selector' => "{{WRAPPER}}$selector_suffix .e-search-input", + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => "search_field_box_shadow__$tab_id", + 'selector' => "{{WRAPPER}}$selector_suffix .e-search-input", + ] + ); + } + + protected function register_style_section_clear() { + $this->start_controls_section( + 'style_section_clear', + [ + 'label' => esc_html__( 'Clear', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'icon_clear[value]!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'icon_clear_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-icon-clear-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->start_controls_tabs( + 'icon_clear_color_tabs', + ); + + $this->start_controls_tab( + 'icon_clear_normal_tab', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'icon_clear_normal_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-icon-clear-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'icon_clear_hover_tab', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'icon_clear_hover_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-search-input-wrapper > svg:hover' => '--e-search-icon-clear-color: {{VALUE}};', + '{{WRAPPER}} .e-search-input-wrapper > i:hover' => '--e-search-icon-clear-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'icon_clear_hover_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-icon-clear-transition: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function register_style_section_additional_settings() { + $this->start_controls_section( + 'style_additional_settings', + [ + 'label' => esc_html__( 'Additional Settings', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'pagination_type_options' => [ + 'numbers_previous_next', + 'previous_next', + 'numbers', + ], + ], + ] + ); + + $this->add_control( + 'heading_style_additional_settings', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'style_additional_settings_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'toggle' => true, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-justify-content: {{VALUE}};', + ], + + ] + ); + + $this->add_control( + 'style_additional_settings_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'top' => '--e-search-pagination-vertical-position: column-reverse', + 'bottom' => '--e-search-pagination-vertical-position: column', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography_title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-pagination', + ] + ); + + $this->add_control( + 'heading_style_additional_settings_colors', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Colors', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( + 'style_additional_settings_color_tabs', + ); + + $this->start_controls_tab( + 'style_additional_settings_normal_tab', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'style_additional_settings_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'style_additional_settings_hover_tab', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'style_additional_settings_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-hover: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'style_button_color_tabs_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'style_button_color_icon_active', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-current: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'page_numbers_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-page-numbers-gap: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'top_spacing', + [ + 'label' => esc_html__( 'Top Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-block-start-spacing: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'bottom_spacing', + [ + 'label' => esc_html__( 'Bottom Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-pagination-block-end-spacing: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_style_section_submit() { + $this->start_controls_section( + 'style_section_submit', + [ + 'label' => esc_html__( 'Submit Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'submit_trigger!' => 'key_enter', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'submit_typography', + 'selector' => '{{WRAPPER}} .e-search-submit span', + ] + ); + + $this->add_responsive_control( + 'icon_submit_position', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start (before)', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'end' => [ + 'title' => esc_html__( 'End (after)', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'icon_submit[value]!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--e-search-submit-button-flex-direction: row; --e-search-submit-icon-margin-inline-start: 0px; --e-search-submit-icon-margin-inline-end: var(--e-search-submit-icon-gap);', + 'end' => '--e-search-submit-button-flex-direction: row-reverse; --e-search-submit-icon-margin-inline-start: var(--e-search-submit-icon-gap); --e-search-submit-icon-margin-inline-end: 0px;', + ], + ] + ); + + $this->add_responsive_control( + 'icon_submit_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'condition' => [ + 'icon_submit[value]!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-icon-submit-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'icon_submit_gap', + [ + 'label' => esc_html__( 'Gap between text and icon', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'condition' => [ + 'icon_submit[value]!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-submit-icon-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->start_controls_tabs( + 'submit_style_tabs', + ); + + $this->start_controls_tab( + 'submit_style_normal_tab', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->register_submit_style_tabs( 'normal' ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'submit_style_hover_tab', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->register_submit_style_tabs( 'hover' ); + + $this->add_control( + 'submit_hover_animation', + [ + 'label' => esc_html__( 'Hover animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->add_control( + 'submit_hover_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + ], + 'range' => [ + 's' => [ + 'max' => 5, + ], + 'ms' => [ + 'max' => 5000, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-submit-hover-transition: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'submit_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-submit-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'submit_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-submit-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + } + + /** + * Registers the controls of the submit section style for normal/hover state tabs. + * + * @param string $tab_id Accepts 'normal' or 'hover' as value. + */ + protected function register_submit_style_tabs( $tab_id ) { + $is_normal = 'normal' === $tab_id; + $state_suffix = $is_normal ? '' : ":$tab_id"; + $selector_suffix = $is_normal ? '' : " .e-search-submit$state_suffix"; + + $this->add_control( + "submit_text_color_$tab_id", + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + "{{WRAPPER}}$selector_suffix" => '--e-search-submit-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + "submit_icon_color_$tab_id", + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + 'icon_submit[value]!' => '', + ], + 'selectors' => [ + "{{WRAPPER}}$selector_suffix" => '--e-search-icon-submit-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => "submit_background_$tab_id", + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => "{{WRAPPER}} .e-search-submit$state_suffix", + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => "submit_border_$tab_id", + 'selector' => "{{WRAPPER}} .e-search-submit$state_suffix", + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => "submit_box_shadow_$tab_id", + 'selector' => "{{WRAPPER}} .e-search-submit$state_suffix", + ] + ); + } + + protected function register_style_section_results() { + $this->start_controls_section( + 'style_section_results', + [ + 'label' => esc_html__( 'Results', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'live_results' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'results_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .e-search-results-container', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'results_border_type', + 'selector' => '{{WRAPPER}} .e-search-results-container > div', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'results_box_shadow', + 'selector' => '{{WRAPPER}} .e-search-results-container > div', + ] + ); + + $this->add_responsive_control( + 'results_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'results_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'results_distance_from_search_field', + [ + 'label' => esc_html__( 'Distance from search field', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + 'vw' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-input-and-results-gap: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'results_is_dropdown_width', + [ + 'label' => esc_html__( 'Dropdown Width', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'search_field' => esc_html__( 'Search Field', 'elementor-pro' ), + 'widget_width' => esc_html__( 'Widget Width', 'elementor-pro' ), + ], + 'default' => 'search_field', + 'separator' => 'before', + 'frontend_available' => true, + ], + ); + + $this->add_control( + 'results_is_custom_width', + [ + 'label' => esc_html__( 'Custom Width', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'On', 'elementor-pro' ), + 'label_on' => esc_html__( 'Off', 'elementor-pro' ), + 'default' => '', + ] + ); + + $this->add_responsive_control( + 'results_custom_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'results_is_custom_width' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'results_max_height', + [ + 'label' => esc_html__( 'Max height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 500, + ], + '%' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 50, + ], + 'rem' => [ + 'max' => 50, + ], + 'vw' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-max-height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'results_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'toggle' => true, + 'condition' => [ + 'results_is_custom_width' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--e-search-results-inset-inline-start: 0; --e-search-results-inset-inline-end: initial; --e-search-results-transform: initial;', + 'center' => '--e-search-results-inset-inline-start: 50%; --e-search-results-inset-inline-end: initial; --e-search-results-transform: translateX(-50%);', + 'end' => '--e-search-results-inset-inline-start: initial; --e-search-results-inset-inline-end: 0; --e-search-results-transform: initial;', + ], + ] + ); + + $this->add_responsive_control( + 'search_result_column_gap', + [ + 'label' => esc_html__( 'Gap between columns', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-column-gap: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'search_result_row_gap', + [ + 'label' => esc_html__( 'Gap between rows', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-results-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_search_reasult_loader', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Loader', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + 'enable_loader' => 'yes', + ], + ] + ); + + $this->add_control( + 'search_result_loader_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + 'enable_loader' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-loader-icon-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'search_result_loader_icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'condition' => [ + 'live_results' => 'yes', + 'template_id!' => '', + 'enable_loader' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-loader-icon-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_style_section_nothing_found_message() { + $this->start_controls_section( + 'style_section_nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => $this->get_nothing_found_conditions(), + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_space_from_top', + [ + 'label' => esc_html__( 'Space from top', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-nothing-found-padding-block-start: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_space_from_bottom', + [ + 'label' => esc_html__( 'Space from bottom', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-nothing-found-padding-block-end: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'nothing_found_message_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-nothing-found-message-alignment: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'nothing_found_message_typography', + 'selector' => '{{WRAPPER}} .e-search-nothing-found-message', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'nothing_found_message_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-search-nothing-found-message-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'nothing_found_message_text_shadow', + 'selector' => '{{WRAPPER}} .e-search-nothing-found-message', + ] + ); + + $this->add_group_control( + Group_Control_Text_Stroke::get_type(), + [ + 'name' => 'nothing_found_message_text_stroke', + 'selector' => '{{WRAPPER}} .e-search-nothing-found-message', + ] + ); + + $this->end_controls_section(); + } + + public function render_results() { + $this->query_posts(); + + /** @var \WP_Query $query */ + $query = $this->get_query(); + + if ( ! $query->found_posts ) { + $this->handle_no_posts_found(); + return; + } + + while ( $query->have_posts() ) { + $query->the_post(); + + $this->render_post(); + } + + wp_reset_postdata(); + } + + public function render_pagination() { + $parent_settings = $this->get_settings_for_display(); + $pagination_types = $parent_settings['pagination_type_options']; + $this->add_render_attibutes_pagination(); + + if ( 'none' === $pagination_types ) { + return; + } + + if ( 1 >= $this->get_query()->max_num_pages ) { + return; + } + + $total = $parent_settings['page_limit_settings'] > $this->get_query()->max_num_pages ? $this->get_query()->max_num_pages : $parent_settings['page_limit_settings']; + + $paginate_args = [ + 'type' => 'array', + 'current' => $this->page_number, + 'total' => $total, + 'prev_next' => 'numbers' !== $pagination_types, + 'next_text' => $parent_settings['pagination_next_label'], + 'prev_text' => $parent_settings['pagination_prev_label'], + 'show_all' => 'yes' !== $parent_settings['pagination_shorten_settings'], + 'before_page_number' => '' . esc_html__( 'Page', 'elementor-pro' ) . '', + ]; + + $paginate_args = $this->get_paginate_args_for_rest_request( $paginate_args ); + + $links = []; + $links = paginate_links( $paginate_args ); + + if ( 1 === $this->page_number && 'numbers' !== $pagination_types ) { + $prev = '' . $parent_settings['pagination_prev_label'] . ''; + array_unshift( $links, $prev ); + } + + if ( $this->page_number === $total && 'numbers' !== $pagination_types ) { + $next = '' . $parent_settings['pagination_next_label'] . ''; + $links[] = $next; + } + + $links = $this->add_nofollow_to_links( $links ); + + echo implode( PHP_EOL, $links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + } + + protected function add_nofollow_to_links( $content ) { + $content = str_replace( 'get_settings_for_display(); + + if ( 'yes' !== $settings['enable_nothing_found_message'] ) { + return; + } + $nothing_found_message_html_tag = Utils::validate_html_tag( $settings['nothing_found_message_html_tag'] ); + ?> + < class="e-search-nothing-found-message"> + + > + get_settings_for_display(); + $template_id = $settings['template_id'] ?? 0; + $post_id = get_the_ID(); + + /** @var LoopDocument $document */ + $document = Plugin::elementor()->documents->get( $template_id ); + + if ( ! $document ) { + return; + } + + $this->print_dynamic_css( $post_id, $template_id ); + $document->print_content(); + } + + protected function render_loader( $settings ) { + if ( isset( $settings['enable_loader'] ) && 'yes' === $settings['enable_loader'] ) { + ?> +
      + + + +
      + get_settings_for_display(); + $attribute_ids = $this->element_attribute_ids; + $this->add_render_attibutes(); + ?> + print_render_attribute_string( $attribute_ids['search_wrapper'] ); ?>> +
      print_render_attribute_string( $attribute_ids['form'] ); ?>> + + + + + +
      print_render_attribute_string( $attribute_ids['input_wrapper'] ); ?>> + print_render_attribute_string( $attribute_ids['input'] ); ?>> + maybe_render_icon( 'icon_clear' ); ?> + get_dropdown_width() ) : ?> + print_render_attribute_string( $attribute_ids['results_wrapper'] ); ?>> +
      + render_loader( $settings ); ?> +
      + +
      + get_dropdown_width() ) : ?> + print_render_attribute_string( $attribute_ids['results_wrapper'] ); ?>> +
      + render_loader( $settings ); ?> +
      + + + + + + print_render_attribute_string( $attribute_ids['widget_props'] ); ?>> +
      +
      + query = $this->get_query_args(); + } + + public function get_query_name() { + return $this->get_name(); + } + + private function add_render_attibutes_pagination() { + $pagination_class = 'elementor-pagination'; + + $this->add_render_attribute( $this->element_attribute_ids['nav'], [ + 'class' => $pagination_class, + ] ); + } + + private function add_render_attibutes() { + $id = $this->get_id(); + $settings = $this->get_settings_for_display(); + $screen_only_class = 'elementor-screen-only'; + + $this->add_render_attribute( $this->element_attribute_ids['search_wrapper'], [ + 'class' => [ 'e-search', 'hidden' ], + 'role' => 'search', + ] ); + + if ( 'previous_next' === $settings['pagination_type_options'] ) { + $this->add_render_attribute( $this->element_attribute_ids['results_wrapper'], [ + 'class' => 'hide-pagination-numbers', + ] ); + } + + $this->add_render_attribute( $this->element_attribute_ids['form'], [ + 'class' => 'e-search-form', + 'action' => esc_url( home_url() ), + 'method' => 'get', + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['label'], [ + 'class' => 'e-search-label', + 'for' => "search-$id", + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['label_text'], [ + 'class' => $screen_only_class, + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['input_wrapper'], [ + 'class' => 'e-search-input-wrapper', + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['input'], [ + 'id' => "search-$id", + 'placeholder' => esc_attr( $settings['search_input_placeholder_text'] ), + 'class' => 'e-search-input', + 'type' => 'search', + 'name' => 's', + 'value' => '', + 'autocomplete' => $this->get_autocomplete_state(), + 'role' => 'combobox', + 'aria-autocomplete' => 'list', + 'aria-expanded' => 'false', + 'aria-controls' => "results-$id", + 'aria-haspopup' => 'listbox', + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['submit_button'], [ + 'class' => [ + 'e-search-submit', + $this->is_submit_button_shown() ? '' : $screen_only_class, + $settings['submit_hover_animation'] ? 'elementor-animation-' . $settings['submit_hover_animation'] : '', + ], + 'type' => 'submit', + ] ); + + if ( empty( $settings['submit_button_text'] ) ) { + $this->add_render_attribute( $this->element_attribute_ids['submit_button'], 'aria-label', esc_html__( 'Search', 'elementor-pro' ) ); + } + + $this->add_render_attribute( $this->element_attribute_ids['submit_text'], [ + 'class' => $this->is_submit_button_shown() ? '' : $screen_only_class, + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['results_wrapper'], [ + 'id' => "results-$id", + 'class' => 'e-search-results-container hide-loader', + 'aria-live' => 'polite', + 'aria-atomic' => 'true', + 'aria-label' => esc_attr__( 'Results for search', 'elementor-pro' ), + 'tabindex' => '0', + ] ); + + $this->add_render_attribute( $this->element_attribute_ids['widget_props'], [ + 'type' => 'hidden', + 'name' => 'e_search_props', + 'value' => $this->get_id() . '-' . Pro_Utils::get_current_post_id(), + ] ); + } + + private function is_submit_button_shown() { + return 'key_enter' !== $this->get_settings_for_display( 'submit_trigger' ); + } + + private function get_autocomplete_state() { + return 'yes' !== $this->get_settings_for_display( 'autocomplete' ) ? 'off' : 'on'; + } + + private function get_dropdown_width() { + return 'widget_width' === $this->get_settings_for_display( 'results_is_dropdown_width' ); + } + + private function maybe_render_icon( $target ) { + $icon_settings = $this->get_settings_for_display( $target ) ?? [ + 'library' => '', + 'value' => '', + ]; + + Icons_Manager::render_icon( + $icon_settings ?? [ '', '' ], + [ 'aria-hidden' => 'true' ], + 'i' + ); + } + + private function get_supported_post_types() { + $supported_post_types = [ + 'any' => esc_html__( 'All', 'elementor-pro' ), + 'product' => esc_html__( 'Products', 'elementor-pro' ), + 'post' => esc_html__( 'Posts', 'elementor-pro' ), + 'page' => esc_html__( 'Pages', 'elementor-pro' ), + ]; + + $cpts = $this->get_supported_cpts(); + + return array_merge( $supported_post_types, $cpts ); + } + + private function get_supported_cpts() { + $cpts = new Collection( get_post_types( + [ + 'public' => true, + '_builtin' => false, + ], + 'objects' + ) ); + + return $cpts->except( [ 'product', 'related_products', 'elementor_library' ] ) + ->map_with_keys( function ( $item, $post_type ) { + return [ $post_type => $item->label ?? null ]; + } ) + ->filter() + ->all(); + } + + private function get_property_key_prefix() { + return $this->get_query_name() . '_query'; + } +} diff --git a/modules/share-buttons/module.php b/modules/share-buttons/module.php new file mode 100644 index 00000000..840266a5 --- /dev/null +++ b/modules/share-buttons/module.php @@ -0,0 +1,143 @@ + [ + 'title' => 'Facebook', + 'has_counter' => true, + ], + 'twitter' => [ + 'title' => 'Twitter', + ], + 'linkedin' => [ + 'title' => 'LinkedIn', + 'has_counter' => true, + ], + 'pinterest' => [ + 'title' => 'Pinterest', + 'has_counter' => true, + ], + 'reddit' => [ + 'title' => 'Reddit', + 'has_counter' => true, + ], + 'vk' => [ + 'title' => 'VK', + 'has_counter' => true, + ], + 'odnoklassniki' => [ + 'title' => 'OK', + 'has_counter' => true, + ], + 'tumblr' => [ + 'title' => 'Tumblr', + ], + 'digg' => [ + 'title' => 'Digg', + ], + 'skype' => [ + 'title' => 'Skype', + ], + 'stumbleupon' => [ + 'title' => 'StumbleUpon', + 'has_counter' => true, + ], + 'mix' => [ + 'title' => 'Mix', + ], + 'telegram' => [ + 'title' => 'Telegram', + ], + 'pocket' => [ + 'title' => 'Pocket', + 'has_counter' => true, + ], + 'xing' => [ + 'title' => 'XING', + 'has_counter' => true, + ], + 'whatsapp' => [ + 'title' => 'WhatsApp', + ], + 'email' => [ + 'title' => 'Email', + ], + 'print' => [ + 'title' => 'Print', + ], + 'x-twitter' => [ + 'title' => 'X', + ], + 'threads' => [ + 'title' => 'Threads', + ], + ]; + + public static function get_networks( $network_name = null ) { + if ( $network_name ) { + return self::$networks[ $network_name ] ?? null; + } + + return self::$networks; + } + + public function get_widgets() { + return [ + 'Share_Buttons', + ]; + } + + public function get_name() { + return 'share-buttons'; + } + + public function add_localize_data( $settings ) { + $settings['shareButtonsNetworks'] = self::get_networks(); + + return $settings; + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/share-buttons/assets/scss/frontend.scss` + * to `/assets/css/widget-share-buttons.min.css`. + * + * @return void + */ + public function register_styles() { + wp_register_style( + 'widget-share-buttons', + $this->get_css_assets_url( 'widget-share-buttons', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + public function __construct() { + parent::__construct(); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + + add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'add_localize_data' ] ); + + add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_localize_data' ] ); + } +} diff --git a/modules/share-buttons/widgets/share-buttons.php b/modules/share-buttons/widgets/share-buttons.php new file mode 100644 index 00000000..7edc567b --- /dev/null +++ b/modules/share-buttons/widgets/share-buttons.php @@ -0,0 +1,726 @@ + [ + 'value' => 'fa fa-get-pocket', + ], + 'email' => [ + 'value' => 'fa fa-envelope', + ], + ]; + + private static $networks_icon_mapping = [ + 'pocket' => [ + 'value' => 'fab fa-get-pocket', + 'library' => 'fa-brands', + ], + 'email' => [ + 'value' => 'fas fa-envelope', + 'library' => 'fa-solid', + ], + 'print' => [ + 'value' => 'fas fa-print', + 'library' => 'fa-solid', + ], + ]; + + public function get_style_depends(): array { + $style_depends = [ 'widget-share-buttons', 'e-apple-webkit' ]; + + if ( Icons_Manager::is_migration_allowed() ) { + $style_depends[] = 'elementor-icons-fa-solid'; + $style_depends[] = 'elementor-icons-fa-brands'; + } + + return $style_depends; + } + + private static function get_network_icon_data( $network_name ) { + $prefix = 'fa '; + $library = ''; + + if ( Icons_Manager::is_migration_allowed() ) { + if ( isset( self::$networks_icon_mapping[ $network_name ] ) ) { + return self::$networks_icon_mapping[ $network_name ]; + } + $prefix = 'fab '; + $library = 'fa-brands'; + } + if ( isset( self::$networks_class_dictionary[ $network_name ] ) ) { + return self::$networks_class_dictionary[ $network_name ]; + } + + return [ + 'value' => $prefix . 'fa-' . $network_name, + 'library' => $library, + ]; + } + + public function get_name() { + return 'share-buttons'; + } + + public function get_title() { + return esc_html__( 'Share Buttons', 'elementor-pro' ); + } + + public function get_icon() { + return 'eicon-share'; + } + + public function get_keywords() { + return [ 'sharing', 'social', 'icon', 'button', 'like' ]; + } + + protected function is_dynamic_content(): bool { + return false; + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + $this->start_controls_section( + 'section_buttons_content', + [ + 'label' => esc_html__( 'Share Buttons', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $networks = Module::get_networks(); + + $networks_names = array_keys( $networks ); + + $repeater->add_control( + 'button', + [ + 'label' => esc_html__( 'Network', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => array_reduce( $networks_names, function( $options, $network_name ) use ( $networks ) { + $options[ $network_name ] = $networks[ $network_name ]['title']; + + return $options; + }, [] ), + 'default' => 'facebook', + ] + ); + + $repeater->add_control( + 'text', + [ + 'label' => esc_html__( 'Custom Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'share_buttons', + [ + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'button' => 'facebook', + ], + [ + 'button' => 'twitter', + ], + [ + 'button' => 'linkedin', + ], + ], + 'title_field' => ' {{{ elementorPro.modules.shareButtons.getNetworkTitle( obj ) }}}', + ] + ); + + $this->add_control( + 'view', + [ + 'label' => esc_html__( 'View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'icon-text' => esc_html__( 'Icon & Text', 'elementor-pro' ), + 'icon' => esc_html__( 'Icon', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + ], + 'default' => 'icon-text', + 'separator' => 'before', + 'prefix_class' => 'elementor-share-buttons--view-', + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'show_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'condition' => [ + 'view' => 'icon-text', + ], + ] + ); + + $this->add_control( + 'skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'gradient' => esc_html__( 'Gradient', 'elementor-pro' ), + 'minimal' => esc_html__( 'Minimal', 'elementor-pro' ), + 'framed' => esc_html__( 'Framed', 'elementor-pro' ), + 'boxed' => esc_html__( 'Boxed Icon', 'elementor-pro' ), + 'flat' => esc_html__( 'Flat', 'elementor-pro' ), + ], + 'default' => 'gradient', + 'prefix_class' => 'elementor-share-buttons--skin-', + ] + ); + + $this->add_control( + 'shape', + [ + 'label' => esc_html__( 'Shape', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'square' => esc_html__( 'Square', 'elementor-pro' ), + 'rounded' => esc_html__( 'Rounded', 'elementor-pro' ), + 'circle' => esc_html__( 'Circle', 'elementor-pro' ), + ], + 'default' => 'square', + 'prefix_class' => 'elementor-share-buttons--shape-', + ] + ); + + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '0', + 'options' => [ + '0' => esc_html__( 'Auto', 'elementor-pro' ), + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-grid%s-', + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'condition' => [ + 'columns' => '0', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--alignment: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'share_url_type', + [ + 'label' => esc_html__( 'Target URL', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'current_page' => esc_html__( 'Current Page', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'current_page', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'share_url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'options' => false, + 'condition' => [ + 'share_url_type' => 'custom', + ], + 'show_label' => false, + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_buttons_style', + [ + 'label' => esc_html__( 'Share Buttons', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-side-margin: {{SIZE}}{{UNIT}}; --grid-column-gap: {{SIZE}}{{UNIT}}; --grid-row-gap: {{SIZE}}{{UNIT}}', + '(tablet) {{WRAPPER}}' => '--grid-side-margin: {{SIZE}}{{UNIT}}; --grid-column-gap: {{SIZE}}{{UNIT}}', + '(mobile) {{WRAPPER}}' => '--grid-side-margin: {{SIZE}}{{UNIT}}; --grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}; --grid-bottom-margin: {{SIZE}}{{UNIT}}', + '(tablet) {{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}; --grid-bottom-margin: {{SIZE}}{{UNIT}}', + '(mobile) {{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}; --grid-bottom-margin: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'button_size', + [ + 'label' => esc_html__( 'Button Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0.5, + 'max' => 2, + 'step' => 0.05, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn' => 'font-size: calc({{SIZE}}{{UNIT}} * 10);', + ], + ] + ); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'default' => [ + 'unit' => 'em', + ], + 'tablet_default' => [ + 'unit' => 'em', + ], + 'mobile_default' => [ + 'unit' => 'em', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn__icon' => '--e-share-buttons-icon-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'view!' => 'text', + ], + ] + ); + + $this->add_responsive_control( + 'button_height', + [ + 'label' => esc_html__( 'Button Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'default' => [ + 'unit' => 'em', + ], + 'tablet_default' => [ + 'unit' => 'em', + ], + 'mobile_default' => [ + 'unit' => 'em', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'border_size', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'size' => 2, + ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn' => 'border-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'skin' => [ 'framed', 'boxed' ], + ], + ] + ); + + $this->add_control( + 'color_source', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'official' => esc_html__( 'Official', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'official', + 'prefix_class' => 'elementor-share-buttons--color-', + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( + 'tabs_button_style', + [ + 'condition' => [ + 'color_source' => 'custom', + ], + ] + ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'primary_color', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => '--e-share-buttons-primary-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'secondary_color', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--e-share-buttons-secondary-color: {{VALUE}}', + ], + 'separator' => 'after', + 'condition' => [ + 'skin!' => 'framed', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'primary_color_hover', + [ + 'label' => esc_html__( 'Primary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn:hover' => '--e-share-buttons-primary-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'secondary_color_hover', + [ + 'label' => esc_html__( 'Secondary Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-share-btn:hover' => '--e-share-buttons-secondary-color: {{VALUE}}', + ], + 'separator' => 'after', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'selector' => '{{WRAPPER}} .elementor-share-btn__title', + 'exclude' => [ 'line_height' ], + ] + ); + + $this->add_control( + 'text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} a.elementor-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + 'condition' => [ + 'view' => 'text', + ], + ] + ); + + $this->end_controls_section(); + + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['share_buttons'] ) ) { + return; + } + + $this->add_render_attribute( 'wrapper', 'class', 'elementor-grid' ); + $this->add_render_attribute( 'item_wrapper', 'class', 'elementor-grid-item' ); + + if ( count( $settings['share_buttons'] ) > 1 ) { + $this->add_render_attribute( 'wrapper', 'role', 'list' ); + $this->add_render_attribute( 'item_wrapper', 'role', 'listitem' ); + } + + $show_text = 'text' === $settings['view'] || 'yes' === $settings['show_label']; + ?> +
      print_render_attribute_string( 'wrapper' ); ?>> + $button ) { + $network_name = $button['button']; + + // A deprecated network. + if ( ! isset( $networks_data[ $network_name ] ) ) { + continue; + } + + $this->add_render_attribute( + 'item_link_' . $index, + [ + 'class' => [ 'elementor-share-btn', 'elementor-share-btn_' . $network_name ], + 'role' => 'button', + 'tabindex' => '0', + 'aria-label' => sprintf( esc_attr__( 'Share on %s', 'elementor-pro' ), esc_attr( $network_name ) ), + ] + ); + ?> +
      print_render_attribute_string( 'item_wrapper' ); ?>> +
      print_render_attribute_string( 'item_link_' . $index ); ?>> + + + + + + +
      + + + + + +
      + +
      +
      + +
      + + <# + view.addRenderAttribute( 'wrapper', 'class', 'elementor-grid' ); + view.addRenderAttribute( 'item_wrapper', 'class', 'elementor-grid-item' ); + + if ( settings.share_buttons.length > 1 ) { + view.addRenderAttribute( 'wrapper', 'role', 'list' ); + view.addRenderAttribute( 'item_wrapper', 'role', 'listitem' ); + } + + var shareButtonsEditorModule = elementorPro.modules.shareButtons; + + var showText = 'icon-text' === settings.view ? 'yes' === settings.show_label : 'text' === settings.view; + #> +
      + <# + _.each( settings.share_buttons, function( button, index ) { + // A deprecated network. + if ( ! shareButtonsEditorModule.getNetworkData( button ) ) { + return; + } + + var networkName = button.button; + + view.addRenderAttribute( + 'item_link_' + index, + { + 'class': [ 'elementor-share-btn', 'elementor-share-btn_' + networkName ], + 'role': 'button', + 'tabindex': '0', + 'aria-label': 'Share on ' + networkName, + } + ); + #> +
      +
      + <# if ( 'icon' === settings.view || 'icon-text' === settings.view ) { #> + + + + <# } #> + <# if ( showText ) { #> +
      + <# if ( 'yes' === settings.show_label || 'text' === settings.view ) { #> + {{{ shareButtonsEditorModule.getNetworkTitle( button ) }}} + <# } #> +
      + <# } #> +
      +
      + <# } ); #> +
      + experiments->is_feature_active( 'e_font_icon_svg' ) ) { + $icon = Icons_Manager::render_font_icon( $network_icon_data, [ 'aria-hidden' => 'true' ] ); + } else { + $icon = sprintf( '', esc_attr( $network_icon_data['value'] ) ); + } + + Utils::print_unescaped_internal_string( $icon ); + } +} diff --git a/modules/slides/controls/control-slides-animation.php b/modules/slides/controls/control-slides-animation.php new file mode 100644 index 00000000..21081191 --- /dev/null +++ b/modules/slides/controls/control-slides-animation.php @@ -0,0 +1,23 @@ + esc_html__( 'Down', 'elementor-pro' ), + 'fadeInUp' => esc_html__( 'Up', 'elementor-pro' ), + 'fadeInRight' => esc_html__( 'Right', 'elementor-pro' ), + 'fadeInLeft' => esc_html__( 'Left', 'elementor-pro' ), + 'zoomIn' => esc_html__( 'Zoom', 'elementor-pro' ), + ]; + } +} diff --git a/modules/slides/module.php b/modules/slides/module.php new file mode 100644 index 00000000..7fac55c2 --- /dev/null +++ b/modules/slides/module.php @@ -0,0 +1,63 @@ +register( new Control_Slides_Animation() ); + } ); + } + + public function get_name() { + return 'slides'; + } + + public function get_widgets() { + return [ + 'Slides', + ]; + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/slides/assets/scss/frontend.scss` + * to `/assets/css/widget-slides.min.css`. + * + * @return void + */ + public function register_styles() { + $direction_suffix = is_rtl() ? '-rtl' : ''; + $has_custom_breakpoints = Plugin::elementor()->breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-slides', + Plugin::get_frontend_file_url( "widget-slides{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/slides/widgets/slides.php b/modules/slides/widgets/slides.php new file mode 100644 index 00000000..907d03ae --- /dev/null +++ b/modules/slides/widgets/slides.php @@ -0,0 +1,1614 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'e-swiper', 'widget-slides' ]; + } + + public static function get_button_sizes() { + return [ + 'xs' => esc_html__( 'Extra Small', 'elementor-pro' ), + 'sm' => esc_html__( 'Small', 'elementor-pro' ), + 'md' => esc_html__( 'Medium', 'elementor-pro' ), + 'lg' => esc_html__( 'Large', 'elementor-pro' ), + 'xl' => esc_html__( 'Extra Large', 'elementor-pro' ), + ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'slides_name', + [ + 'label' => esc_html__( 'Slides Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Slides', 'elementor-pro' ), + ] + ); + + $repeater = new Repeater(); + + $repeater->start_controls_tabs( 'slides_repeater' ); + + $repeater->start_controls_tab( + 'background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'background_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#bbbbbb', + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-bg' => 'background-color: {{VALUE}}', + ], + ] + ); + + $repeater->add_control( + 'background_image', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-bg' => 'background-image: url({{URL}})', + ], + 'default' => [ + 'url' => '', + ], + ] + ); + + $repeater->add_control( + 'background_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'cover', + 'options' => [ + 'cover' => esc_html__( 'Cover', 'elementor-pro' ), + 'contain' => esc_html__( 'Contain', 'elementor-pro' ), + 'auto' => esc_html__( 'Auto', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-bg' => 'background-size: {{VALUE}}', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_image[url]', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'background_ken_burns', + [ + 'label' => esc_html__( 'Ken Burns Effect', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_image[url]', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'zoom_direction', + [ + 'label' => esc_html__( 'Zoom Direction', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'in', + 'options' => [ + 'in' => esc_html__( 'In', 'elementor-pro' ), + 'out' => esc_html__( 'Out', 'elementor-pro' ), + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_ken_burns', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'background_overlay', + [ + 'label' => esc_html__( 'Background Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_image[url]', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'background_overlay_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => 'rgba(0,0,0,0.5)', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_overlay', + 'value' => 'yes', + ], + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .elementor-background-overlay' => 'background-color: {{VALUE}}', + ], + ] + ); + + $repeater->add_control( + 'background_overlay_blend_mode', + [ + 'label' => esc_html__( 'Blend Mode', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Normal', 'elementor-pro' ), + 'multiply' => 'Multiply', + 'screen' => 'Screen', + 'overlay' => 'Overlay', + 'darken' => 'Darken', + 'lighten' => 'Lighten', + 'color-dodge' => 'Color Dodge', + 'color-burn' => 'Color Burn', + 'hue' => 'Hue', + 'saturation' => 'Saturation', + 'color' => 'Color', + 'exclusion' => 'Exclusion', + 'luminosity' => 'Luminosity', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'background_overlay', + 'value' => 'yes', + ], + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .elementor-background-overlay' => 'mix-blend-mode: {{VALUE}}', + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( + 'content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'heading', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Slide Heading', 'elementor-pro' ), + 'label_block' => true, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Button Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Click Here', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'link_click', + [ + 'label' => esc_html__( 'Apply Link On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'slide' => esc_html__( 'Whole Slide', 'elementor-pro' ), + 'button' => esc_html__( 'Button Only', 'elementor-pro' ), + ], + 'default' => 'slide', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'link[url]', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( + 'style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'custom_style', + [ + 'label' => esc_html__( 'Custom', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'description' => esc_html__( 'Set custom style that will only affect this specific slide.', 'elementor-pro' ), + ] + ); + + $repeater->add_control( + 'horizontal_position', + [ + 'label' => esc_html__( 'Horizontal Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-contents' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'left' => 'margin-right: auto', + 'center' => 'margin: 0 auto', + 'right' => 'margin-left: auto', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'custom_style', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-inner' => 'align-items: {{VALUE}}', + ], + 'selectors_dictionary' => [ + 'top' => 'flex-start', + 'middle' => 'center', + 'bottom' => 'flex-end', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'custom_style', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-inner' => 'text-align: {{VALUE}}', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'custom_style', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $repeater->add_control( + 'content_color', + [ + 'label' => esc_html__( 'Content Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-inner .elementor-slide-heading' => 'color: {{VALUE}}', + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-inner .elementor-slide-description' => 'color: {{VALUE}}', + '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-inner .elementor-slide-button' => 'color: {{VALUE}}; border-color: {{VALUE}}', + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'custom_style', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $repeater->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'repeater_text_shadow', + 'selector' => '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-contents', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'custom_style', + 'value' => 'yes', + ], + ], + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $this->add_control( + 'slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'show_label' => true, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'heading' => esc_html__( 'Slide 1 Heading', 'elementor-pro' ), + 'description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'button_text' => esc_html__( 'Click Here', 'elementor-pro' ), + 'background_color' => '#833ca3', + 'background_image' => [ + 'url' => '', + ], + ], + [ + 'heading' => esc_html__( 'Slide 2 Heading', 'elementor-pro' ), + 'description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'button_text' => esc_html__( 'Click Here', 'elementor-pro' ), + 'background_color' => '#4054b2', + 'background_image' => [ + 'url' => '', + ], + ], + [ + 'heading' => esc_html__( 'Slide 3 Heading', 'elementor-pro' ), + 'description' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'button_text' => esc_html__( 'Click Here', 'elementor-pro' ), + 'background_color' => '#1abc9c', + 'background_image' => [ + 'url' => '', + ], + ], + ], + 'title_field' => '{{{ heading }}}', + ] + ); + + $this->add_responsive_control( + 'slides_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 100, + 'max' => 1000, + ], + 'em' => [ + 'min' => 10, + 'max' => 100, + ], + 'rem' => [ + 'min' => 10, + 'max' => 100, + ], + 'vh' => [ + 'min' => 10, + 'max' => 100, + ], + ], + 'default' => [ + 'size' => 400, + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide' => 'height: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'slides_title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'div', + ] + ); + + $this->add_control( + 'slides_description_tag', + [ + 'label' => esc_html__( 'Description HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'div', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_slider_options', + [ + 'label' => esc_html__( 'Slider Options', 'elementor-pro' ), + 'type' => Controls_Manager::SECTION, + ] + ); + + $this->add_control( + 'navigation', + [ + 'label' => esc_html__( 'Navigation', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'both', + 'options' => [ + 'both' => esc_html__( 'Arrows and Dots', 'elementor-pro' ), + 'arrows' => esc_html__( 'Arrows', 'elementor-pro' ), + 'dots' => esc_html__( 'Dots', 'elementor-pro' ), + 'none' => esc_html__( 'None', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay', + [ + 'label' => esc_html__( 'Autoplay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'pause_on_hover', + [ + 'label' => esc_html__( 'Pause on Hover', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'render_type' => 'none', + 'frontend_available' => true, + 'condition' => [ + 'autoplay!' => '', + ], + ] + ); + + $this->add_control( + 'pause_on_interaction', + [ + 'label' => esc_html__( 'Pause on Interaction', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'render_type' => 'none', + 'frontend_available' => true, + 'condition' => [ + 'autoplay!' => '', + ], + ] + ); + + $this->add_control( + 'autoplay_speed', + [ + 'label' => esc_html__( 'Autoplay Speed', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5000, + 'condition' => [ + 'autoplay' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide' => 'transition-duration: calc({{VALUE}}ms*1.2)', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'infinite', + [ + 'label' => esc_html__( 'Infinite Loop', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'transition', + [ + 'label' => esc_html__( 'Transition', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'slide', + 'options' => [ + 'slide' => esc_html__( 'Slide', 'elementor-pro' ), + 'fade' => esc_html__( 'Fade', 'elementor-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'transition_speed', + [ + 'label' => esc_html__( 'Transition Speed', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::NUMBER, + 'default' => 500, + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'content_animation', + [ + 'label' => esc_html__( 'Content Animation', 'elementor-pro' ), + 'type' => Control_Slides_Animation::TYPE, + 'default' => 'fadeInUp', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_slides', + [ + 'label' => esc_html__( 'Slides', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'content_max_width', + [ + 'label' => esc_html__( 'Content Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'default' => [ + 'size' => 66, + 'unit' => '%', + ], + 'tablet_default' => [ + 'unit' => '%', + ], + 'mobile_default' => [ + 'unit' => '%', + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide-contents' => 'max-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'slides_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide-inner' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'slides_horizontal_position', + [ + 'label' => esc_html__( 'Horizontal Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'prefix_class' => 'elementor--h-position-', + ] + ); + + $this->add_control( + 'slides_vertical_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'middle', + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'prefix_class' => 'elementor--v-position-', + ] + ); + + $this->add_control( + 'slides_text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'default' => 'center', + 'selectors' => [ + '{{WRAPPER}} .swiper-slide-inner' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'text_shadow', + 'selector' => '{{WRAPPER}} .swiper-slide-contents', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide-inner .elementor-slide-heading:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-heading' => 'color: {{VALUE}}', + + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-slide-heading', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_description', + [ + 'label' => esc_html__( 'Description', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'description_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-slide-inner .elementor-slide-description:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'description_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-description' => 'color: {{VALUE}}', + + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'description_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'selector' => '{{WRAPPER}} .elementor-slide-description', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_button', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'button_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'sm', + 'options' => self::get_button_sizes(), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .elementor-slide-button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + ] + ); + + $this->add_control( + 'button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button' => 'border-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->start_controls_tabs( 'button_tabs' ); + + $this->start_controls_tab( + 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-slide-button', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'button_hover_background', + 'types' => [ 'classic', 'gradient' ], + 'exclude' => [ 'image' ], + 'selector' => '{{WRAPPER}} .elementor-slide-button:hover', + 'fields_options' => [ + 'background' => [ + 'default' => 'classic', + ], + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button:hover' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-slide-button' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_navigation', + [ + 'label' => esc_html__( 'Navigation', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'navigation' => [ 'arrows', 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'heading_style_arrows', + [ + 'label' => esc_html__( 'Arrows', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'arrows_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'inside', + 'options' => [ + 'inside' => esc_html__( 'Inside', 'elementor-pro' ), + 'outside' => esc_html__( 'Outside', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-arrows-position-', + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_responsive_control( + 'arrows_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-swiper-button' => 'font-size: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'arrows_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-swiper-button' => 'color: {{VALUE}}', + '{{WRAPPER}} .elementor-swiper-button svg' => 'fill: {{VALUE}}', + ], + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'heading_style_dots', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'inside', + 'options' => [ + 'outside' => esc_html__( 'Outside', 'elementor-pro' ), + 'inside' => esc_html__( 'Inside', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-pagination-position-', + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_responsive_control( + 'dots_gap', + [ + 'label' => esc_html__( 'Space Between Dots', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet' => '--swiper-pagination-bullet-horizontal-gap: {{SIZE}}{{UNIT}}; --swiper-pagination-bullet-vertical-gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_responsive_control( + 'dots_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet' => 'height: {{SIZE}}{{UNIT}}; width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .swiper-horizontal .swiper-pagination-progressbar' => 'height: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .swiper-pagination-fraction' => 'font-size: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_color_inactive', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + // The opacity property will override the default inactive dot color which is opacity 0.2. + '{{WRAPPER}} .swiper-pagination-bullet:not(.swiper-pagination-bullet-active)' => 'background-color: {{VALUE}}; opacity: 1;', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_color', + [ + 'label' => esc_html__( 'Active Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .swiper-pagination-bullet-active' => 'background-color: {{VALUE}};', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['slides'] ) ) { + return; + } + + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + $direction = is_rtl() ? 'rtl' : 'ltr'; + + $this->add_render_attribute( [ + 'wrapper' => [ + 'class' => [ 'elementor-slides-wrapper', 'elementor-main-swiper', 'swiper' ], + 'role' => 'region', + 'aria-roledescription' => 'carousel', + 'aria-label' => $settings['slides_name'], + 'dir' => $direction, + 'data-animation' => $settings['content_animation'], + ], + ] ); + + $title_tag = Utils::validate_html_tag( $settings['slides_title_tag'] ); + $description_tag = Utils::validate_html_tag( $settings['slides_description_tag'] ); + + $this->add_render_attribute( 'button', 'class', [ 'elementor-button', 'elementor-slide-button' ] ); + + if ( ! empty( $settings['button_size'] ) ) { + $this->add_render_attribute( 'button', 'class', 'elementor-size-' . $settings['button_size'] ); + } + + $slides = []; + $slide_count = 0; + + foreach ( $settings['slides'] as $slide_index => $slide ) { + $slide_html = ''; + $btn_attributes = ''; + $slide_attributes = ''; + $slide_element = 'div'; + $btn_element = 'div'; + + if ( ! empty( $slide['link']['url'] ) ) { + $this->add_link_attributes( 'slide_link' . $slide_count, $slide['link'] ); + + if ( 'button' === $slide['link_click'] ) { + $btn_element = 'a'; + $btn_attributes = $this->get_render_attribute_string( 'slide_link' . $slide_count ); + } else { + $slide_element = 'a'; + $slide_attributes = $this->get_render_attribute_string( 'slide_link' . $slide_count ); + } + } + + $this->add_render_attribute( 'slide_bg_' . $slide_index, 'class', 'swiper-slide-bg' ); + + if ( $slide['background_ken_burns'] ) { + $this->add_render_attribute( 'slide_bg_' . $slide_index, 'class', [ 'elementor-ken-burns', 'elementor-ken-burns--' . $slide['zoom_direction'] ] ); + } + + if ( ! empty( $slide['background_image']['id'] ) ) { + $this->add_render_attribute( 'slide_bg_' . $slide_index, 'role', 'img' ); + $this->add_render_attribute( 'slide_bg_' . $slide_index, 'aria-label', Control_Media::get_image_alt( $slide['background_image'] ) ); + } + + $slide_html .= '<' . $slide_element . ' class="swiper-slide-inner" ' . $slide_attributes . '>'; + + $slide_html .= '
      '; + + if ( $slide['heading'] ) { + $slide_html .= '<' . $title_tag . ' class="elementor-slide-heading">' . $slide['heading'] . ''; + } + + if ( $slide['description'] ) { + $slide_html .= '<' . $description_tag . ' class="elementor-slide-description">' . $slide['description'] . ''; + } + + if ( $slide['button_text'] ) { + $slide_html .= '<' . $btn_element . ' ' . $btn_attributes . ' ' . $this->get_render_attribute_string( 'button' ) . '>' . $slide['button_text'] . ''; + } + + $slide_html .= '
      '; + + if ( 'yes' === $slide['background_overlay'] ) { + $slide_html = '
      ' . $slide_html; + } + + $slide_html = '
      get_render_attribute_string( 'slide_bg_' . $slide_index ) . '>
      ' . $slide_html; + + $slides[] = '
      ' . $slide_html . '
      '; + $slide_count++; + } + + $show_dots = ( in_array( $settings['navigation'], [ 'dots', 'both' ] ) ); + $show_arrows = ( in_array( $settings['navigation'], [ 'arrows', 'both' ] ) ); + + $slides_count = count( $settings['slides'] ); + ?> + +
      + +
      print_render_attribute_string( 'wrapper' ); ?>> +
      + + +
      + + +
      + render_swiper_button( 'previous' ); ?> +
      +
      + render_swiper_button( 'next' ); ?> +
      + + +
      + + +
      + +
      + + + <# + var direction = elementorFrontend.config.is_rtl ? 'rtl' : 'ltr', + next = elementorFrontend.config.is_rtl ? 'left' : 'right', + prev = elementorFrontend.config.is_rtl ? 'right' : 'left', + navi = settings.navigation, + showDots = ( 'dots' === navi || 'both' === navi ), + showArrows = ( 'arrows' === navi || 'both' === navi ), + buttonSize = settings.button_size, + titleTag = elementor.helpers.validateHTMLTag( settings.slides_title_tag ), + descriptionTag = elementor.helpers.validateHTMLTag( settings.slides_description_tag ); + optimizedMarkup = elementorCommon.config.experimentalFeatures.e_optimized_markup; + + view.addRenderAttribute( + 'wrapper', + { + 'class': [ 'elementor-slides-wrapper', 'elementor-main-swiper', elementorFrontend.config.swiperClass ], + 'role': 'region', + 'aria-roledescription': 'carousel', + 'aria-label': settings.slides_name, + 'dir': direction, + 'data-animation': settings.content_animation, + } + ); + #> + <# if ( ! optimizedMarkup ) { #> +
      + <# } #> +
      +
      + <# + jQuery.each( settings.slides, function( index, slide ) { + + view.addRenderAttribute( 'slide_bg_' + index, 'class', 'swiper-slide-bg' ); + + if ( '' != slide.background_ken_burns ) { + view.addRenderAttribute( 'slide_bg_' + index, 'class', [ 'elementor-ken-burns', 'elementor-ken-burns--' + _.escape( slide.zoom_direction ) ] ); + } + + if ( slide.background_image.id ) { + view.addRenderAttribute( 'slide_bg_' + index, 'role', 'img' ); + view.addRenderAttribute( 'slide_bg_' + index, 'aria-label', slide.background_image.alt || '' ); + } + #> +
      +
      + <# if ( 'yes' === slide.background_overlay ) { #> +
      + <# } #> +
      +
      + <# if ( slide.heading ) { #> + <{{ titleTag }} class="elementor-slide-heading">{{{ slide.heading }}} + <# } + if ( slide.description ) { #> + <{{descriptionTag}} class="elementor-slide-description">{{{ slide.description }}} + <# } + if ( slide.button_text ) { #> +
      {{{ slide.button_text }}}
      + <# } #> +
      +
      +
      + <# } ); #> +
      + <# if ( 1 < settings.slides.length ) { #> + <# if ( showArrows ) { #> +
      + +
      +
      + +
      + <# } #> + <# if ( showDots ) { #> +
      + <# } #> + <# } #> +
      + <# if ( ! optimizedMarkup ) { #> +
      + <# } #> + 'eicons', + 'value' => $icon_value, + ], [ 'aria-hidden' => 'true' ] ); + } +} diff --git a/modules/social/classes/facebook-sdk-manager.php b/modules/social/classes/facebook-sdk-manager.php new file mode 100644 index 00000000..237166b0 --- /dev/null +++ b/modules/social/classes/facebook-sdk-manager.php @@ -0,0 +1,180 @@ +', esc_attr( $app_id ) ); + } + } + + /** + * @param Widget_Base $widget + */ + public static function add_app_id_control( $widget ) { + if ( ! self::get_app_id() ) { + $content = sprintf( + /* translators: 1: Setting Page Link opening tag, 2: Link closing tag. */ + esc_html__( 'Set your Facebook App ID in the %1$sIntegrations Settings%2$s', 'elementor-pro' ), + sprintf( '
      ', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ); + $alert_type = 'warning'; + } else { + $content = sprintf( + /* translators: 1: App ID, 2: Setting Page Link opening tag, 3: Link closing tag. */ + esc_html__( 'You are connected to Facebook App %1$s, %2$sChange App%3$s', 'elementor-pro' ), + self::get_app_id(), + sprintf( '', Settings::get_settings_tab_url( 'integrations' ) ), + '' + ); + $alert_type = 'info'; + } + + $widget->add_control( + 'app_id', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => $alert_type, + 'content' => $content, + ] + ); + + $widget->add_control( + 'app_eu_message', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'For visitors from the EU, Facebook widgets will only work for site visitors if they have logged into Facebook and consented to cookies. %1$sLearn more%2$s', 'elementor-pro' ), + sprintf( '', 'https://developers.facebook.com/docs/plugins/' ), + '' + ), + ] + ); + } + + public function localize_settings( $settings ) { + $settings['facebook_sdk'] = [ + 'lang' => self::get_lang(), + 'app_id' => self::get_app_id(), + ]; + + return $settings; + } + + public function __construct() { + add_action( 'wp_head', [ __CLASS__, 'enqueue_meta_app_id' ] ); + add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'localize_settings' ] ); + + // The nonce already validated on the options page, + if ( ! empty( $_POST['option_page'] ) && 'elementor' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing + $this->validate_sdk(); + } + + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ] ); + } + } + + public static function get_permalink( $settings = [] ) { + $post_id = get_the_ID(); + + if ( isset( $settings['url_format'] ) && Module::URL_FORMAT_PRETTY === $settings['url_format'] ) { + return get_permalink( $post_id ); + } + + // Use plain url to avoid losing comments after change the permalink. + return add_query_arg( 'p', $post_id, home_url() ); + } + + public function register_admin_fields( Settings $settings ) { + $settings->add_section( Settings::TAB_INTEGRATIONS, 'facebook_sdk', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'Facebook SDK', 'elementor-pro' ) . '

      '; + + echo sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Facebook SDK lets you connect to your %1$sdedicated application%2$s so you can track the Facebook Widgets analytics on your site.', 'elementor-pro' ), + '', + '' + ); + echo '

      '; + + echo esc_html__( 'If you are using the Facebook Comments Widget, you can add moderating options through your application. Note that this option will not work on local sites and on domains that don\'t have public access.', 'elementor-pro' ); + }, + 'fields' => [ + 'pro_facebook_app_id' => [ + 'label' => esc_html__( 'App ID', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'text', + 'desc' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Remember to add the domain to your %1$sApp Domains%2$s', 'elementor-pro' ), + sprintf( '', $this->get_app_settings_url() ), + '' + ), + ], + ], + ], + ] ); + } + + private function get_app_settings_url() { + $app_id = self::get_app_id(); + if ( $app_id ) { + return sprintf( 'https://developers.facebook.com/apps/%d/settings/', $app_id ); + } else { + return 'https://developers.facebook.com/apps/'; + } + } + + private function validate_sdk() { + $errors = []; + + // The nonce already validated on the options page, + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $app_id = Utils::_unstable_get_super_global_value( $_POST, 'elementor_pro_facebook_app_id' ); + + if ( $app_id ) { + $response = wp_remote_get( 'https://graph.facebook.com/' . $app_id ); + + if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { + $errors[] = esc_html__( 'Facebook App ID is not valid', 'elementor-pro' ); + } + } + + $message = implode( '
      ', $errors ); + + if ( ! empty( $errors ) ) { + wp_die( $message, esc_html__( 'Facebook SDK', 'elementor-pro' ), [ 'back_link' => true ] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } +} diff --git a/modules/social/module.php b/modules/social/module.php new file mode 100644 index 00000000..2a819a94 --- /dev/null +++ b/modules/social/module.php @@ -0,0 +1,63 @@ +get_css_assets_url( 'widget-social', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + + public function __construct() { + parent::__construct(); + + $this->add_component( 'facebook_sdk', new Facebook_SDK_Manager() ); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + } +} diff --git a/modules/social/widgets/facebook-button.php b/modules/social/widgets/facebook-button.php new file mode 100644 index 00000000..fb90c152 --- /dev/null +++ b/modules/social/widgets/facebook-button.php @@ -0,0 +1,235 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-social' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + ] + ); + + Facebook_SDK_Manager::add_app_id_control( $this ); + + $this->add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'like', + 'options' => [ + 'like' => esc_html__( 'Like', 'elementor-pro' ), + 'recommend' => esc_html__( 'Recommend', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'standard', + 'options' => [ + 'standard' => esc_html__( 'Standard', 'elementor-pro' ), + 'button' => esc_html__( 'Button', 'elementor-pro' ), + 'button_count' => esc_html__( 'Button Count', 'elementor-pro' ), + 'box_count' => esc_html__( 'Box Count', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'small', + 'options' => [ + 'small' => esc_html__( 'Small', 'elementor-pro' ), + 'large' => esc_html__( 'Large', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'color_scheme', + [ + 'label' => esc_html__( 'Color Scheme', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'light', + 'options' => [ + 'light' => esc_html__( 'Light', 'elementor-pro' ), + 'dark' => esc_html__( 'Dark', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'show_share', + [ + 'label' => esc_html__( 'Share Button', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'type!' => 'follow', + ], + ] + ); + + $this->add_control( + 'show_faces', + [ + 'label' => esc_html__( 'Faces', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ] + ); + + $this->add_control( + 'url_type', + [ + 'label' => esc_html__( 'Target URL', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + Module::URL_TYPE_CURRENT_PAGE => esc_html__( 'Current Page', 'elementor-pro' ), + Module::URL_TYPE_CUSTOM => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => Module::URL_TYPE_CURRENT_PAGE, + 'separator' => 'before', + 'condition' => [ + 'type' => [ 'like', 'recommend' ], + ], + ] + ); + + $this->add_control( + 'url_format', + [ + 'label' => esc_html__( 'URL Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + Module::URL_FORMAT_PLAIN => esc_html__( 'Plain Permalink', 'elementor-pro' ), + Module::URL_FORMAT_PRETTY => esc_html__( 'Pretty Permalink', 'elementor-pro' ), + ], + 'default' => Module::URL_FORMAT_PLAIN, + 'condition' => [ + 'url_type' => Module::URL_TYPE_CURRENT_PAGE, + ], + ] + ); + + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'placeholder' => esc_html__( 'https://your-link.com', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'type' => [ 'like', 'recommend' ], + 'url_type' => Module::URL_TYPE_CUSTOM, + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $settings = $this->get_settings(); + + // Validate URL + switch ( $settings['type'] ) { + case 'like': + case 'recommend': + if ( Module::URL_TYPE_CUSTOM === $settings['url_type'] && ! filter_var( $settings['url'], FILTER_VALIDATE_URL ) ) { + if ( Plugin::elementor()->editor->is_edit_mode() ) { + echo $this->get_title() . ': ' . esc_html__( 'Please enter a valid URL', 'elementor-pro' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + return; + } + break; + } + + $attributes = [ + 'data-layout' => $settings['layout'], + 'data-colorscheme' => $settings['color_scheme'], + 'data-size' => $settings['size'], + 'data-show-faces' => $settings['show_faces'] ? 'true' : 'false', + ]; + + switch ( $settings['type'] ) { + case 'like': + case 'recommend': + if ( Module::URL_TYPE_CURRENT_PAGE === $settings['url_type'] ) { + $permalink = Facebook_SDK_Manager::get_permalink( $settings ); + } else { + $permalink = esc_url( $settings['url'] ); + } + + $attributes['class'] = 'elementor-facebook-widget fb-like'; + $attributes['data-href'] = $permalink; + $attributes['data-share'] = $settings['show_share'] ? 'true' : 'false'; + $attributes['data-action'] = $settings['type']; + break; + } + + $this->add_render_attribute( 'embed_div', $attributes ); + ?> +
      print_render_attribute_string( 'embed_div' ); ?>>
      + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-social' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Comments Box', 'elementor-pro' ), + ] + ); + + Facebook_SDK_Manager::add_app_id_control( $this ); + + $this->add_control( + 'comments_number', + [ + 'label' => esc_html__( 'Comment Count', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'min' => 5, + 'max' => 100, + 'default' => '10', + 'description' => esc_html__( 'Minimum number of comments: 5', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'order_by', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'social', + 'options' => [ + 'social' => esc_html__( 'Social', 'elementor-pro' ), + 'reverse_time' => esc_html__( 'Reverse Time', 'elementor-pro' ), + 'time' => esc_html__( 'Time', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'url_type', + [ + 'label' => esc_html__( 'Target URL', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + Module::URL_TYPE_CURRENT_PAGE => esc_html__( 'Current Page', 'elementor-pro' ), + Module::URL_TYPE_CUSTOM => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => Module::URL_TYPE_CURRENT_PAGE, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'url_format', + [ + 'label' => esc_html__( 'URL Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + Module::URL_FORMAT_PLAIN => esc_html__( 'Plain Permalink', 'elementor-pro' ), + Module::URL_FORMAT_PRETTY => esc_html__( 'Pretty Permalink', 'elementor-pro' ), + ], + 'default' => Module::URL_FORMAT_PLAIN, + 'condition' => [ + 'url_type' => Module::URL_TYPE_CURRENT_PAGE, + ], + ] + ); + + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'placeholder' => esc_html__( 'https://your-link.com', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'url_type' => Module::URL_TYPE_CUSTOM, + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + if ( Module::URL_TYPE_CURRENT_PAGE === $settings['url_type'] ) { + $permalink = Facebook_SDK_Manager::get_permalink( $settings ); + } else { + if ( ! filter_var( $settings['url'], FILTER_VALIDATE_URL ) ) { + echo $this->get_title() . ': ' . esc_html__( 'Please enter a valid URL', 'elementor-pro' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + return; + } + + $permalink = esc_url( $settings['url'] ); + } + + $attributes = [ + 'class' => 'elementor-facebook-widget fb-comments', + 'data-href' => $permalink, + 'data-width' => '100%', + 'data-numposts' => $settings['comments_number'], + 'data-order-by' => $settings['order_by'], + // The style prevent's the `widget.handleEmptyWidget` to set it as an empty widget + 'style' => 'min-height: 1px', + ]; + + $this->add_render_attribute( 'embed_div', $attributes ); + ?> +
      print_render_attribute_string( 'embed_div' ); ?>>
      + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-social' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Embed', 'elementor-pro' ), + ] + ); + + Facebook_SDK_Manager::add_app_id_control( $this ); + + $this->add_control( + 'widget_exclusively_web', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + esc_html__( 'Facebook post embedding is exclusively available for the web, mobile devices are not supported. %1$sLearn more%2$s', 'elementor-pro' ), + sprintf( '', Facebook_SDK_Manager::FACEBOOK_PLUGINS_FAQ_URL ), + '' + ), + ] + ); + + $this->add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post', + 'options' => [ + 'post' => esc_html__( 'Post', 'elementor-pro' ), + 'video' => esc_html__( 'Video', 'elementor-pro' ), + 'comment' => esc_html__( 'Comment', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'post_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'default' => 'https://www.facebook.com/elemntor/posts/2624214124556197', + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'type' => 'post', + ], + 'description' => esc_html__( 'Hover over the date next to the post, and copy its link address.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'video_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'default' => 'https://www.facebook.com/elemntor/videos/1683988961912056/', + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'type' => 'video', + ], + 'description' => esc_html__( 'Hover over the date next to the video, and copy its link address.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'comment_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'default' => 'https://www.facebook.com/elemntor/videos/1811703749140576/?comment_id=1812873919023559', + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'type' => 'comment', + ], + 'description' => esc_html__( 'Hover over the date next to the comment, and copy its link address.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'include_parent', + [ + 'label' => esc_html__( 'Parent Comment', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Set to include parent comment (if URL is a reply).', 'elementor-pro' ), + 'condition' => [ + 'type' => 'comment', + ], + ] + ); + + $this->add_control( + 'show_text', + [ + 'label' => esc_html__( 'Full Post', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Show the full text of the post', 'elementor-pro' ), + 'condition' => [ + 'type' => [ 'post', 'video' ], + ], + ] + ); + + $this->add_control( + 'video_allowfullscreen', + [ + 'label' => esc_html__( 'Allow Full Screen', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'type' => 'video', + ], + ] + ); + + $this->add_control( + 'video_autoplay', + [ + 'label' => esc_html__( 'Autoplay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'type' => 'video', + ], + ] + ); + + $this->add_control( + 'video_show_captions', + [ + 'label' => esc_html__( 'Captions', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Show captions if available (only on desktop).', 'elementor-pro' ), + 'condition' => [ + 'type' => 'video', + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['type'] ) ) { + echo esc_html__( 'Please set the embed type', 'elementor-pro' ); + + return; + } + + if ( 'comment' === $settings['type'] && empty( $settings['comment_url'] ) || 'post' === $settings['type'] && empty( $settings['post_url'] ) || 'video' === $settings['type'] && empty( $settings['video_url'] ) ) { + echo esc_html__( 'Please enter a valid URL', 'elementor-pro' ); + + return; + } + + $attributes = [ + // The style prevent's the `widget.handleEmptyWidget` to set it as an empty widget + 'style' => 'min-height: 1px', + ]; + + switch ( $settings['type'] ) { + case 'comment': + $attributes['class'] = 'elementor-facebook-widget fb-comment-embed'; + $attributes['data-href'] = esc_url( $settings['comment_url'] ); + $attributes['data-include-parent'] = 'yes' === $settings['include_parent'] ? 'true' : 'false'; + break; + case 'post': + $attributes['class'] = 'elementor-facebook-widget fb-post'; + $attributes['data-href'] = esc_url( $settings['post_url'] ); + $attributes['data-show-text'] = 'yes' === $settings['show_text'] ? 'true' : 'false'; + break; + case 'video': + $attributes['class'] = 'elementor-facebook-widget fb-video'; + $attributes['data-href'] = esc_url( $settings['video_url'] ); + $attributes['data-show-text'] = 'yes' === $settings['show_text'] ? 'true' : 'false'; + $attributes['data-allowfullscreen'] = 'yes' === $settings['video_allowfullscreen'] ? 'true' : 'false'; + $attributes['data-autoplay'] = 'yes' === $settings['video_autoplay'] ? 'true' : 'false'; + $attributes['data-show-captions'] = 'yes' === $settings['video_show_captions'] ? 'true' : 'false'; + break; + } + + $this->add_render_attribute( 'embed_div', $attributes ); + + echo '
      get_render_attribute_string( 'embed_div' ) . '>
      '; // XSS ok. + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'social'; + } +} diff --git a/modules/social/widgets/facebook-page.php b/modules/social/widgets/facebook-page.php new file mode 100644 index 00000000..37c19cc5 --- /dev/null +++ b/modules/social/widgets/facebook-page.php @@ -0,0 +1,205 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-social' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Page', 'elementor-pro' ), + ] + ); + + Facebook_SDK_Manager::add_app_id_control( $this ); + + $this->add_control( + 'widget_exclusively_web', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + esc_html__( 'Facebook page embedding is exclusively available for the web, mobile devices are not supported. %1$sLearn more%2$s', 'elementor-pro' ), + sprintf( '', Facebook_SDK_Manager::FACEBOOK_PLUGINS_FAQ_URL ), + '' + ), + ] + ); + + $this->add_control( + 'url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'placeholder' => 'https://www.facebook.com/your-page/', + 'default' => 'https://www.facebook.com/elemntor/', + 'label_block' => true, + 'description' => esc_html__( 'Paste the URL of the Facebook page.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tabs', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'label_block' => true, + 'default' => [ + 'timeline', + ], + 'options' => [ + 'timeline' => esc_html__( 'Timeline', 'elementor-pro' ), + 'events' => esc_html__( 'Events', 'elementor-pro' ), + 'messages' => esc_html__( 'Messages', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'small_header', + [ + 'label' => esc_html__( 'Small Header', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + ] + ); + + $this->add_control( + 'show_cover', + [ + 'label' => esc_html__( 'Cover Photo', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_facepile', + [ + 'label' => esc_html__( 'Profile Photos', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_cta', + [ + 'label' => esc_html__( 'Custom CTA Button', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->add_control( + 'height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 500, + ], + 'range' => [ + 'px' => [ + 'min' => 50, + 'max' => 1000, + ], + 'em' => [ + 'min' => 5, + 'max' => 100, + ], + 'rem' => [ + 'min' => 5, + 'max' => 100, + ], + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['url'] ) ) { + echo $this->get_title() . ': ' . esc_html__( 'Please enter a valid URL', 'elementor-pro' ); // XSS ok. + + return; + } + + $height = $settings['height']['size'] . $settings['height']['unit']; + + $attributes = [ + 'class' => 'elementor-facebook-widget fb-page', + 'data-href' => $settings['url'], + 'data-tabs' => implode( ',', $settings['tabs'] ), + 'data-height' => $height, + 'data-width' => '500px', // Try the max possible width + 'data-small-header' => $settings['small_header'] ? 'true' : 'false', + 'data-hide-cover' => $settings['show_cover'] ? 'false' : 'true', // if `show` - don't hide. + 'data-show-facepile' => $settings['show_facepile'] ? 'true' : 'false', + 'data-hide-cta' => $settings['show_cta'] ? 'false' : 'true', // if `show` - don't hide. + // The style prevent's the `widget.handleEmptyWidget` to set it as an empty widget. + 'style' => 'min-height: 1px;height:' . $height, + ]; + + $this->add_render_attribute( 'embed_div', $attributes ); + + echo '
      get_render_attribute_string( 'embed_div' ) . '>
      '; // XSS ok. + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'social'; + } +} diff --git a/modules/sticky/module.php b/modules/sticky/module.php new file mode 100644 index 00000000..29bea5d2 --- /dev/null +++ b/modules/sticky/module.php @@ -0,0 +1,267 @@ +add_actions(); + } + + public function get_name() { + return 'sticky'; + } + + /** + * Check if `$element` is an instance of a class in the `$types` array. + * + * @param $element + * @param $types + * + * @return bool + */ + private function is_instance_of( $element, array $types ) { + foreach ( $types as $type ) { + if ( $element instanceof $type ) { + return true; + } + } + + return false; + } + + public function register_controls( Element_Base $element ) { + $element->add_control( + 'sticky', + [ + 'label' => esc_html__( 'Sticky', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'top' => esc_html__( 'Top', 'elementor-pro' ), + 'bottom' => esc_html__( 'Bottom', 'elementor-pro' ), + ], + 'separator' => 'before', + 'render_type' => 'none', + 'frontend_available' => true, + 'assets' => $this->get_asset_conditions_data(), + ] + ); + + // TODO: In Pro 3.5.0, get the active devices using Breakpoints/Manager::get_active_devices_list(). + $active_breakpoint_instances = Plugin::elementor()->breakpoints->get_active_breakpoints(); + // Devices need to be ordered from largest to smallest. + $active_devices = array_reverse( array_keys( $active_breakpoint_instances ) ); + + // Add desktop in the correct position. + if ( in_array( 'widescreen', $active_devices, true ) ) { + $active_devices = array_merge( array_slice( $active_devices, 0, 1 ), [ 'desktop' ], array_slice( $active_devices, 1 ) ); + } else { + $active_devices = array_merge( [ 'desktop' ], $active_devices ); + } + + $sticky_device_options = []; + + foreach ( $active_devices as $device ) { + $label = 'desktop' === $device ? esc_html__( 'Desktop', 'elementor-pro' ) : $active_breakpoint_instances[ $device ]->get_label(); + $sticky_device_options[ $device ] = $label; + } + + $element->add_control( + 'sticky_on', + [ + 'label' => esc_html__( 'Sticky On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'label_block' => true, + 'default' => $active_devices, + 'options' => $sticky_device_options, + 'condition' => [ + 'sticky!' => '', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $element->add_responsive_control( + 'sticky_offset', + [ + 'label' => esc_html__( 'Sticky Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'min' => 0, + 'max' => 500, + 'required' => true, + 'condition' => [ + 'sticky!' => '', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $element->add_responsive_control( + 'sticky_effects_offset', + [ + 'label' => esc_html__( 'Effects Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'min' => 0, + 'max' => 1000, + 'required' => true, + 'condition' => [ + 'sticky!' => '', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $element->add_responsive_control( + 'sticky_anchor_link_offset', + [ + 'label' => esc_html__( 'Anchor Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 0, + 'min' => 0, + 'max' => 500, + 'required' => true, + 'condition' => [ + 'sticky!' => '', + ], + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + + $element->add_control( + 'anchor_offset_description', + [ + 'raw' => sprintf( + esc_html__( 'Using the Anchor offset may require you to adjust the offset of other sticky elements. %1$s Learn more %2$s', 'elementor-pro' ), + '', + '' + ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-control-field-description', + 'condition' => [ + 'sticky!' => '', + ], + ] + ); + + // Add `Stay In Column` only to the following types: + $types = [ + Element_Section::class, + Widget_Base::class, + ]; + + // TODO: Remove when Container is the default. + if ( Plugin::elementor()->experiments->is_feature_active( 'container' ) ) { + $types[] = \Elementor\Includes\Elements\Container::class; + } + + if ( $this->is_instance_of( $element, $types ) ) { + $conditions = [ + 'sticky!' => '', + ]; + + // Target only inner sections. + // Checking for `$element->get_data( 'isInner' )` in both editor & frontend causes it to work properly on the frontend but + // break on the editor, because the inner section is created in JS and not rendered in PHP. + // So this is a hack to force the editor to show the `sticky_parent` control, and still make it work properly on the frontend. + if ( $element instanceof Element_Section && Plugin::elementor()->editor->is_edit_mode() ) { + $conditions['isInner'] = true; + } + + $element->add_control( + 'sticky_parent', + [ + 'label' => esc_html__( 'Stay In Column', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => $conditions, + 'render_type' => 'none', + 'frontend_available' => true, + ] + ); + } + + $element->add_control( + 'sticky_divider', + [ + 'type' => Controls_Manager::DIVIDER, + ] + ); + } + + private function get_asset_conditions_data() { + return [ + 'styles' => [ + [ + 'name' => 'e-sticky', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'sticky', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + 'scripts' => [ + [ + 'name' => 'e-sticky', + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'sticky', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ]; + } + + public function register_frontend_styles() { + $suffix = Utils::is_script_debug() ? '' : '.min'; + + wp_register_style( + 'e-sticky', + ELEMENTOR_PRO_URL . 'assets/css/modules/sticky' . $suffix . '.css', + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function enqueue_preview_styles() { + wp_enqueue_style( 'e-sticky' ); + } + + private function add_actions() { + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_frontend_styles' ] ); + add_action( 'elementor/preview/enqueue_styles', [ $this, 'enqueue_preview_styles' ] ); + + add_action( 'elementor/element/section/section_effects/after_section_start', [ $this, 'register_controls' ] ); + add_action( 'elementor/element/container/section_effects/after_section_start', [ $this, 'register_controls' ] ); + add_action( 'elementor/element/common/section_effects/after_section_start', [ $this, 'register_controls' ] ); + } +} diff --git a/modules/table-of-contents/module.php b/modules/table-of-contents/module.php new file mode 100644 index 00000000..59e73f7a --- /dev/null +++ b/modules/table-of-contents/module.php @@ -0,0 +1,54 @@ +get_css_assets_url( 'widget-table-of-contents', null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/table-of-contents/widgets/table-of-contents.php b/modules/table-of-contents/widgets/table-of-contents.php new file mode 100644 index 00000000..1237a4dd --- /dev/null +++ b/modules/table-of-contents/widgets/table-of-contents.php @@ -0,0 +1,965 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-table-of-contents' ]; + } + + /** + * Get Frontend Settings + * + * In the TOC widget, this implementation is used to pass a pre-rendered version of the icon to the front end, + * which is required in case the FontAwesome SVG experiment is active. + * + * @since 3.4.0 + * + * @return array + */ + public function get_frontend_settings() { + $frontend_settings = parent::get_frontend_settings(); + + if ( Plugin::elementor()->experiments->is_feature_active( 'e_font_icon_svg' ) && ! empty( $frontend_settings['icon']['value'] ) ) { + $frontend_settings['icon']['rendered_tag'] = Icons_Manager::render_font_icon( $frontend_settings['icon'] ); + } + + return $frontend_settings; + } + + protected function register_controls() { + $this->start_controls_section( + 'table_of_contents', + [ + 'label' => esc_html__( 'Table of Contents', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'default' => esc_html__( 'Table of Contents', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + ], + 'default' => 'h4', + ] + ); + + $this->start_controls_tabs( 'include_exclude_tags', [ 'separator' => 'before' ] ); + + $this->start_controls_tab( 'include', + [ + 'label' => esc_html__( 'Include', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'headings_by_tags', + [ + 'label' => esc_html__( 'Anchors By Tags', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'default' => [ 'h2', 'h3', 'h4', 'h5', 'h6' ], + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + ], + 'label_block' => true, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'container', + [ + 'label' => esc_html__( 'Container', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'label_block' => true, + 'description' => esc_html__( 'This control confines the Table of Contents to heading elements under a specific container', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->end_controls_tab(); // include + + $this->start_controls_tab( 'exclude', + [ + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'exclude_headings_by_selector', + [ + 'label' => esc_html__( 'Anchors By Selector', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'description' => esc_html__( 'CSS selectors, in a comma-separated list', 'elementor-pro' ), + 'default' => [], + 'label_block' => true, + 'frontend_available' => true, + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->end_controls_tab(); // exclude + + $this->end_controls_tabs(); // include_exclude_tags + + $this->add_control( + 'marker_view', + [ + 'label' => esc_html__( 'Marker View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'numbers', + 'options' => [ + 'numbers' => esc_html__( 'Numbers', 'elementor-pro' ), + 'bullets' => esc_html__( 'Bullets', 'elementor-pro' ), + ], + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'default' => [ + 'value' => 'fas fa-circle', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'circle', + 'dot-circle', + 'square-full', + ], + 'fa-regular' => [ + 'circle', + 'dot-circle', + 'square-full', + ], + ], + 'condition' => [ + 'marker_view' => 'bullets', + ], + 'skin' => 'inline', + 'label_block' => false, + 'exclude_inline_options' => [ 'svg' ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'no_headings_message', + [ + 'label' => esc_html__( 'No Headings Found Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'No headings were found on this page.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); // table_of_contents + + $this->start_controls_section( + 'additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'word_wrap', + [ + 'label' => esc_html__( 'Word Wrap', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'ellipsis', + 'prefix_class' => 'elementor-toc--content-', + ] + ); + + $this->add_control( + 'minimize_box', + [ + 'label' => esc_html__( 'Minimize Box', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'expand_icon', + [ + 'label' => esc_html__( 'Expand Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'default' => [ + 'value' => 'fas fa-chevron-down', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-down', + 'angle-down', + 'angle-double-down', + 'caret-down', + 'caret-square-down', + ], + 'fa-regular' => [ + 'caret-square-down', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'minimize_box' => 'yes', + ], + ] + ); + + $this->add_control( + 'collapse_icon', + [ + 'label' => esc_html__( 'Collapse Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'default' => [ + 'value' => 'fas fa-chevron-up', + 'library' => 'fa-solid', + ], + 'recommended' => [ + 'fa-solid' => [ + 'chevron-up', + 'angle-up', + 'angle-double-up', + 'caret-up', + 'caret-square-up', + ], + 'fa-regular' => [ + 'caret-square-up', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'minimize_box' => 'yes', + ], + ] + ); + + // TODO: For Pro 3.6.0, convert this to the breakpoints utility method introduced in core 3.5.0. + $breakpoints = Plugin::elementor()->breakpoints->get_active_breakpoints(); + + $minimized_on_options = []; + + foreach ( $breakpoints as $breakpoint_key => $breakpoint ) { + // This feature is meant for mobile screens. + if ( 'widescreen' === $breakpoint_key ) { + continue; + } + + $minimized_on_options[ $breakpoint_key ] = sprintf( + /* translators: 1: Breakpoint label, 2: `<` character, 3: Breakpoint value. */ + esc_html__( '%1$s (%2$s %3$dpx)', 'elementor-pro' ), + $breakpoint->get_label(), + '<', + $breakpoint->get_value() + ); + } + + $minimized_on_options['desktop'] = esc_html__( 'Desktop (or smaller)', 'elementor-pro' ); + + $this->add_control( + 'minimized_on', + [ + 'label' => esc_html__( 'Minimized On', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'tablet', + 'options' => $minimized_on_options, + 'prefix_class' => 'elementor-toc--minimized-on-', + 'condition' => [ + 'minimize_box!' => '', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'hierarchical_view', + [ + 'label' => esc_html__( 'Hierarchical View', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'frontend_available' => true, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'collapse_subitems', + [ + 'label' => esc_html__( 'Collapse Subitems', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'description' => esc_html__( 'The "Collapse" option should only be used if the Table of Contents is made sticky', 'elementor-pro' ), + 'condition' => [ + 'hierarchical_view' => 'yes', + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); // settings + + $this->start_controls_section( + 'box_style', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => '--box-background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--box-border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'loader_color', + [ + 'label' => esc_html__( 'Loader Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + // Not using CSS var for BC, when not configured: the loader should get the color from the body tag. + '{{WRAPPER}} .elementor-toc__spinner' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--box-border-width: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--box-border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'header_separator_width', + [ + 'label' => esc_html__( 'Separator Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--separator-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--box-padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'min_height', + [ + 'label' => esc_html__( 'Min Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--box-min-height: {{SIZE}}{{UNIT}}', + ], + 'frontend_available' => true, + 'separator' => 'after', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}}', + ] + ); + + $this->end_controls_section(); // box_style + + $this->start_controls_section( + 'header_style', + [ + 'label' => esc_html__( 'Header', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $logical_start = is_rtl() ? 'right' : 'left'; + $logical_end = is_rtl() ? 'left' : 'right'; + + $this->add_responsive_control( + 'header_text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-text-align-$logical_start", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-text-align-$logical_end", + ], + ], + 'default' => 'start', + 'selectors' => [ + '{{WRAPPER}} .elementor-toc__header-title' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'header_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--header-background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'header_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--header-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'header_typography', + 'selector' => '{{WRAPPER}} .elementor-toc__header, {{WRAPPER}} .elementor-toc__header-title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_control( + 'toggle_button_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'condition' => [ + 'minimize_box' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-color: {{VALUE}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'toggle_button_position', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'row-reverse' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-$logical_start", + ], + 'row' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-$logical_end", + ], + ], + 'default' => 'row', + 'toggle' => false, + 'selectors' => [ + '{{WRAPPER}} .elementor-toc__header' => 'flex-direction: {{VALUE}};', + ], + 'condition' => [ + 'minimize_box' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'heading_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-toc__header' => 'column-gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'minimize_box' => 'yes', + ], + ] + ); + + $this->end_controls_section(); // header_style + + $this->start_controls_section( + 'list_style', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'max_height', + [ + 'label' => esc_html__( 'Max Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 1000, + ], + 'em' => [ + 'max' => 100, + ], + 'rem' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--toc-body-max-height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'list_typography', + 'selector' => '{{WRAPPER}} .elementor-toc__list-item', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_responsive_control( + 'list_indent', + [ + 'label' => esc_html__( 'Indent', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'unit' => 'em', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--nested-list-indent: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->start_controls_tabs( 'item_text_style' ); + + $this->start_controls_tab( 'normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'item_text_color_normal', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'item_text_underline_normal', + [ + 'label' => esc_html__( 'Underline', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-decoration: underline', + ], + ] + ); + + $this->end_controls_tab(); // normal + + $this->start_controls_tab( 'hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'item_text_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-hover-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'item_text_underline_hover', + [ + 'label' => esc_html__( 'Underline', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-hover-decoration: underline', + ], + ] + ); + + $this->add_control( + 'item_text_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-transition-duration: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_tab(); // hover + + $this->start_controls_tab( 'active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'item_text_color_active', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-active-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'item_text_underline_active', + [ + 'label' => esc_html__( 'Underline', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}}' => '--item-text-active-decoration: underline', + ], + ] + ); + + $this->end_controls_tab(); // active + + $this->end_controls_tabs(); // item_text_style + + $this->add_control( + 'heading_marker', + [ + 'label' => esc_html__( 'Marker', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'marker_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--marker-color: {{VALUE}}', + ], + ] + ); + + $this->add_responsive_control( + 'marker_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--marker-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); // list_style + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $toc_id = 'elementor-toc__' . $this->get_id(); + + $this->add_render_attribute( 'header', 'class', 'elementor-toc__header' ); + + $this->add_render_attribute( + 'body', + [ + 'id' => $toc_id, + 'class' => 'elementor-toc__body', + ] + ); + + if ( $settings['collapse_subitems'] ) { + $this->add_render_attribute( 'body', 'class', 'elementor-toc__list-items--collapsible' ); + } + + if ( 'yes' === $settings['minimize_box'] ) { + $this->add_render_attribute( + 'expand-button', + [ + 'class' => 'elementor-toc__toggle-button elementor-toc__toggle-button--expand', + 'role' => 'button', + 'tabindex' => '0', + 'aria-controls' => $toc_id, + 'aria-expanded' => 'true', + 'aria-label' => esc_attr__( 'Open table of contents', 'elementor-pro' ), + ] + ); + $this->add_render_attribute( + 'collapse-button', + [ + 'class' => 'elementor-toc__toggle-button elementor-toc__toggle-button--collapse', + 'role' => 'button', + 'tabindex' => '0', + 'aria-controls' => $toc_id, + 'aria-expanded' => 'true', + 'aria-label' => esc_attr__( 'Close table of contents', 'elementor-pro' ), + ] + ); + } + + $html_tag = Utils::validate_html_tag( $settings['html_tag'] ); + ?> + +
      print_render_attribute_string( 'header' ); ?>> + + < class="elementor-toc__header-title"> + + > + + +
      print_render_attribute_string( 'expand-button' ); ?>> 'true' ] ); ?>
      +
      print_render_attribute_string( 'collapse-button' ); ?>> 'true' ] ); ?>
      + +
      + +
      print_render_attribute_string( 'body' ); ?>> +
      + 'eicons', + 'value' => 'eicon-loading', + ], + [ + 'class' => [ + 'elementor-toc__spinner', + 'eicon-animation-spin', + ], + 'aria-hidden' => 'true', + ] + ); ?> +
      +
      + get_locations_manager()->do_location( $location ); +} + +function elementor_location_exits( $location, $check_match = false ) { + /** @var Theme_Builder_Module $theme_builder_module */ + $theme_builder_module = Theme_Builder_Module::instance(); + + return $theme_builder_module->get_locations_manager()->location_exits( $location, $check_match ); +} diff --git a/modules/theme-builder/assets/images/conditions-tab.svg b/modules/theme-builder/assets/images/conditions-tab.svg new file mode 100644 index 00000000..59b8a723 --- /dev/null +++ b/modules/theme-builder/assets/images/conditions-tab.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/modules/theme-builder/classes/conditions-cache.php b/modules/theme-builder/classes/conditions-cache.php new file mode 100644 index 00000000..dc9d32d4 --- /dev/null +++ b/modules/theme-builder/classes/conditions-cache.php @@ -0,0 +1,143 @@ +refresh(); + } + + /** + * @param Theme_Document $document + * @param array $conditions + * + * @return $this + */ + public function add( Theme_Document $document, array $conditions ) { + $location = $document->get_location(); + if ( $location ) { + if ( ! isset( $this->conditions[ $location ] ) ) { + $this->conditions[ $location ] = []; + } + $this->conditions[ $location ][ $document->get_main_id() ] = $conditions; + } + + return $this; + } + + /** + * @param int $post_id + * + * @return $this + */ + public function remove( $post_id ) { + $post_id = absint( $post_id ); + + foreach ( $this->conditions as $location => $templates ) { + foreach ( $templates as $id => $template ) { + if ( $post_id === $id ) { + unset( $this->conditions[ $location ][ $id ] ); + } + } + } + + return $this; + } + + /** + * @param Theme_Document $document + * @param array $conditions + * + * @return $this + */ + public function update( $document, $conditions ) { + return $this->remove( $document->get_main_id() )->add( $document, $conditions ); + } + + public function save() { + return update_option( self::OPTION_NAME, $this->conditions ); + } + + public function refresh() { + $this->conditions = get_option( self::OPTION_NAME, [] ); + + return $this; + } + + public function clear() { + $this->conditions = []; + + return $this; + } + + public function get_by_location( $location ) { + if ( isset( $this->conditions[ $location ] ) ) { + return $this->conditions[ $location ]; + } + + return []; + } + + public function regenerate() { + $this->clear(); + + $document_types = Plugin::elementor()->documents->get_document_types(); + + $post_types = [ + Source_Local::CPT, + ]; + + foreach ( $document_types as $document_type ) { + if ( $document_type::get_property( 'support_conditions' ) && $document_type::get_property( 'cpt' ) ) { + $post_types = array_merge( $post_types, $document_type::get_property( 'cpt' ) ); + } + } + + $query_args = [ + 'posts_per_page' => -1, + 'post_type' => $post_types, + 'fields' => 'ids', + 'meta_key' => '_elementor_conditions', + ]; + + /** + * Query args for regenerating conditions cache. + * + * Filters the query arguments used for regenerating conditions cache. This hook + * allows developers to alter those arguments. + * + * @since 3.7.0 + * + * @param array $query_args An array of WordPress query arguments. + */ + $query_args = apply_filters( 'elementor/theme/conditions/cache/regenerate/query_args', $query_args ); + + $query = new \WP_Query( $query_args ); + + foreach ( $query->posts as $post_id ) { + $document = Module::instance()->get_document( $post_id ); + + if ( $document ) { + $conditions = $document->get_meta( '_elementor_conditions' ); + $this->add( $document, $conditions ); + } + } + + $this->save(); + + return $this; + } +} diff --git a/modules/theme-builder/classes/conditions-manager.php b/modules/theme-builder/classes/conditions-manager.php new file mode 100644 index 00000000..dc4b5d9f --- /dev/null +++ b/modules/theme-builder/classes/conditions-manager.php @@ -0,0 +1,563 @@ +cache = new Conditions_Cache(); + + add_action( 'wp_loaded', [ $this, 'register_conditions' ] ); // After Plugins Registered CPT. + add_action( 'wp_trash_post', [ $this, 'purge_post_from_cache' ] ); + add_action( 'untrashed_post', [ $this, 'on_untrash_post' ] ); + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + add_action( 'manage_' . Source_Local::CPT . '_posts_columns', [ $this, 'admin_columns_headers' ] ); + add_action( 'manage_' . Source_Local::CPT . '_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + + add_action( 'manage_e-floating-buttons_posts_columns', [ $this, 'admin_columns_headers' ] ); + add_action( 'manage_e-floating-buttons_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + } + + public function on_untrash_post( $post_id ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $document = $theme_builder_module->get_document( $post_id ); + + if ( $document ) { + $conditions = $document->get_meta( '_elementor_conditions' ); + + if ( $conditions ) { + $this->cache->add( $document, $conditions )->save(); + } + } + } + + public function admin_columns_headers( $posts_columns ) { + $offset = 3; + + $posts_columns = array_slice( $posts_columns, 0, $offset, true ) + [ + 'instances' => esc_html__( 'Instances', 'elementor-pro' ), + ] + array_slice( $posts_columns, $offset, null, true ); + + return $posts_columns; + } + + public function admin_columns_content( $column_name, $post_id ) { + if ( 'instances' !== $column_name ) { + return; + } + + $instances = $this->get_document_instances( $post_id ); + + if ( ! empty( $instances ) ) { + echo wp_kses_post( implode( '
      ', $instances ) ); + } else { + echo esc_html__( 'None', 'elementor-pro' ); + } + } + + /** + * @access public + * + * @param Ajax $ajax_manager + */ + public function register_ajax_actions( $ajax_manager ) { + $ajax_manager->register_ajax_action( 'pro_theme_builder_save_conditions', [ $this, 'ajax_save_theme_template_conditions' ] ); + $ajax_manager->register_ajax_action( 'pro_theme_builder_conditions_check_conflicts', [ $this, 'ajax_check_conditions_conflicts' ] ); + } + + /** + * @throws \Exception + */ + public function ajax_check_conditions_conflicts( $request ) { + $document = Utils::_unstable_get_document_for_edit( $request['editor_post_id'] ); + + $condition = $request['condition']; + + unset( $condition['_id'] ); + + $condition = rtrim( implode( '/', $condition ), '/' ); + + $conflicted = array_map( function ( $conflict ) { + return sprintf( + '%s', $conflict['edit_url'], $conflict['template_title'] + ); + }, $this->get_conditions_conflicts( $document->get_main_id(), $condition ) ); + + if ( empty( $conflicted ) ) { + return ''; + } + + return sprintf( + /* translators: %s: a list of conflicted templates */ + esc_html__( 'We noticed that you already applied %s with the same condition.', 'elementor-pro' ), + implode( ', ', $conflicted ) + ) . '
      ' . esc_html__( "To continue, set different conditions for each so they don't conflict.", 'elementor-pro' ); + } + + public function get_conditions_conflicts_by_location( $condition, $location, $ignore_post_id = null ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $location_settings = $theme_builder_module->get_locations_manager()->get_location( $location ); + + if ( ! empty( $location_settings['multiple'] ) ) { + return []; + } + + $conditions_groups = $this->cache->get_by_location( $location ); + + $conflicted = []; + + if ( ! empty( $conditions_groups ) ) { + foreach ( $conditions_groups as $template_id => $conditions ) { + if ( ! get_post( $template_id ) ) { + $this->purge_post_from_cache( $template_id ); + continue; + } + + if ( $ignore_post_id === $template_id ) { + continue; + } + + if ( false !== array_search( $condition, $conditions, true ) ) { + $template_title = esc_html( get_the_title( $template_id ) ); + $document = $theme_builder_module->get_document( $template_id ); + + if ( ! $document instanceof Theme_Document ) { + Plugin::$instance->logger->get_logger()->error( "Error fetching document in conditions manager. Template: $template_title" ); + } + + $edit_url = isset( $document ) ? $document->get_edit_url() : ''; + + $conflicted[] = [ + 'template_id' => $template_id, + 'template_title' => $template_title, + 'edit_url' => $edit_url, + ]; + } + } + } + + return $conflicted; + } + + public function get_conditions_conflicts( $post_id, $condition ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $document = $theme_builder_module->get_document( $post_id ); + + return $this->get_conditions_conflicts_by_location( $condition, $document->get_location(), $post_id ); + } + + /** + * @throws \Exception + */ + public function ajax_save_theme_template_conditions( $request ) { + $document = Utils::_unstable_get_document_for_edit( $request['editor_post_id'] ); + + if ( ! isset( $request['conditions'] ) ) { + $request['conditions'] = []; + } + + $is_saved = $this->save_conditions( $document->get_main_id(), $request['conditions'] ); + + if ( ! $is_saved ) { + throw new \Exception( 'Error while saving conditions.', Exceptions::INTERNAL_SERVER_ERROR ); + } + } + + private function register_condition( $id, $args = [] ) { + if ( isset( $this->conditions[ $id ] ) ) { + return; + } + + $class_name = ucfirst( $id ); + $class_name = '\\ElementorPro\\Modules\\ThemeBuilder\\Conditions\\' . $class_name; + /** @var Condition_Base $condition */ + $condition = new $class_name( $args ); + $this->register_condition_instance( $condition ); + + foreach ( $condition->get_sub_conditions() as $key => $val ) { + if ( is_numeric( $key ) ) { + $id = $val; + $args = []; + } else { + $id = $key; + $args = $val; + } + $this->register_condition( $id, $args ); + } + } + + /** + * @param Condition_Base $instance + */ + public function register_condition_instance( $instance ) { + $this->conditions[ $instance->get_name() ] = $instance; + } + + /** + * @param $id + * + * @return Condition_Base|bool + */ + public function get_condition( $id ) { + return isset( $this->conditions[ $id ] ) ? $this->conditions[ $id ] : false; + } + + public function get_conditions_config() { + $config = []; + + foreach ( $this->conditions as $condition ) { + $config[ $condition->get_name() ] = $condition->get_config(); + } + + return $config; + } + + public function get_document_instances( $post_id ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $document = $theme_builder_module->get_document( $post_id ); + + $summary = []; + + if ( ! $document ) { + return $summary; + } + + $document_conditions = $this->get_document_conditions( $document ); + + if ( ! empty( $document_conditions ) ) { + foreach ( $document_conditions as $document_condition ) { + if ( 'exclude' === $document_condition['type'] ) { + continue; + } + + $condition_name = ! empty( $document_condition['sub_name'] ) ? $document_condition['sub_name'] : $document_condition['name']; + + $condition = $this->get_condition( $condition_name ); + if ( ! $condition ) { + continue; + } + + if ( ! empty( $document_condition['sub_id'] ) ) { + $instance_label = $condition->get_label() . " #{$document_condition['sub_id']}"; + } else { + $instance_label = $condition->get_all_label(); + } + + $summary[ $condition->get_name() ] = $instance_label; + } + } + + return $summary; + } + + public function register_conditions() { + $this->register_condition( 'general' ); + + /** + * Elementor theme conditions registration. + * + * Fires when a new theme condition is registered. This hook allows developers + * to register new theme conditions. + * + * @param Conditions_Manager $this An instance of conditions manager. + */ + do_action( 'elementor/theme/register_conditions', $this ); + } + + public function save_conditions( $post_id, $conditions ) { + $conditions_to_save = []; + + foreach ( $conditions as $condition ) { + unset( $condition['_id'] ); + $conditions_to_save[] = rtrim( implode( '/', $condition ), '/' ); + } + + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $document = $theme_builder_module->get_document( $post_id ); + + if ( ! $document ) { + return false; + } + + if ( empty( $conditions_to_save ) ) { + $is_saved = $document->delete_meta( '_elementor_conditions' ); + } else { + $is_saved = $document->update_meta( '_elementor_conditions', $conditions_to_save ); + } + + $this->cache->regenerate(); + + return $is_saved; + } + + public function get_location_templates( $location ) { + $conditions_priority = []; + + $conditions_groups = $this->cache->get_by_location( $location ); + + if ( empty( $conditions_groups ) ) { + return $conditions_priority; + } + + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $location_manager = $theme_builder_module->get_locations_manager(); + $excludes = []; + + foreach ( $conditions_groups as $theme_template_id => $conditions ) { + /** + * Template ID for theme location templates. + * + * Filters the template ID for theme location templates. + * + * @param int $theme_template_id Template ID. + * @param string $location Theme location. + */ + $theme_template_id = apply_filters( 'elementor/theme/get_location_templates/template_id', $theme_template_id, $location ); + + foreach ( $conditions as $condition ) { + $parsed_condition = $this->parse_condition( $condition ); + + $include = $parsed_condition['type']; + $name = $parsed_condition['name']; + $sub_name = $parsed_condition['sub_name']; + $sub_id = $parsed_condition['sub_id']; + + $is_include = 'include' === $include; + $condition_instance = $this->get_condition( $name ); + + if ( ! $condition_instance ) { + continue; + } + + $condition_pass = $condition_instance->check( [] ); + $sub_condition_instance = null; + + if ( $condition_pass && $sub_name ) { + $sub_condition_instance = $this->get_condition( $sub_name ); + if ( ! $sub_condition_instance ) { + continue; + } + + $args = [ + 'id' => apply_filters( 'elementor/theme/get_location_templates/condition_sub_id', $sub_id, $parsed_condition ), + ]; + + $condition_pass = $sub_condition_instance->check( $args ); + } + + if ( $condition_pass ) { + + $post_status = get_post_status( $theme_template_id ); + + if ( 'publish' !== $post_status ) { + $location_manager->inspector_log( [ + 'location' => $location, + 'document' => $theme_builder_module->get_document( $theme_template_id ), + 'description' => 'Skipped, is not Published', + ] ); + continue; + } + + if ( $is_include ) { + $conditions_priority[ $theme_template_id ] = $this->get_condition_priority( $condition_instance, $sub_condition_instance, $sub_id ); + } else { + $excludes[] = $theme_template_id; + } + } + } // End foreach(). + } // End foreach(). + + foreach ( $excludes as $exclude_id ) { + unset( $conditions_priority[ $exclude_id ] ); + } + + asort( $conditions_priority ); + + return $conditions_priority; + } + + public function get_theme_templates_ids( $location ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $location_manager = $theme_builder_module->get_locations_manager(); + + // In case the user want to preview any page with a theme_template_id, + // like http://domain.com/any-post/?preview=1&theme_template_id=6453 + $force_template_id = Utils::_unstable_get_super_global_value( $_GET, 'theme_template_id' ); + if ( $force_template_id ) { + $document = $theme_builder_module->get_document( $force_template_id ); + // e.g. header / header + if ( $document && $location === $document->get_location() ) { + $location_manager->inspector_log( [ + 'location' => $location, + 'document' => $document, + 'description' => 'Force Template by URL param', + ] ); + + return [ + $force_template_id => 1, + ]; + } + } + + $current_post_id = get_the_ID(); + $document = $theme_builder_module->get_document( $current_post_id ); + if ( $document && $location === $document->get_location() ) { + $location_manager->inspector_log( [ + 'location' => $location, + 'document' => $document, + 'description' => 'Current Edited Template', + ] ); + + return [ + $current_post_id => 1, + ]; + } + + $templates = $this->get_location_templates( $location ); + + return $templates; + } + + /** + * @param Condition_Base $condition_instance + * @param Condition_Base $sub_condition_instance + * @param int $sub_id + * + * @return mixed + * @throws \Exception + */ + private function get_condition_priority( $condition_instance, $sub_condition_instance, $sub_id ) { + $priority = $condition_instance::get_priority(); + + if ( $sub_condition_instance ) { + if ( $sub_condition_instance::get_priority() < $priority ) { + $priority = $sub_condition_instance::get_priority(); + } + + $priority -= 10; + + if ( $sub_id ) { + $priority -= 10; + } elseif ( 0 === count( $sub_condition_instance->get_sub_conditions() ) ) { + // if no sub conditions - it's more specific. + $priority -= 5; + } + } + + return $priority; + } + + /** + * @param Theme_Document $document + * + * @return array + */ + public function get_document_conditions( $document ) { + $saved_conditions = $document->get_main_meta( '_elementor_conditions' ); + $conditions = []; + + if ( is_array( $saved_conditions ) ) { + foreach ( $saved_conditions as $condition ) { + $conditions[] = $this->parse_condition( $condition ); + } + } + + return $conditions; + } + + protected function parse_condition( $condition ) { + list ( $type, $name, $sub_name, $sub_id ) = array_pad( explode( '/', $condition ), 4, '' ); + + return compact( 'type', 'name', 'sub_name', 'sub_id' ); + } + + /** + * @param $location + * + * @return Theme_Document[] + */ + public function get_documents_for_location( $location ) { + if ( isset( $this->location_cache[ $location ] ) ) { + return $this->location_cache[ $location ]; + } + + $theme_templates_ids = $this->get_theme_templates_ids( $location ); + + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $location_settings = $theme_builder_module->get_locations_manager()->get_location( $location ); + + $documents = []; + + foreach ( $theme_templates_ids as $theme_template_id => $priority ) { + $document = $theme_builder_module->get_document( $theme_template_id ); + if ( $document ) { + $documents[ $theme_template_id ] = $document; + } + + if ( empty( $location_settings['multiple'] ) ) { + break; + } + } + + $this->location_cache[ $location ] = $documents; + + return $documents; + } + + public function purge_post_from_cache( $post_id ) { + return $this->cache->remove( $post_id )->save(); + } + + public function get_cache() { + return $this->cache; + } + + public function clear_cache() { + $this->cache->clear(); + } + + public function clear_location_cache() { + $this->location_cache = []; + } +} diff --git a/modules/theme-builder/classes/conditions-repeater.php b/modules/theme-builder/classes/conditions-repeater.php new file mode 100644 index 00000000..1211abdf --- /dev/null +++ b/modules/theme-builder/classes/conditions-repeater.php @@ -0,0 +1,78 @@ + 'none', + 'fields' => [ + [ + 'name' => 'type', + 'type' => Controls_Manager::SELECT, + 'default' => 'include', + 'options' => [ + 'include' => esc_html__( 'Include', 'elementor-pro' ), + 'exclude' => esc_html__( 'Exclude', 'elementor-pro' ), + ], + ], + [ + 'name' => 'name', + 'type' => Controls_Manager::SELECT, + 'default' => 'general', + 'groups' => [ + [ + 'label' => esc_html__( 'General', 'elementor-pro' ), + 'options' => [], + ], + ], + ], + [ + 'name' => 'sub_name', + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'All', 'elementor-pro' ), + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + [ + 'name' => 'sub_id', + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'All', 'elementor-pro' ), + ], + 'conditions' => [ + 'terms' => [ + [ + 'name' => 'sub_name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] ); + } +} diff --git a/modules/theme-builder/classes/control-media-preview.php b/modules/theme-builder/classes/control-media-preview.php new file mode 100644 index 00000000..43e289f9 --- /dev/null +++ b/modules/theme-builder/classes/control-media-preview.php @@ -0,0 +1,35 @@ + +
      + +
      +
      +
      +
      +
      + <# if ( data.description ) { #> +
      {{{ data.description }}}
      + <# } #> + +
      + set_core_locations(); + + add_filter( 'the_content', [ $this, 'builder_wrapper' ], 9999999 ); // 9999999 = after preview->builder_wrapper + add_filter( 'template_include', [ $this, 'template_include' ], 11 ); // 11 = after WooCommerce. + add_action( 'template_redirect', [ $this, 'register_locations' ] ); + + add_filter( 'elementor/admin/create_new_post/meta', [ $this, 'filter_add_location_meta_on_create_new_post' ] ); + + if ( ! Module::is_preview() ) { + add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_styles' ] ); + } + + add_filter( 'pre_handle_404', [ $this, 'should_allow_pagination_on_single_templates' ], 10, 2 ); + add_filter( 'pre_handle_404', [ $this, 'should_allow_pagination_on_archive_templates' ], 11, 2 ); + } + + /** + * Fix WP 5.5 pagination issue. + * + * Return true to mark that it's handled and avoid WP to set it as 404. + * + * @see https://github.com/elementor/elementor/issues/12126 + * @see https://core.trac.wordpress.org/ticket/50976 + * + * Based on the logic at \WP::handle_404. + * + * @param $handled - Default false. + * @param $wp_query + * + * @return bool + */ + public function should_allow_pagination_on_single_templates( $handled, $wp_query ) { + if ( $handled || empty( $wp_query->query_vars['page'] ) || empty( $wp_query->post ) ) { + return $handled; + } + + $current_post_id = get_the_ID(); + $documents = Module::instance()->get_conditions_manager()->get_documents_for_location( 'single' ); + + if ( empty( $documents ) ) { + return $handled; + } + + foreach ( $documents as $document ) { + $post_id = $document->get_post()->ID; + + // Will be handled by the pre_handle_404 filter in the posts module. + if ( $current_post_id === $post_id ) { + continue; + } + + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( $this->is_valid_pagination( $document->get_elements_data(), $wp_query->query_vars['page'] ) ) { + $handled = true; + } + } + + return $handled; + } + + /** + * Fix WP 5.5 pagination issue. + * + * Return true to mark that it's handled and avoid WP to set it as 404. + * + * @see https://github.com/elementor/elementor/issues/12126 + * @see https://core.trac.wordpress.org/ticket/50976 + * + * Based on the logic at \WP::handle_404. + * + * @param $handled - Default false. + * @param $wp_query + * + * @return bool + */ + public function should_allow_pagination_on_archive_templates( $handled, $wp_query ) { + $is_archive = is_archive() || is_home() || is_search(); + + if ( $handled || ! $is_archive ) { + return $handled; + } + + $current_post_id = $wp_query->query['page_id'] ?? ( $wp_query->queried_object->ID ?? null ); + $documents = Module::instance()->get_conditions_manager()->get_documents_for_location( 'archive' ); + + if ( empty( $documents ) ) { + return $handled; + } + + foreach ( $documents as $document ) { + $post_id = $document->get_post()->ID; + + // Will be handled by the pre_handle_404 filter in the posts module. + if ( $current_post_id === $post_id ) { + continue; + } + + $document = Plugin::elementor()->documents->get( $post_id ); + $current_page = max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) ); + + if ( $this->is_valid_pagination( $document->get_elements_data(), $current_page ) ) { + $handled = true; + } + } + + return $handled; + } + + public function register_locations() { + // Run Once. + if ( ! did_action( 'elementor/theme/register_locations' ) ) { + /** + * Elementor theme locations registration. + * + * Fires after template files where included but before locations have + * been registered. This hook allows theme developers to register new + * theme locations. + * + * @since 2.0.0 + * + * @param Locations_Manager $this An instance of locations manager. + */ + do_action( 'elementor/theme/register_locations', $this ); + } + } + + public function enqueue_styles() { + $locations = $this->get_locations(); + + if ( empty( $locations ) ) { + return; + } + + if ( ! empty( $this->current_page_template ) ) { + $locations = $this->filter_page_template_locations( $locations ); + } + + $current_post_id = get_the_ID(); + + /** @var Post_CSS[] $css_files */ + $css_files = []; + + foreach ( $locations as $location => $settings ) { + $documents = Module::instance()->get_conditions_manager()->get_documents_for_location( $location ); + foreach ( $documents as $document ) { + $post_id = $document->get_post()->ID; + + // Don't enqueue current post here (let the preview/frontend components to handle it) + if ( $current_post_id !== $post_id ) { + do_action( 'elementor/post/render', $post_id ); + + $css_file = new Post_CSS( $post_id ); + $css_files[] = $css_file; + + $this->handle_page_assets( $post_id, $document ); + } + } + } + + if ( ! empty( $css_files ) ) { + // Enqueue the frontend styles manually also for pages that don't built with Elementor. + Plugin::elementor()->frontend->enqueue_styles(); + + // Enqueue after the frontend styles to override them. + foreach ( $css_files as $css_file ) { + $css_file->enqueue(); + } + } + } + + /** + * @param int $post_id + * @param Theme_Document $document + * + * @return void + */ + private function handle_page_assets( $post_id, $document ): void { + $page_assets = get_post_meta( $post_id, Assets::ASSETS_META_KEY, true ); + if ( ! empty( $page_assets ) ) { + Plugin::elementor()->assets_loader->enable_assets( $page_assets ); + return; + } + + if ( ! method_exists( $document, 'update_runtime_elements' ) ) { + return; + } + + $document->update_runtime_elements(); + } + + public function template_include( $template ) { + $location = ''; + + if ( is_singular() ) { + $document = Plugin::elementor()->documents->get_doc_for_frontend( get_the_ID() ); + if ( $document && $document::get_property( 'support_wp_page_templates' ) ) { + $wp_page_template = $document->get_meta( '_wp_page_template' ); + if ( $wp_page_template && 'default' !== $wp_page_template ) { + $this->inspector_log( [ + 'template' => $template, + 'description' => 'Template File: WP Page Template', + ] ); + $this->current_page_template = $wp_page_template; + return $template; + } + } + } else { + $document = false; + } + + if ( $document && $document instanceof Theme_Document ) { + // For editor preview iframe. + $location = $document->get_location(); + } elseif ( function_exists( 'is_shop' ) && is_shop() ) { + $location = 'archive'; + } elseif ( is_archive() || is_tax() || is_home() || is_search() ) { + $location = 'archive'; + } elseif ( is_singular() || is_404() ) { + $location = 'single'; + } + + if ( $location ) { + $location_settings = $this->get_location( $location ); + $location_documents = Module::instance()->get_conditions_manager()->get_documents_for_location( $location ); + if ( empty( $location_documents ) ) { + $this->inspector_log( [ + 'template' => $template, + 'description' => 'Template File: No Templates for condition', + ] ); + + return $template; + } + + if ( 'single' === $location || 'archive' === $location ) { + $first_key = key( $location_documents ); + $theme_document = $location_documents[ $first_key ]; + + if ( Module::is_preview() && $theme_document->get_autosave_id() ) { + $theme_document = $theme_document->get_autosave(); + } + + $document_page_template = $theme_document->get_settings( 'page_template' ); + if ( $document_page_template ) { + $page_template = $document_page_template; + $this->inspector_log( [ + 'document' => $theme_document, + 'template' => $template, + 'description' => 'Template File: Document Page Template', + ] ); + } + } + } + + /** + * @var \Elementor\Modules\PageTemplates\Module $page_templates_module + */ + $page_templates_module = Plugin::elementor()->modules_manager->get_modules( 'page-templates' ); + + // If is a `content` document or the theme is not support the document location (top header/ sidebar and etc.). + $location_exist = ! empty( $location_settings ); + $is_header_footer = 'header' === $location || 'footer' === $location; + $need_override_location = ! empty( $location_settings['overwrite'] ) && ! $is_header_footer; + + /** + * Override theme location. + * + * Filters the ability to override any Elementor theme location. + * + * @param bool $need_override_location Whether to override theme location. + * @param string $location Location name. + * @param Locations_Manager $this An instance of location manager. + */ + $need_override_location = apply_filters( 'elementor/theme/need_override_location', $need_override_location, $location, $this ); + + if ( $location && empty( $page_template ) && ( ! $location_exist || $need_override_location ) ) { + $page_template = $page_templates_module::TEMPLATE_HEADER_FOOTER; + } + + if ( ! empty( $page_template ) ) { + $template_path = $page_templates_module->get_template_path( $page_template ); + + if ( $template_path ) { + $page_templates_module->set_print_callback( function() use ( $location ) { + Module::instance()->get_locations_manager()->do_location( $location ); + } ); + + $this->inspector_log( [ + 'location' => $location, + 'template' => $template_path, + 'description' => $location_exist ? 'Template File: Location Settings (Override)' : 'Template File: Location not exit', + ] ); + + $template = $template_path; + } + } + + return $template; + } + + /** + * @param string $location + * @param integer $document_id + */ + public function add_doc_to_location( $location, $document_id ) { + if ( isset( $this->locations_skipped[ $location ][ $document_id ] ) ) { + // Don't re-add skipped documents. + return; + } + + if ( ! isset( $this->locations_queue[ $location ] ) ) { + $this->locations_queue[ $location ] = []; + } + + $this->locations_queue[ $location ][ $document_id ] = $document_id; + } + + public function remove_doc_from_location( $location, $document_id ) { + unset( $this->locations_queue[ $location ][ $document_id ] ); + } + + public function skip_doc_in_location( $location, $document_id ) { + $this->remove_doc_from_location( $location, $document_id ); + + if ( ! isset( $this->locations_skipped[ $location ] ) ) { + $this->locations_skipped[ $location ] = []; + } + + $this->locations_skipped[ $location ][ $document_id ] = $document_id; + } + + public function is_printed( $location, $document_id ) { + return isset( $this->locations_printed[ $location ][ $document_id ] ); + } + + public function set_is_printed( $location, $document_id ) { + if ( ! isset( $this->locations_printed[ $location ] ) ) { + $this->locations_printed[ $location ] = []; + } + + $this->locations_printed[ $location ][ $document_id ] = $document_id; + $this->remove_doc_from_location( $location, $document_id ); + } + + public function do_location( $location ) { + /** @var Theme_Document[] $documents_by_conditions */ + $documents_by_conditions = Module::instance()->get_conditions_manager()->get_documents_for_location( $location ); + + foreach ( $documents_by_conditions as $document_id => $document ) { + $this->add_doc_to_location( $location, $document_id ); + } + + // Locations Queue can contain documents that added manually. + if ( empty( $this->locations_queue[ $location ] ) ) { + return false; + } + + if ( is_singular() ) { + Utils::set_global_authordata(); + } + + /** + * Before location content printed. + * + * Fires before Elementor theme location is printed. + * + * The dynamic portion of the hook name, `$location`, refers to the location name. + * + * @since 2.0.0 + * + * @param Locations_Manager $this An instance of locations manager. + */ + do_action( "elementor/theme/before_do_{$location}", $this ); + + while ( ! empty( $this->locations_queue[ $location ] ) ) { + $document_id = key( $this->locations_queue[ $location ] ); + $document = Module::instance()->get_document( $document_id ); + + if ( ! $document || $this->is_printed( $location, $document_id ) ) { + $this->skip_doc_in_location( $location, $document_id ); + continue; + } + + // `$documents_by_conditions` can pe current post even if it's a draft. + if ( empty( $documents_by_conditions[ $document_id ] ) ) { + + $post_status = get_post_status( $document_id ); + + if ( 'publish' !== $post_status ) { + $this->inspector_log( [ + 'location' => $location, + 'document' => $document, + 'description' => 'Added manually but skipped because is not Published', + ] ); + + $this->skip_doc_in_location( $location, $document_id ); + continue; + } + } + + $this->inspector_log( [ + 'location' => $location, + 'document' => $document, + 'description' => isset( $documents_by_conditions[ $document_id ] ) ? 'Added By Condition' : 'Added Manually', + + ] ); + + $this->current_location = $location; + $document->print_content(); + $this->did_locations[] = $this->current_location; + $this->current_location = null; + + $this->set_is_printed( $location, $document_id ); + } + + /** + * After location content printed. + * + * Fires after Elementor theme location is printed. + * + * The dynamic portion of the hook name, `$location`, refers to the location name. + * + * @since 2.0.0 + * + * @param Locations_Manager $this An instance of locations manager. + */ + do_action( "elementor/theme/after_do_{$location}", $this ); + + return true; + } + + + public function get_documents_for_location( string $location ) : array { + return $this->locations_queue[ $location ] ?? []; + } + + public function did_location( $location ) { + return in_array( $location, $this->did_locations, true ); + } + + public function get_current_location() { + return $this->current_location; + } + + public function builder_wrapper( $content ) { + $post_id = get_the_ID(); + + if ( $post_id ) { + $document = Module::instance()->get_document( $post_id ); + if ( $document ) { + $document_location = $document->get_location(); + $location_settings = $this->get_location( $document_location ); + // If is a `content` document or the theme is not support the document location (header/footer and etc.). + if ( $location_settings && ! $location_settings['edit_in_content'] ) { + $content = '
      ' . esc_html__( 'Content area', 'elementor-pro' ) . '
      '; + } + } + } + + return $content; + } + + public function get_locations( $filter_args = [] ) { + $this->register_locations(); + + if ( is_string( $filter_args ) ) { + _deprecated_argument( __FUNCTION__, '2.4.0', 'Passing a location name is deprecated. Use `get_location` instead.' ); + return $this->get_location( $filter_args ); + } + + return wp_list_filter( $this->locations, $filter_args ); + } + + public function get_location( $location ) { + $locations = $this->get_locations(); + + if ( isset( $locations[ $location ] ) ) { + $location_config = $locations[ $location ]; + } else { + $location_config = []; + } + + return $location_config; + } + + public function get_doc_location( $post_id ) { + /** @var Theme_Document $document */ + $document = Plugin::elementor()->documents->get( $post_id ); + + return $document->get_location(); + } + + public function get_core_locations() { + return $this->core_locations; + } + + public function register_all_core_location() { + foreach ( $this->core_locations as $location => $settings ) { + $this->register_location( $location, $settings ); + } + } + + public function register_location( $location, $args = [] ) { + $args = wp_parse_args( $args, [ + 'label' => $location, + 'multiple' => false, + 'public' => true, + 'edit_in_content' => true, + 'hook' => 'elementor/theme/' . $location, + ] ); + + $this->locations[ $location ] = $args; + + add_action( $args['hook'], function() use ( $location, $args ) { + $did_location = Module::instance()->get_locations_manager()->do_location( $location ); + + if ( $did_location && ! empty( $args['remove_hooks'] ) ) { + foreach ( $args['remove_hooks'] as $item ) { + remove_action( $args['hook'], $item ); + } + } + }, 5 ); + } + + public function register_core_location( $location, $args = [] ) { + if ( ! isset( $this->core_locations[ $location ] ) ) { + /* translators: %s: Location name. */ + wp_die( esc_html( sprintf( esc_html__( 'Location \'%s\' is not a core location.', 'elementor-pro' ), $location ) ) ); + } + + $args = array_replace_recursive( $this->core_locations[ $location ], $args ); + + $this->register_location( $location, $args ); + } + + public function location_exits( $location = '', $check_match = false ) { + $location_exits = ! ! $this->get_location( $location ); + + if ( $location_exits && $check_match ) { + $location_exits = ! ! Module::instance()->get_conditions_manager()->get_documents_for_location( $location ); + } + + return $location_exits; + } + + public function filter_add_location_meta_on_create_new_post( $meta ) { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here. + $meta_location = Utils::_unstable_get_super_global_value( $_GET, 'meta_location' ); + if ( $meta_location ) { + $meta[ Theme_Document::LOCATION_META_KEY ] = $meta_location; + } + + return $meta; + } + + private function set_core_locations() { + $this->core_locations = [ + 'header' => [ + 'is_core' => true, + 'public' => false, + 'label' => esc_html__( 'Header', 'elementor-pro' ), + 'edit_in_content' => false, + ], + 'footer' => [ + 'is_core' => true, + 'public' => false, + 'label' => esc_html__( 'Footer', 'elementor-pro' ), + 'edit_in_content' => false, + ], + 'archive' => [ + 'is_core' => true, + 'public' => false, + 'overwrite' => true, + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + 'edit_in_content' => true, + ], + 'single' => [ + 'is_core' => true, + 'public' => false, + 'label' => esc_html__( 'Single', 'elementor-pro' ), + 'edit_in_content' => true, + ], + ]; + } + + public function inspector_log( $args ) { + $inspector_enabled = method_exists( Plugin::elementor()->inspector, 'is_enabled' ) && Plugin::elementor()->inspector->is_enabled(); + if ( ! $inspector_enabled ) { + return; + } + + $title = []; + $url = ''; + + if ( isset( $args['location'] ) ) { + $location_settings = $this->get_location( $args['location'] ); + if ( $location_settings ) { + $args['location'] = $location_settings['label']; + } + $title[] = 'Location: ' . $args['location']; + } + + if ( isset( $args['description'] ) ) { + $title[] = $args['description']; + } + + if ( ! empty( $args['document'] ) ) { + $title[] = esc_html( $args['document']->get_post()->post_title ); + $url = $args['document']->get_edit_url(); + } + + if ( isset( $args['template'] ) ) { + $title[] = Plugin::elementor()->inspector->parse_template_path( $args['template'] ); + } + + $title = implode( ' > ', $title ); + + Plugin::elementor()->inspector->add_log( 'Theme', $title, $url ); + } + + private function filter_page_template_locations( array $locations ) { + $templates_to_filter = [ + PageTemplatesModule::TEMPLATE_CANVAS, + PageTemplatesModule::TEMPLATE_HEADER_FOOTER, + ]; + + if ( ! in_array( $this->current_page_template, $templates_to_filter, true ) ) { + return $locations; + } + + if ( PageTemplatesModule::TEMPLATE_CANVAS === $this->current_page_template ) { + $allowed_core = []; + } else { + $allowed_core = [ 'header', 'footer' ]; + } + + foreach ( $locations as $location => $settings ) { + if ( ! empty( $settings['is_core'] ) && ! in_array( $location, $allowed_core, true ) ) { + unset( $locations[ $location ] ); + } + } + + return $locations; + } +} diff --git a/modules/theme-builder/classes/preview-manager.php b/modules/theme-builder/classes/preview-manager.php new file mode 100644 index 00000000..35168279 --- /dev/null +++ b/modules/theme-builder/classes/preview-manager.php @@ -0,0 +1,78 @@ +get_document( $current_post_id ); + + if ( $document ) { + // Show all taxonomies + unset( $taxonomy_args['object_type'] ); + } + + return $taxonomy_args; + } + + /** + * @access public + * + * @param $query_vars array + * + * @return array + */ + public function filter_query_control_args( $query_vars ) { + $document = Plugin::elementor()->documents->get_doc_or_auto_save( get_the_ID() ); + + if ( $document && $document instanceof Theme_Document ) { + $query_vars = $document->get_preview_as_query_args(); + } + + return $query_vars; + } + + /** + * @access public + */ + public function switch_to_preview_query() { + $current_post_id = get_the_ID(); + $document = Plugin::elementor()->documents->get_doc_or_auto_save( $current_post_id ); + + if ( ! $document || ! $document instanceof Theme_Document ) { + return; + } + + $new_query_vars = $document->get_preview_as_query_args(); + + Plugin::elementor()->db->switch_to_query( $new_query_vars, true ); + + $document->after_preview_switch_to_query(); + } + + /** + * @access public + */ + public function restore_current_query() { + Plugin::elementor()->db->restore_current_query(); + } +} diff --git a/modules/theme-builder/classes/template-conditions.php b/modules/theme-builder/classes/template-conditions.php new file mode 100644 index 00000000..21a8f044 --- /dev/null +++ b/modules/theme-builder/classes/template-conditions.php @@ -0,0 +1,27 @@ +add_control( + 'conditions', + [ + 'section' => 'settings', + 'type' => Conditions_Repeater::CONTROL_TYPE, + ] + ); + } +} diff --git a/modules/theme-builder/classes/templates-types-manager.php b/modules/theme-builder/classes/templates-types-manager.php new file mode 100644 index 00000000..557518e4 --- /dev/null +++ b/modules/theme-builder/classes/templates-types-manager.php @@ -0,0 +1,51 @@ +documents->get_document_types( $args ); + + foreach ( $document_types as $type => $document_type ) { + $properties = $document_type::get_properties(); + + if ( ( new $document_type() ) instanceof Documents\Theme_Document ) { + $config[ $type ] = $properties; + } + } + + return $config; + } + + public function register_documents() { + $this->docs_types = [ + 'section' => Documents\Section::get_class_full_name(), + 'header' => Documents\Header::get_class_full_name(), + 'footer' => Documents\Footer::get_class_full_name(), + 'single' => Documents\Single::get_class_full_name(), + 'single-post' => Documents\Single_Post::get_class_full_name(), + 'single-page' => Documents\Single_Page::get_class_full_name(), + 'archive' => Documents\Archive::get_class_full_name(), + 'search-results' => Documents\Search_Results::get_class_full_name(), + 'error-404' => Documents\Error_404::get_class_full_name(), + ]; + + foreach ( $this->docs_types as $type => $class_name ) { + Plugin::elementor()->documents->register_document_type( $type, $class_name ); + } + } +} diff --git a/modules/theme-builder/classes/theme-support.php b/modules/theme-builder/classes/theme-support.php new file mode 100644 index 00000000..1ca79b3b --- /dev/null +++ b/modules/theme-builder/classes/theme-support.php @@ -0,0 +1,130 @@ +get_template() ) { + case 'generatepress': + new GeneratePress_Theme_Support(); + break; + case 'elementor-safe': + new Safe_Mode_Theme_Support(); + break; + } + + add_action( 'elementor/theme/register_locations', [ $this, 'after_register_locations' ], 99 ); + } + + /** + * @param Locations_Manager $location_manager + */ + public function after_register_locations( $location_manager ) { + $core_locations = $location_manager->get_core_locations(); + $overwrite_header_location = false; + $overwrite_footer_location = false; + + foreach ( $core_locations as $location => $settings ) { + if ( ! $location_manager->get_location( $location ) ) { + if ( 'header' === $location ) { + $overwrite_header_location = true; + } elseif ( 'footer' === $location ) { + $overwrite_footer_location = true; + } + $location_manager->register_core_location( $location, [ + 'overwrite' => true, + ] ); + } + } + + if ( $overwrite_header_location || $overwrite_footer_location ) { + /** @var Module $theme_builder_module */ + $theme_builder_module = Module::instance(); + + $conditions_manager = $theme_builder_module->get_conditions_manager(); + + $headers = $conditions_manager->get_documents_for_location( 'header' ); + $footers = $conditions_manager->get_documents_for_location( 'footer' ); + + if ( ! empty( $headers ) || ! empty( $footers ) ) { + add_action( 'get_header', [ $this, 'get_header' ] ); + add_action( 'get_footer', [ $this, 'get_footer' ] ); + add_filter( 'show_admin_bar', [ $this, 'filter_admin_bar_from_body_open' ] ); + } + } + } + + public function get_header( $name ) { + require __DIR__ . '/../views/theme-support-header.php'; + + $templates = []; + $name = (string) $name; + if ( '' !== $name ) { + $templates[] = "header-{$name}.php"; + } + + $templates[] = 'header.php'; + + // Avoid running wp_head hooks again + remove_all_actions( 'wp_head' ); + ob_start(); + // It cause a `require_once` so, in the get_header it self it will not be required again. + locate_template( $templates, true ); + ob_get_clean(); + } + + /** + * Don't show admin bar on `wp_body_open` because the theme header HTML is ignored via `$this->get_header()`. + * + * @param bool $show_admin_bar + * + * @return bool + */ + public function filter_admin_bar_from_body_open( $show_admin_bar ) { + global $wp_current_filter; + + // A flag to mark if $show_admin_bar is switched to false during this filter, + // if so, it needed to switch back on the next filter (wp_footer). + static $switched = false; + + if ( $show_admin_bar && in_array( 'wp_body_open', $wp_current_filter ) ) { + $show_admin_bar = false; + $switched = true; + } elseif ( $switched ) { + $show_admin_bar = true; + } + + return $show_admin_bar; + } + + public function get_footer( $name ) { + require __DIR__ . '/../views/theme-support-footer.php'; + + $templates = []; + $name = (string) $name; + if ( '' !== $name ) { + $templates[] = "footer-{$name}.php"; + } + + $templates[] = 'footer.php'; + + ob_start(); + // It cause a `require_once` so, in the get_header it self it will not be required again. + locate_template( $templates, true ); + ob_get_clean(); + } +} diff --git a/modules/theme-builder/conditions/any-child-of-term.php b/modules/theme-builder/conditions/any-child-of-term.php new file mode 100644 index 00000000..47e4db69 --- /dev/null +++ b/modules/theme-builder/conditions/any-child-of-term.php @@ -0,0 +1,46 @@ +taxonomy->name; + } + + public function get_label() { + /* translators: %s: Singular taxonomy label. */ + return sprintf( esc_html__( 'Any child %s of', 'elementor-pro' ), $this->taxonomy->labels->singular_name ); + } + + public function __construct( $data ) { + parent::__construct( $data ); + + $this->taxonomy = $data['object']; + } + + public function check( $args ) { + $id = (int) $args['id']; + /** + * @var \WP_Term $current + */ + $current = get_queried_object(); + if ( ! $this->is_term() || 0 === $current->parent ) { + return false; + } + + while ( $current->parent > 0 ) { + if ( $id === $current->parent ) { + return true; + } + $current = get_term_by( 'id', $current->parent, $current->taxonomy ); + } + + return $id === $current->parent; + } +} diff --git a/modules/theme-builder/conditions/any-child-of.php b/modules/theme-builder/conditions/any-child-of.php new file mode 100644 index 00000000..bb1ca2e5 --- /dev/null +++ b/modules/theme-builder/conditions/any-child-of.php @@ -0,0 +1,28 @@ + $label ) { + if ( ! get_post_type_archive_link( $post_type ) ) { + continue; + } + + $condition = new Post_Type_Archive( [ + 'post_type' => $post_type, + ] ); + + $this->register_sub_condition( $condition ); + } + } + + public function check( $args ) { + $is_archive = is_archive() || is_home() || is_search(); + + // WooCommerce is handled by `woocommerce` module. + if ( $is_archive && class_exists( 'woocommerce' ) && is_woocommerce() ) { + $is_archive = false; + } + + return $is_archive; + } +} diff --git a/modules/theme-builder/conditions/author.php b/modules/theme-builder/conditions/author.php new file mode 100644 index 00000000..518c3e7d --- /dev/null +++ b/modules/theme-builder/conditions/author.php @@ -0,0 +1,47 @@ +add_control( + 'author_id', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_AUTHOR, + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/by-author.php b/modules/theme-builder/conditions/by-author.php new file mode 100644 index 00000000..8dfad1fa --- /dev/null +++ b/modules/theme-builder/conditions/by-author.php @@ -0,0 +1,47 @@ +add_control( + 'author_id', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_AUTHOR, + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/child-of-term.php b/modules/theme-builder/conditions/child-of-term.php new file mode 100644 index 00000000..25f006dd --- /dev/null +++ b/modules/theme-builder/conditions/child-of-term.php @@ -0,0 +1,39 @@ +taxonomy->name; + } + + public function get_label() { + /* translators: %s: Singular taxonomy label. */ + return sprintf( esc_html__( 'Direct child %s of', 'elementor-pro' ), $this->taxonomy->labels->singular_name ); + } + + public function __construct( $data ) { + parent::__construct( $data ); + + $this->taxonomy = $data['object']; + } + + public function is_term() { + $taxonomy = $this->taxonomy->name; + $current = get_queried_object(); + return ( $current && isset( $current->taxonomy ) && $taxonomy === $current->taxonomy ); + } + + public function check( $args ) { + $id = (int) $args['id']; + $current = get_queried_object(); + + return $this->is_term() && $id === $current->parent; + } +} diff --git a/modules/theme-builder/conditions/child-of.php b/modules/theme-builder/conditions/child-of.php new file mode 100644 index 00000000..cc096a53 --- /dev/null +++ b/modules/theme-builder/conditions/child-of.php @@ -0,0 +1,62 @@ + true, + 'public' => true, + ] ); + + $this->add_control( + 'parent_id', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => array_keys( $hierarchical_post_types ), + ], + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/condition-base.php b/modules/theme-builder/conditions/condition-base.php new file mode 100644 index 00000000..1622422e --- /dev/null +++ b/modules/theme-builder/conditions/condition-base.php @@ -0,0 +1,68 @@ +get_name(); + } + + public static function get_type() { + throw new \Exception( 'Please overwrite the method.', Exceptions::INTERNAL_SERVER_ERROR ); + } + + public function check( $args ) { + return false; + } + + public function get_sub_conditions() { + return $this->sub_conditions; + } + + public function get_all_label() { + return $this->get_label(); + } + + protected function get_initial_config() { + $config = parent::get_initial_config(); + + $config['label'] = $this->get_label(); + $config['sub_conditions'] = $this->get_sub_conditions(); + $config['all_label'] = $this->get_all_label(); + + return $config; + } + + public function register_sub_conditions() {} + + /** + * @param self $condition + */ + public function register_sub_condition( $condition ) { + $conditions_manager = Module::instance()->get_conditions_manager(); + $conditions_manager->register_condition_instance( $condition ); + $this->sub_conditions[] = $condition->get_name(); + } + + public function __construct( array $data = [] ) { + parent::__construct( $data ); + + $this->register_sub_conditions(); + } +} diff --git a/modules/theme-builder/conditions/date.php b/modules/theme-builder/conditions/date.php new file mode 100644 index 00000000..ff7afab8 --- /dev/null +++ b/modules/theme-builder/conditions/date.php @@ -0,0 +1,29 @@ +taxonomy = $data['object']; + } + + public function get_name() { + return 'in_' . $this->taxonomy->name . '_children'; + } + + public function get_label() { + /* translators: %s: Taxonomy label. */ + return sprintf( esc_html__( 'In child %s', 'elementor-pro' ), $this->taxonomy->labels->name ); + } + + public function check( $args ) { + $id = (int) $args['id']; + if ( ! is_singular() || ! $id ) { + return false; + } + $child_terms = get_term_children( $id, $this->taxonomy->name ); + + return ! empty( $child_terms ) && has_term( $child_terms, $this->taxonomy->name ); + } +} diff --git a/modules/theme-builder/conditions/in-taxonomy.php b/modules/theme-builder/conditions/in-taxonomy.php new file mode 100644 index 00000000..54a50bba --- /dev/null +++ b/modules/theme-builder/conditions/in-taxonomy.php @@ -0,0 +1,65 @@ +taxonomy = $data['object']; + } + + public function get_name() { + return 'in_' . $this->taxonomy->name; + } + + public function get_label() { + /* translators: %s: Taxonomy label. */ + return sprintf( esc_html__( 'In %s', 'elementor-pro' ), $this->taxonomy->labels->singular_name ); + } + + public function check( $args ) { + return is_singular() && has_term( (int) $args['id'], $this->taxonomy->name ); + } + + protected function register_controls() { + $this->add_control( + 'taxonomy', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_TAX, + 'display' => 'detailed', + 'by_field' => 'term_id', + 'query' => [ + 'taxonomy' => $this->taxonomy->name, + ], + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/not-found404.php b/modules/theme-builder/conditions/not-found404.php new file mode 100644 index 00000000..085dd7ce --- /dev/null +++ b/modules/theme-builder/conditions/not-found404.php @@ -0,0 +1,29 @@ +post_type = get_post_type_object( $data['post_type'] ); + $taxonomies = get_object_taxonomies( $data['post_type'], 'objects' ); + $this->post_taxonomies = wp_filter_object_list( $taxonomies, [ + 'public' => true, + 'show_in_nav_menus' => true, + ] ); + + parent::__construct(); + } + + public function get_name() { + return $this->post_type->name . '_archive'; + } + + public function get_label() { + /* translators: %s: Post type label. */ + return sprintf( esc_html__( '%s archive', 'elementor-pro' ), $this->post_type->label ); + } + + public function get_all_label() { + /* translators: %s: Post type label. */ + return sprintf( esc_html__( '%s archive', 'elementor-pro' ), $this->post_type->label ); + } + + public function register_sub_conditions() { + foreach ( $this->post_taxonomies as $slug => $object ) { + $condition = new Taxonomy( [ + 'object' => $object, + ] ); + + $this->register_sub_condition( $condition ); + + if ( ! $object->hierarchical ) { + continue; + } + + $sub_conditions = [ + 'Child_Of_Term', + 'Any_Child_Of_Term', + ]; + + foreach ( $sub_conditions as $class_name ) { + $full_class_name = __NAMESPACE__ . '\\' . $class_name; + $this->register_sub_condition( new $full_class_name( [ 'object' => $object ] ) ); + } + } + } + + public function check( $args ) { + return is_post_type_archive( $this->post_type->name ) || ( 'post' === $this->post_type->name && is_home() ); + } +} diff --git a/modules/theme-builder/conditions/post-type-by-author.php b/modules/theme-builder/conditions/post-type-by-author.php new file mode 100644 index 00000000..cebe755b --- /dev/null +++ b/modules/theme-builder/conditions/post-type-by-author.php @@ -0,0 +1,56 @@ +post_type = $post_type; + } + + public function get_name() { + return $this->post_type->name . '_by_author'; + } + + public function get_label() { + /* translators: %s: Post type label. */ + return sprintf( esc_html__( '%s by author', 'elementor-pro' ), $this->post_type->label ); + } + + public function check( $args = null ) { + return is_singular( $this->post_type->name ) && get_post_field( 'post_author' ) === $args['id']; + } + + protected function register_controls() { + $this->add_control( + 'author_id', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_AUTHOR, + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/post.php b/modules/theme-builder/conditions/post.php new file mode 100644 index 00000000..4f95b7c9 --- /dev/null +++ b/modules/theme-builder/conditions/post.php @@ -0,0 +1,95 @@ +post_type = get_post_type_object( $data['post_type'] ); + $taxonomies = get_object_taxonomies( $data['post_type'], 'objects' ); + $this->post_taxonomies = wp_filter_object_list( $taxonomies, [ + 'public' => true, + 'show_in_nav_menus' => true, + ] ); + + parent::__construct(); + } + + public function get_name() { + return $this->post_type->name; + } + + public function get_label() { + return $this->post_type->labels->singular_name; + } + + public function get_all_label() { + return $this->post_type->label; + } + + public function check( $args ) { + if ( isset( $args['id'] ) ) { + $id = (int) $args['id']; + if ( $id ) { + return is_singular() && get_queried_object_id() === $id; + } + } + + return is_singular( $this->post_type->name ); + } + + public function register_sub_conditions() { + foreach ( $this->post_taxonomies as $slug => $object ) { + $in_taxonomy = new In_Taxonomy( [ + 'object' => $object, + ] ); + $this->register_sub_condition( $in_taxonomy ); + + if ( $object->hierarchical ) { + $in_sub_term = new In_Sub_Term( [ + 'object' => $object, + ] ); + $this->register_sub_condition( $in_sub_term ); + } + } + + $by_author = new Post_Type_By_Author( $this->post_type ); + $this->register_sub_condition( $by_author ); + + } + + protected function register_controls() { + $this->add_control( + 'post_id', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'dropdownCssClass' => 'elementor-conditions-select2-dropdown', + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => $this->get_name(), + ], + ], + ] + ); + } +} diff --git a/modules/theme-builder/conditions/search.php b/modules/theme-builder/conditions/search.php new file mode 100644 index 00000000..659298da --- /dev/null +++ b/modules/theme-builder/conditions/search.php @@ -0,0 +1,29 @@ +label; + + foreach ( $post_types as $post_type => $label ) { + $condition = new Post( [ + 'post_type' => $post_type, + ] ); + + $this->register_sub_condition( $condition ); + } + + $this->sub_conditions[] = 'child_of'; + + $this->sub_conditions[] = 'any_child_of'; + + $this->sub_conditions[] = 'by_author'; + + // Last condition. + $this->sub_conditions[] = 'not_found404'; + } + + public function check( $args ) { + return ( is_singular() && ! is_embed() ) || is_404(); + } +} diff --git a/modules/theme-builder/conditions/taxonomy.php b/modules/theme-builder/conditions/taxonomy.php new file mode 100644 index 00000000..ebc44de6 --- /dev/null +++ b/modules/theme-builder/conditions/taxonomy.php @@ -0,0 +1,70 @@ +taxonomy = $data['object']; + } + + public function get_name() { + return $this->taxonomy->name; + } + + public function get_label() { + return $this->taxonomy->label; + } + + public function check( $args ) { + $taxonomy = $this->get_name(); + $id = (int) $args['id']; + + if ( 'category' === $taxonomy ) { + return is_category( $id ); + } + + if ( 'post_tag' === $taxonomy ) { + return is_tag( $id ); + } + + return is_tax( $taxonomy, $id ); + } + + protected function register_controls() { + $this->add_control( + 'taxonomy', + [ + 'section' => 'settings', + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [ + '' => esc_html__( 'All', 'elementor-pro' ), + ], + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_TAX, + 'by_field' => 'term_id', + 'query' => [ + 'taxonomy' => $this->taxonomy->name, + ], + ], + ] + ); + } +} diff --git a/modules/theme-builder/documents/archive-single-base.php b/modules/theme-builder/documents/archive-single-base.php new file mode 100644 index 00000000..eb0f9ea4 --- /dev/null +++ b/modules/theme-builder/documents/archive-single-base.php @@ -0,0 +1,60 @@ +save_sub_type_condition(); + } + + private function save_sub_type_condition() { + $conditions_manager = ThemeBuilderModule::instance()->get_conditions_manager(); + + $sub_type = Utils::_unstable_get_super_global_value( $_REQUEST, self::REMOTE_CATEGORY_META_KEY ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + + if ( ! empty( $sub_type ) && $conditions_manager->get_condition( $sub_type ) ) { + $this->update_meta( self::REMOTE_CATEGORY_META_KEY, $sub_type ); + + $conditions_manager->save_conditions( $this->post->ID, [ + [ + 'include', + $this->get_property( 'condition_type' ), + $sub_type, + ], + ] ); + } + } +} diff --git a/modules/theme-builder/documents/archive.php b/modules/theme-builder/documents/archive.php new file mode 100644 index 00000000..933ca646 --- /dev/null +++ b/modules/theme-builder/documents/archive.php @@ -0,0 +1,105 @@ + esc_html__( 'What is an archive template?', 'elementor-pro' ), + 'content' => esc_html__( 'An archive template allows you to easily design the layout and style of archive pages - those pages that show a list of posts (e.g. a blog’s list of recent posts), which may be filtered by terms such as authors, categories, tags, search results, etc.', 'elementor-pro' ), + 'tip' => esc_html__( 'If you’d like a different style for a specific category, it’s easy to create a separate archive template whose condition is to only display when users are viewing that category’s list of posts.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-archive', + 'video_url' => 'https://www.youtube.com/embed/wxElpEh9bfA', + ]; + } + + protected static function get_editor_panel_categories() { + $categories = [ + 'theme-elements-archive' => [ + 'title' => esc_html__( 'Archive', 'elementor-pro' ), + ], + ]; + + return $categories + parent::get_editor_panel_categories(); + } + + public static function get_preview_as_default() { + return 'archive/recent_posts'; + } + + public static function get_preview_as_options() { + $post_type_archives = []; + + $taxonomies = []; + + $post_types = Module::get_public_post_types(); + + foreach ( $post_types as $post_type => $label ) { + $post_type_object = get_post_type_object( $post_type ); + + if ( $post_type_object->has_archive ) { + /* translators: %s: Post type label. */ + $post_type_archives[ 'post_type_archive/' . $post_type ] = sprintf( esc_html__( '%s archive', 'elementor-pro' ), $post_type_object->label ); + } + + $post_type_taxonomies = get_object_taxonomies( $post_type, 'objects' ); + + $post_type_taxonomies = wp_filter_object_list( $post_type_taxonomies, [ + 'public' => true, + 'show_in_nav_menus' => true, + ] ); + + foreach ( $post_type_taxonomies as $slug => $object ) { + /* translators: %s: Taxonomy label. */ + $taxonomies[ 'taxonomy/' . $slug ] = sprintf( esc_html__( '%s archive', 'elementor-pro' ), $object->label ); + } + } + + $options = [ + 'archive/recent_posts' => esc_html__( 'Recent posts', 'elementor-pro' ), + 'archive/date' => esc_html__( 'Date archive', 'elementor-pro' ), + 'archive/author' => esc_html__( 'Author archive', 'elementor-pro' ), + 'search' => esc_html__( 'Search results', 'elementor-pro' ), + ]; + + $options += $taxonomies + $post_type_archives; + + return [ + 'archive' => [ + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + 'options' => $options, + ], + ]; + } +} diff --git a/modules/theme-builder/documents/error-404.php b/modules/theme-builder/documents/error-404.php new file mode 100644 index 00000000..767f285b --- /dev/null +++ b/modules/theme-builder/documents/error-404.php @@ -0,0 +1,53 @@ + esc_html__( 'What is a 404 page template?', 'elementor-pro' ), + 'content' => esc_html__( 'A 404 page template allows you to easily design the layout and style of the page that is displayed when a visitor arrives at a page that does not exist.', 'elementor-pro' ), + 'tip' => esc_html__( 'Keep your site\'s visitors happy when they get lost by displaying your recent posts, a search bar, or any information that might help the user find what they were looking for.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-error-404', + 'video_url' => 'https://www.youtube.com/embed/ACCNp9tBMQg', + ]; + } + + public static function get_preview_as_options() { + return [ + 'page/404' => esc_html__( '404', 'elementor-pro' ), + ]; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = '404 page'; + + return $config; + } +} diff --git a/modules/theme-builder/documents/footer.php b/modules/theme-builder/documents/footer.php new file mode 100644 index 00000000..89374e69 --- /dev/null +++ b/modules/theme-builder/documents/footer.php @@ -0,0 +1,47 @@ + esc_html__( 'What is a footer template?', 'elementor-pro' ), + 'content' => esc_html__( 'The footer template allows you to easily design and edit custom WordPress footers without the limits of your theme’s footer design constraints', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple footers, and assign each to different areas of your site.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-footer', + 'video_url' => 'https://www.youtube.com/embed/xa8DoR4tQrY', + ]; + } +} diff --git a/modules/theme-builder/documents/header-footer-base.php b/modules/theme-builder/documents/header-footer-base.php new file mode 100644 index 00000000..c1ae0b8a --- /dev/null +++ b/modules/theme-builder/documents/header-footer-base.php @@ -0,0 +1,67 @@ +get_main_id(); + } + + protected static function get_editor_panel_categories() { + // Move to top as active. + $categories = [ + 'theme-elements' => [ + 'title' => esc_html__( 'Site', 'elementor-pro' ), + 'active' => true, + ], + ]; + + return $categories + parent::get_editor_panel_categories(); + } + + protected function register_controls() { + parent::register_controls(); + + Post::register_style_controls( $this ); + + $this->update_control( + 'section_page_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + ] + ); + + $this->start_injection( [ + 'of' => 'margin', + ] ); + + $this->add_control( + 'hidden_header_footer_style_control', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => 'hidden_control', + 'selectors' => [ + '.elementor-theme-builder-content-area' => 'height: 400px;', + '.elementor-location-header:before, .elementor-location-footer:before' => 'content: ""; display: table; clear: both;', + ], + ] + ); + + $this->end_injection(); + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = $this->get_name(); + + return $config; + } +} diff --git a/modules/theme-builder/documents/header.php b/modules/theme-builder/documents/header.php new file mode 100644 index 00000000..2b983e86 --- /dev/null +++ b/modules/theme-builder/documents/header.php @@ -0,0 +1,48 @@ + esc_html__( 'What is a header template?', 'elementor-pro' ), + 'content' => esc_html__( 'The header template allows you to easily design and edit custom WordPress headers so you are no longer constrained by your theme’s header design limitations.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple headers, and assign each to different areas of your site.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-header', + 'video_url' => 'https://www.youtube.com/embed/HHy5RK6W-6I', + ]; + } +} diff --git a/modules/theme-builder/documents/search-results.php b/modules/theme-builder/documents/search-results.php new file mode 100644 index 00000000..9975dc8a --- /dev/null +++ b/modules/theme-builder/documents/search-results.php @@ -0,0 +1,68 @@ + esc_html__( 'What is a search results template?', 'elementor-pro' ), + 'content' => esc_html__( 'You can easily control the layout and design of the Search Results page with the Search Results template, which is simply a special archive template just for displaying search results.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can customize the message if there are no results for the search term.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-search-results', + 'video_url' => 'https://www.youtube.com/embed/KKkIU_L5sDo', + ]; + } + + public static function get_preview_as_default() { + return 'search'; + } + + public static function get_preview_as_options() { + $options = [ + 'search' => esc_html__( 'Search results', 'elementor-pro' ), + ]; + + return [ + 'archive' => [ + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + 'options' => $options, + ], + ]; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'archive'; + + return $config; + } +} diff --git a/modules/theme-builder/documents/section.php b/modules/theme-builder/documents/section.php new file mode 100644 index 00000000..c7deb2c6 --- /dev/null +++ b/modules/theme-builder/documents/section.php @@ -0,0 +1,113 @@ +get_locations_manager()->register_locations(); + + $locations = Module::instance()->get_locations_manager()->get_locations( [ + 'public' => true, + ] ); + + if ( empty( $locations ) ) { + return; + } + + $this->start_controls_section( + 'location_settings', + [ + 'label' => esc_html__( 'Location Settings', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_SETTINGS, + ] + ); + + $options = [ + '' => esc_html__( 'Select', 'elementor-pro' ), + ]; + + foreach ( $locations as $location => $settings ) { + $options[ $location ] = $settings['label']; + } + + $this->add_control( + 'location', + [ + 'label' => esc_html__( 'Location', 'elementor-pro' ), + 'label_block' => true, + 'type' => Controls_Manager::SELECT, + 'default' => $this->get_location(), + 'save_default' => true, + 'options' => $options, + ] + ); + + $this->add_control( + 'apply_location', + [ + 'type' => Controls_Manager::BUTTON, + 'label' => '', + 'text' => esc_html__( 'Apply', 'elementor-pro' ), + 'event' => 'elementorThemeBuilder:ApplyPreview', + ] + ); + + $this->end_controls_section(); + } + + public function get_export_data() { + $data = parent::get_export_data(); + + $data['location'] = $this->get_location(); + + return $data; + } + + public function save_settings( $settings ) { + if ( isset( $settings['location'] ) ) { + if ( empty( $settings['location'] ) ) { + $this->delete_main_meta( '_elementor_location' ); + } else { + $this->update_main_meta( '_elementor_location', $settings['location'] ); + unset( $settings['location'] ); + } + Module::instance()->get_conditions_manager()->get_cache()->regenerate(); + } + + parent::save_settings( $settings ); + } +} diff --git a/modules/theme-builder/documents/single-base.php b/modules/theme-builder/documents/single-base.php new file mode 100644 index 00000000..8a61c13f --- /dev/null +++ b/modules/theme-builder/documents/single-base.php @@ -0,0 +1,189 @@ + true, + ]; + + return $config; + } + + protected static function get_editor_panel_categories() { + $categories = [ + 'theme-elements-single' => [ + 'title' => esc_html__( 'Single', 'elementor-pro' ), + ], + ]; + + return $categories + parent::get_editor_panel_categories(); + } + + public function before_get_content() { + parent::before_get_content(); + + // For `loop_start` hook. + if ( have_posts() ) { + the_post(); + } + } + + public function after_get_content() { + wp_reset_postdata(); + + parent::after_get_content(); + } + + public function get_container_attributes() { + $attributes = parent::get_container_attributes(); + + if ( is_singular() /* Not 404 */ ) { + $post_classes = get_post_class( '', get_the_ID() ); + $attributes['class'] .= ' ' . implode( ' ', $post_classes ); + } + + return $attributes; + } + + public function print_content() { + $requested_post_id = get_the_ID(); + if ( $requested_post_id !== $this->post->ID ) { + $requested_document = Module::instance()->get_document( $requested_post_id ); + + if ( $requested_document instanceof Floating_Buttons ) { + $requested_document->print_content(); + parent::print_content(); + return; + } + + /** + * if current requested document is theme-document & it's not a content type ( like header/footer/sidebar ) + * show a placeholder instead of content. + */ + if ( $requested_document && ! $requested_document instanceof Section && $requested_document->get_location() !== $this->get_location() ) { + echo '
      ' . esc_html__( 'Content area', 'elementor-pro' ) . '
      '; + + return; + } + } + + parent::print_content(); + } + + protected function register_controls() { + parent::register_controls(); + + $post_type = $this->get_main_meta( self::REMOTE_CATEGORY_META_KEY ); + + $latest_posts = get_posts( [ + 'posts_per_page' => 1, + 'post_type' => $post_type, + ] ); + + if ( ! empty( $latest_posts ) ) { + $this->update_control( + 'preview_type', + [ + 'default' => 'single/' . $post_type, + ] + ); + + $this->update_control( + 'preview_id', + [ + 'default' => $latest_posts[0]->ID, + ] + ); + } + } + + public static function get_preview_as_options() { + $post_types = Module::get_public_post_types(); + + $post_types['attachment'] = get_post_type_object( 'attachment' )->label; + $post_types_options = []; + + foreach ( $post_types as $post_type => $label ) { + $post_types_options[ 'single/' . $post_type ] = get_post_type_object( $post_type )->labels->singular_name; + } + + return [ + 'single' => [ + 'label' => esc_html__( 'Single', 'elementor-pro' ), + 'options' => $post_types_options, + ], + 'page/404' => esc_html__( '404', 'elementor-pro' ), + ]; + } + + public function get_depended_widget() { + return Plugin::elementor()->widgets_manager->get_widget_types( 'theme-post-content' ); + } + + public function get_elements_data( $status = DB::STATUS_PUBLISH ) { + $data = parent::get_elements_data(); + + if ( Plugin::elementor()->preview->is_preview_mode() && self::get_property( 'location' ) === Module::instance()->get_locations_manager()->get_current_location() ) { + $has_the_content = false; + + $depended_widget = $this->get_depended_widget(); + + Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$has_the_content, $depended_widget ) { + if ( isset( $element['widgetType'] ) && $depended_widget->get_name() === $element['widgetType'] ) { + $has_the_content = true; + } + } ); + + if ( ! $has_the_content ) { + add_action( 'wp_footer', [ $this, 'preview_error_handler' ] ); + } + } + + return $data; + } + + public function preview_error_handler() { + $depended_widget_title = $this->get_depended_widget()->get_title(); + + wp_localize_script( 'elementor-frontend', 'elementorPreviewErrorArgs', [ + /* translators: %s: Widget name. */ + 'headerMessage' => sprintf( esc_html__( 'The %s widget was not found in your template.', 'elementor-pro' ), $depended_widget_title ), + /* translators: 1: Widget name, 2: Template name. */ + 'message' => sprintf( esc_html__( 'You must include the %1$s widget in your template (%2$s), in order for Elementor to work on this page.', 'elementor-pro' ), $depended_widget_title, '' . static::get_title() . '' ), + 'strings' => [ + 'confirm' => esc_html__( 'Edit Template', 'elementor-pro' ), + ], + 'confirmURL' => $this->get_edit_url(), + ] ); + } +} diff --git a/modules/theme-builder/documents/single-page.php b/modules/theme-builder/documents/single-page.php new file mode 100644 index 00000000..8ecb7e56 --- /dev/null +++ b/modules/theme-builder/documents/single-page.php @@ -0,0 +1,46 @@ + esc_html__( 'What is a single page template?', 'elementor-pro' ), + 'content' => esc_html__( 'A single page template allows you to easily create the layout and style of pages, ensuring design consistency across all the pages of your site.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple single page templates, and assign each to different areas of your site.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-page', + 'video_url' => 'https://www.youtube.com/embed/_y5eZ60lVoY', + ]; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'single page'; + + return $config; + } +} diff --git a/modules/theme-builder/documents/single-post.php b/modules/theme-builder/documents/single-post.php new file mode 100644 index 00000000..85e02d25 --- /dev/null +++ b/modules/theme-builder/documents/single-post.php @@ -0,0 +1,43 @@ + esc_html__( 'What is a single post template?', 'elementor-pro' ), + 'content' => esc_html__( 'A single post template allows you to easily design the layout and style of posts, ensuring a design consistency throughout all your blog posts, for example.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple single post templates, and assign each to a different category.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-post', + 'video_url' => 'https://www.youtube.com/embed/8Fk-Edu7DL0', + ]; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'single post'; + + return $config; + } +} diff --git a/modules/theme-builder/documents/single.php b/modules/theme-builder/documents/single.php new file mode 100644 index 00000000..e4ae60a2 --- /dev/null +++ b/modules/theme-builder/documents/single.php @@ -0,0 +1,46 @@ +get_meta( self::REMOTE_CATEGORY_META_KEY ); + + if ( $category ) { + if ( 'not_found404' === $category ) { + $category = '404 page'; + } else { + $category = 'single ' . $category; + } + + $config['category'] = $category; + } else { + $config['category'] = 'single post'; + } + + return $config; + } + + protected static function get_site_editor_thumbnail_url() { + return ELEMENTOR_ASSETS_URL . 'images/app/site-editor/single-post.svg'; + } +} diff --git a/modules/theme-builder/documents/theme-document.php b/modules/theme-builder/documents/theme-document.php new file mode 100644 index 00000000..49c6cc02 --- /dev/null +++ b/modules/theme-builder/documents/theme-document.php @@ -0,0 +1,736 @@ + static::get_type(), + 'icon' => static::get_site_editor_icon(), + 'title' => static::get_title(), + 'page_title' => static::get_title(), + 'page_layout' => static::get_site_editor_layout(), + + // Todo: Remove. Core plugin should use `urls.route`. + 'url' => static::get_site_editor_route(), + + 'urls' => [ + 'route' => static::get_site_editor_route(), + 'create' => static::get_create_url(), + 'thumbnail' => static::get_site_editor_thumbnail_url(), + ], + 'tooltip_data' => static::get_site_editor_tooltip_data(), + 'show_instances' => true, + ]; + } + + public static function get_editor_panel_config() { + $panel_config = parent::get_editor_panel_config(); + $document_config = static::get_properties(); + + if ( true === $document_config['support_site_editor'] ) { + $panel_config['messages']['publish_notification'] = esc_html__( 'Congrats! Your site part is live', 'elementor-pro' ); + } + + return $panel_config; + } + + protected function get_have_a_look_url() { + $document_config = static::get_properties(); + + if ( true === $document_config['support_site_editor'] ) { + return ''; + } + + return parent::get_have_a_look_url(); + } + + public static function get_create_url() { + $base_create_url = Plugin::elementor()->documents->get_create_new_post_url( Source_Local::CPT ); + + return add_query_arg( [ 'template_type' => static::get_type() ], $base_create_url ); + } + + protected static function get_site_editor_tooltip_data() { + return [ + 'title' => '', + 'content' => '', + 'tip' => '', + 'video_url' => '', + ]; + } + + public function get_name() { + return static::get_type(); + } + + protected function get_default_wrapping_html_tag() { + return 'div'; + } + + public static function get_lock_behavior_v2() { + return new Feature_Lock( [ + 'type' => static::get_type(), + ] ); + } + + public function get_location_label() { + $location = $this->get_location(); + $locations_settings = Module::instance()->get_locations_manager()->get_location( $location ); + $label = ''; + $is_section_doc_type = 'section' === $this->get_name(); + + if ( $location ) { + if ( $is_section_doc_type ) { + $label .= isset( $locations_settings['label'] ) ? $locations_settings['label'] : $location; + } + } + + $supported = true; + + if ( $is_section_doc_type ) { + if ( $location && ! $locations_settings ) { + $supported = false; + } + } elseif ( ! $location || ! $locations_settings ) { + $supported = false; + } + + if ( ! $supported ) { + $label .= ' (' . esc_html__( 'Unsupported', 'elementor-pro' ) . ')'; + } + + return $label; + } + + public function before_get_content() { + $preview_manager = Module::instance()->get_preview_manager(); + $preview_manager->switch_to_preview_query(); + } + + public function after_get_content() { + $preview_manager = Module::instance()->get_preview_manager(); + $preview_manager->restore_current_query(); + } + + public function get_content( $with_css = false ) { + $this->before_get_content(); + + $content = parent::get_content( $with_css ); + + $this->after_get_content(); + + return $content; + } + + public function print_content() { + $plugin = Plugin::elementor(); + + if ( $plugin->preview->is_preview_mode( $this->get_main_id() ) ) { + // PHPCS - the method builder_wrapper is safe. + echo $plugin->preview->builder_wrapper( '' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + // PHPCS - the method get_content is safe. + echo $this->get_content(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + public static function get_preview_as_default() { + return ''; + } + + public static function get_preview_as_options() { + return []; + } + + public function get_container_attributes() { + $attributes = parent::get_container_attributes(); + + $location = Module::instance()->get_locations_manager()->get_current_location(); + + if ( $location ) { + $attributes['class'] .= ' elementor-location-' . $location; + } + + return $attributes; + } + + /** + * @static + * @since 2.0.0 + * @access public + * + * @return string + */ + public function get_edit_url() { + $url = parent::get_edit_url(); + + if ( isset( $_GET['action'] ) && 'elementor_new_post' === $_GET['action'] ) { + $url .= '#library'; + } + + return $url; + + } + + public function get_export_summary() { + $summary = parent::get_export_summary(); + + $summary['location'] = $this->get_location(); + + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + + $conditions = $theme_builder->get_conditions_manager()->get_document_conditions( $this ); + + foreach ( $conditions as $condition ) { + if ( 'include' === $condition['type'] && ! $condition['sub_id'] ) { + $summary['conditions'][] = $condition; + + break; + } + } + + return $summary; + } + + public function import( array $data ) { + parent::import( $data ); + + /** @var Module $theme_builder */ + $theme_builder = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + + $conditions = isset( $data['import_settings']['conditions'] ) ? $data['import_settings']['conditions'] : []; + + if ( ! empty( $conditions ) ) { + $condition = $conditions[0]; + + $condition = rtrim( implode( '/', $condition ), '/' ); + + $conflicts = $theme_builder->get_conditions_manager()->get_conditions_conflicts_by_location( $condition, $this->get_location() ); + + if ( $conflicts ) { + $override_conditions = $this->get_import_instance()->get_settings( 'overrideConditions' ); + + if ( ! $override_conditions || ! in_array( $data['id'], $override_conditions, true ) ) { + return; + } + + foreach ( $conflicts as $template ) { + /** @var Theme_Document $template_document */ + $template_document = Plugin::elementor()->documents->get( $template['template_id'] ); + + $template_conditions = $theme_builder->get_conditions_manager()->get_document_conditions( $template_document ); + + foreach ( $template_conditions as $index => $template_condition ) { + if ( in_array( $template_condition, $conditions, true ) ) { + unset( $template_conditions[ $index ] ); + } + } + + $theme_builder->get_conditions_manager()->save_conditions( $template_document->get_main_id(), $template_conditions ); + } + } + } + + $theme_builder->get_conditions_manager()->save_conditions( $this->get_main_id(), $conditions ); + } + + /** + * Get the import instance from the appropriate import-export component. + * + * Attempts to get the import instance from the customization component if the + * experiment is active and has a valid import property, otherwise falls back + * to the standard import-export component. + * + * @return mixed The import instance + * @throws \Exception If no valid import instance can be found + */ + private function get_import_instance() { + $is_customization_active = Plugin::elementor()->experiments->is_feature_active( + self::IMPORT_EXPORT_CUSTOMIZATION_NAME + ); + + if ( $is_customization_active ) { + $import_instance = $this->try_get_import_from_component( self::IMPORT_EXPORT_CUSTOMIZATION_NAME ); + + if ( $import_instance ) { + return $import_instance; + } + } + + $import_instance = $this->try_get_import_from_component( self::IMPORT_EXPORT_NAME ); + + if ( ! $import_instance ) { + throw new \Exception( 'No valid import-export component found' ); + } + + return $import_instance; + } + + /** + * Attempt to get import instance from a specific component. + * + * @param string $component_name The name of the component to check + * @return mixed|null The import instance if valid, null otherwise + */ + private function try_get_import_from_component( $component_name ) { + $component = Plugin::elementor()->app->get_component( $component_name ); + + if ( ! $component || ! isset( $component->import ) || is_null( $component->import ) ) { + return null; + } + + return $component->import; + } + + protected function register_controls() { + parent::register_controls(); + + $this->start_controls_section( + 'preview_settings', + [ + 'label' => esc_html__( 'Preview Settings', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_SETTINGS, + ] + ); + + $this->add_control( + 'preview_type', + [ + 'label' => esc_html__( 'Preview Dynamic Content as', 'elementor-pro' ), + 'label_block' => true, + 'type' => Controls_Manager::SELECT, + 'default' => $this::get_preview_as_default(), + 'groups' => $this::get_preview_as_options(), + 'export' => false, + ] + ); + + $this->add_control( + 'preview_id', + [ + 'type' => QueryModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_JS, + ], + 'export' => false, + 'condition' => [ + 'preview_type!' => [ + '', + 'search', + ], + ], + ] + ); + + $this->add_control( + 'preview_search_term', + [ + 'label' => esc_html__( 'Search Term', 'elementor-pro' ), + 'export' => false, + 'condition' => [ + 'preview_type' => 'search', + ], + ] + ); + + $this->add_control( + 'apply_preview', + [ + 'type' => Controls_Manager::BUTTON, + 'label' => esc_html__( 'Apply & Preview', 'elementor-pro' ), + 'label_block' => true, + 'show_label' => false, + 'text' => esc_html__( 'Apply & Preview', 'elementor-pro' ), + 'event' => 'elementorThemeBuilder:ApplyPreview', + ] + ); + + $this->end_controls_section(); + + $this->inject_html_tag_control(); + } + + /** + * @since 2.9.0 + * + * If the implementing document uses optional wrapper HTML tags, this method injects the control to choose the tag + */ + private function inject_html_tag_control() { + $wrapper_tags = $this->get_wrapper_tags(); + + // Only proceed if the implementing document has optional wrapper HTML tags to replace 'div' + if ( ! $wrapper_tags ) { + return; + } + + // Add 'div' to the beginning of the list of wrapper tags + array_unshift( $wrapper_tags, 'div' ); + + /** + * Inject the control that sets the HTML tag for the header/footer wrapper element + */ + $this->start_injection( [ + 'of' => 'post_status', + 'fallback' => [ + 'of' => 'post_title', + ], + ] ); + + $this->add_control( + 'content_wrapper_html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => $this->get_default_wrapping_html_tag(), + 'options' => array_combine( $wrapper_tags, $wrapper_tags ), + ] + ); + + $this->end_injection(); + } + + /** + * @param null $elements_data + * @since 2.9.0 + * @access public + * + * Overwrite method from document.php to check for user-selected tags to use as the document wrapper element + */ + public function print_elements_with_wrapper( $elements_data = null ) { + // Check if the implementing document has optional wrapper tags + $has_wrapper_tags = $this->get_wrapper_tags(); + $settings = $this->get_settings_for_display(); + $wrapper_tag = 'div'; + + // Only proceed if the inheriting document has optional wrapper HTML tags to replace 'div' + if ( $has_wrapper_tags ) { + $wrapper_tag = Utils::validate_html_tag( $settings['content_wrapper_html_tag'] ); + } + + if ( ! $elements_data ) { + $elements_data = $this->get_elements_data(); + } + + ?> + < get_container_attributes() ); ?>> + print_elements( $elements_data ); ?> + > + get_preview_manager(); + + $preview_manager->switch_to_preview_query(); + + $editor_data = parent::get_elements_raw_data( $data, $with_html_content ); + + $preview_manager->restore_current_query(); + + return $editor_data; + } + + public function render_element( $data ) { + $preview_manager = Module::instance()->get_preview_manager(); + + $preview_manager->switch_to_preview_query(); + + $render_html = parent::render_element( $data ); + + $preview_manager->restore_current_query(); + + return $render_html; + } + + public function get_wp_preview_url() { + // Ajax request from editor. + // PHPCS - the method is safe - just retrieving a value. + if ( ! empty( $_POST['initial_document_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing + return parent::get_wp_preview_url(); + } + + $preview_id = (int) $this->get_settings( 'preview_id' ); + $post_id = $this->get_main_id(); + + list( $preview_category, $preview_object_type ) = array_pad( explode( '/', $this->get_settings( 'preview_type' ) ), 2, '' ); + + $home_url = trailingslashit( home_url() ); + + switch ( $preview_category ) { + case 'archive': + switch ( $preview_object_type ) { + case 'author': + if ( empty( $preview_id ) ) { + $preview_id = get_current_user_id(); + } + $preview_url = get_author_posts_url( $preview_id ); + break; + case 'date': + $preview_url = add_query_arg( 'year', gmdate( 'Y' ), $home_url ); + break; + } + break; + case 'search': + $preview_url = add_query_arg( 's', $this->get_settings( 'preview_search_term' ), $home_url ); + break; + case 'taxonomy': + $term = get_term( $preview_id ); + + if ( $term && ! is_wp_error( $term ) ) { + $preview_url = get_term_link( $preview_id ); + } + + break; + case 'page': + switch ( $preview_object_type ) { + case 'home': + $preview_url = get_post_type_archive_link( 'post' ); + break; + case 'front': + $preview_url = $home_url; + break; + case '404': + $preview_url = add_query_arg( 'p', '-1', $home_url ); + break; + } + break; + case 'post_type_archive': + $post_type = $preview_object_type; + if ( post_type_exists( $post_type ) ) { + $preview_url = get_post_type_archive_link( $post_type ); + } + break; + case 'single': + $post = get_post( $preview_id ); + if ( $post ) { + $preview_url = get_permalink( $post ); + } + break; + } // End switch(). + + if ( empty( $preview_url ) ) { + $preview_url = $this->get_permalink(); + } + + $query_args = [ + 'preview' => true, + 'preview_nonce' => wp_create_nonce( 'post_preview_' . $post_id ), + 'theme_template_id' => $post_id, + ]; + + $preview_url = set_url_scheme( add_query_arg( $query_args, $preview_url ) ); + + /** + * Document "WordPress preview" URL. + * + * Filters the WordPress preview URL. + * + * @since 2.0.0 + * + * @param string $preview_url Document preview URL. + * @param Theme_Document $this An instance of the theme document. + */ + $preview_url = apply_filters( 'elementor/document/wp_preview_url', $preview_url, $this ); + + return $preview_url; + } + + public function get_preview_as_query_args() { + $preview_id = (int) $this->get_settings( 'preview_id' ); + + list( $preview_category, $preview_object_type ) = array_pad( explode( '/', $this->get_settings( 'preview_type' ) ), 2, '' ); + + switch ( $preview_category ) { + case 'archive': + switch ( $preview_object_type ) { + case 'author': + if ( empty( $preview_id ) ) { + $preview_id = get_current_user_id(); + } + + $query_args = [ + 'author' => $preview_id, + ]; + break; + case 'date': + $query_args = [ + 'year' => gmdate( 'Y' ), + ]; + break; + case 'recent_posts': + $query_args = [ + 'post_type' => 'post', + ]; + break; + } + break; + case 'search': + $query_args = [ + 's' => $this->get_settings( 'preview_search_term' ), + ]; + break; + case 'taxonomy': + case 'post_taxonomy': + case 'product_taxonomy': + $term = $this->get_taxonomy_term( $preview_id, $preview_object_type ); + + if ( $term && ! is_wp_error( $term ) ) { + $query_args = [ + 'tax_query' => [ + [ + 'taxonomy' => $term->taxonomy, + 'terms' => [ $term->term_id ], + 'field' => 'id', + ], + ], + ]; + } + break; + case 'page': + switch ( $preview_object_type ) { + case 'home': + $query_args = []; + break; + case 'front': + $query_args = [ + 'p' => get_option( 'page_on_front' ), + 'post_type' => 'page', + ]; + break; + case '404': + $query_args = [ + 'p' => -1, + ]; + break; + } + break; + case 'post_type_archive': + $post_type = $preview_object_type; + if ( post_type_exists( $post_type ) ) { + $query_args = [ + 'post_type' => $post_type, + ]; + } + break; + case 'single': + $query_args = [ + 'post_type' => $preview_object_type, + 'p' => $preview_id, + ]; + break; + } // End switch(). + + if ( empty( $query_args ) ) { + $query_args = [ + 'p' => $this->get_main_id(), + 'post_type' => $this->get_main_post()->post_type, + ]; + } + + return $query_args; + } + + public function after_preview_switch_to_query() { + global $wp_query; + if ( 'archive/recent_posts' === $this->get_settings( 'preview_type' ) ) { + $wp_query->is_archive = true; + } + } + + public function get_location() { + $value = self::get_property( 'location' ); + if ( ! $value ) { + $value = $this->get_main_meta( self::LOCATION_META_KEY ); + } + + return $value; + } + + public function get_initial_config() { + $config = parent::get_initial_config(); + + $config['support_site_editor'] = static::get_property( 'support_site_editor' ); + + return $config; + } + + /** + * @param $preview_id + * @param $preview_object_type + * @return \WP_Error|\WP_Term|null + */ + private function get_taxonomy_term( $preview_id, $preview_object_type ) { + if ( ! empty( $preview_id ) ) { + return get_term( $preview_id ); + } + + $terms = get_terms( [ + 'taxonomy' => $preview_object_type, + ] ); + + return reset( $terms ); + } +} diff --git a/modules/theme-builder/documents/theme-page-document.php b/modules/theme-builder/documents/theme-page-document.php new file mode 100644 index 00000000..0f898d0f --- /dev/null +++ b/modules/theme-builder/documents/theme-page-document.php @@ -0,0 +1,131 @@ +get_main_id(); + } + + public static function get_properties() { + $properties = parent::get_properties(); + + $properties['support_wp_page_templates'] = true; + + return $properties; + } + + protected function register_controls() { + parent::register_controls(); + + $this->start_injection( [ + 'of' => 'post_status', + 'fallback' => [ + 'of' => 'post_title', + ], + ] ); + + $this->add_control( + 'page_template', + [ + 'label' => esc_html__( 'Page Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + PageTemplatesModule::TEMPLATE_CANVAS => esc_html__( 'PRO Elements Canvas', 'elementor-pro' ), + PageTemplatesModule::TEMPLATE_HEADER_FOOTER => esc_html__( 'PRO Elements Full Width', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'page_template_default_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Default Page Template from your theme', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'page_template' => 'default', + ], + ] + ); + + $this->add_control( + 'page_template_canvas_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'No header, no footer', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'page_template' => PageTemplatesModule::TEMPLATE_CANVAS, + ], + ] + ); + + $this->add_control( + 'page_template_header_footer_description', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'This template includes the header, full-width content and footer', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'page_template' => PageTemplatesModule::TEMPLATE_HEADER_FOOTER, + ], + ] + ); + + $this->end_injection(); + + Post::register_style_controls( $this ); + } + + /** + * Add body classes. + * + * Add the body classes for the `style` controls selector. + * + * @param $body_classes + * + * @return array + */ + public function filter_body_classes( $body_classes ) { + // Indicator for edit/preview an `archive` document, so it's a `single` elementor_library post - but need a behavior like an archive. + $is_archive_template = 'archive' === Source_Local::get_template_type( get_the_ID() ); + + $add_body_class = false; + + if ( $this instanceof Archive && ( is_archive() || is_search() || is_home() || $is_archive_template ) ) { + $add_body_class = true; + } elseif ( $this instanceof Single_Base && ( is_singular() || is_404() ) && ! $is_archive_template ) { + $add_body_class = true; + } + + if ( $add_body_class ) { + $body_classes[] = 'elementor-page-' . $this->get_main_id(); + } + + return $body_classes; + } + + public function __construct( array $data = [] ) { + if ( $data ) { + add_filter( 'body_class', [ $this, 'filter_body_classes' ] ); + } + + parent::__construct( $data ); + } +} diff --git a/modules/theme-builder/documents/theme-section-document.php b/modules/theme-builder/documents/theme-section-document.php new file mode 100644 index 00000000..901482ca --- /dev/null +++ b/modules/theme-builder/documents/theme-section-document.php @@ -0,0 +1,43 @@ + esc_html__( 'Select...', 'elementor-pro' ), + ], + Archive::get_preview_as_options(), + Single::get_preview_as_options() + ); + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = ''; + + return $config; + } +} diff --git a/modules/theme-builder/import-export-customization/export.php b/modules/theme-builder/import-export-customization/export.php new file mode 100644 index 00000000..cfeb6cb4 --- /dev/null +++ b/modules/theme-builder/import-export-customization/export.php @@ -0,0 +1,87 @@ +export_theme_builder_templates(); + + if ( empty( $theme_builder_data['files'] ) ) { + return $export_data; + } + + $export_data['files'] = array_merge( $export_data['files'], $theme_builder_data['files'] ); + + if ( ! empty( $theme_builder_data['manifest'] ) ) { + $export_data['manifest'][0]['templates'] = ( $export_data['manifest'][0]['templates'] ?? [] ) + $theme_builder_data['manifest']; + } + + return $export_data; + } + + private function export_theme_builder_templates() { + $theme_builder_types = array_keys( Plugin::elementor()->documents->get_document_types( [ + 'is_editable' => true, + 'export_group' => Theme_Document::EXPORT_GROUP, + ] ) ); + + if ( empty( $theme_builder_types ) ) { + return [ + 'files' => [], + 'manifest' => [], + ]; + } + + $query_args = [ + 'post_type' => Source_Local::CPT, + 'post_status' => 'publish', + 'posts_per_page' => -1, + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => $theme_builder_types, + ], + ], + ]; + + $theme_builder_query = new \WP_Query( $query_args ); + + $manifest_data = []; + $files = []; + + foreach ( $theme_builder_query->posts as $template_post ) { + $template_id = $template_post->ID; + + $template_document = Plugin::elementor()->documents->get( $template_id ); + + if ( ! $template_document || ! $template_document instanceof Theme_Document ) { + continue; + } + + $manifest_data[ $template_id ] = $template_document->get_export_summary(); + + $files[] = [ + 'path' => 'templates/' . $template_id, + 'data' => $template_document->get_export_data(), + ]; + } + + return [ + 'files' => $files, + 'manifest' => $manifest_data, + ]; + } +} diff --git a/modules/theme-builder/import-export-customization/import.php b/modules/theme-builder/import-export-customization/import.php new file mode 100644 index 00000000..4da51736 --- /dev/null +++ b/modules/theme-builder/import-export-customization/import.php @@ -0,0 +1,154 @@ +import_theme_builder_templates( $data, $runner ); + + if ( ! empty( $theme_builder_result ) ) { + $result['templates']['succeed'] = $this->array_merge_with_key_preservation( $result['templates']['succeed'], $theme_builder_result['succeed'] ); + $result['templates']['failed'] = $this->array_merge_with_key_preservation( $result['templates']['failed'], $theme_builder_result['failed'] ); + + foreach ( $theme_builder_result['succeed_summary'] as $doc_type => $count ) { + $result['templates']['succeed_summary'][ $doc_type ] = ( $result['templates']['succeed_summary'][ $doc_type ] ?? 0 ) + $count; + } + } + + return $result; + } + + private function import_theme_builder_templates( $data, $runner ) { + $path = $data['extracted_directory_path'] . 'templates/'; + $templates = $data['manifest']['templates']; + + $result = [ + 'succeed' => [], + 'failed' => [], + 'succeed_summary' => [], + ]; + + $theme_builder_types = array_keys( Plugin::elementor()->documents->get_document_types( [ + 'is_editable' => true, + 'export_group' => Theme_Document::EXPORT_GROUP, + ] ) ); + + foreach ( $templates as $id => $template_settings ) { + if ( ! in_array( $template_settings['doc_type'], $theme_builder_types, true ) ) { + continue; + } + + try { + $template_data = ImportExportCustomizationUtils::read_json_file( $path . $id ); + $imported_id = $this->import_theme_builder_template( $id, $template_settings, $template_data, $data ); + + $result['succeed'][ $id ] = $imported_id; + $result['succeed_summary'][ $template_settings['doc_type'] ] = ( $result['succeed_summary'][ $template_settings['doc_type'] ] ?? 0 ) + 1; + } catch ( \Exception $error ) { + $result['failed'][ $id ] = $error->getMessage(); + } + } + + if ( ! empty( $this->templates_conditions ) ) { + $runner->add_import_session_metadata( 'template_conditions', $this->templates_conditions ); + $this->templates_conditions = []; + } + + return $result; + } + + private function import_theme_builder_template( $id, array $template_settings, array $template_data, array $import_data ) { + $new_document = Plugin::elementor()->documents->create( + $template_settings['doc_type'], + [ + 'post_title' => $template_settings['title'], + 'post_type' => Source_Local::CPT, + 'post_status' => 'publish', + ] + ); + + if ( is_wp_error( $new_document ) ) { + throw new \Exception( esc_html( $new_document->get_error_message() ) ); + } + + $template_data['import_settings'] = $template_settings; + $template_data['id'] = $id; + + $this->set_templates_conditions( $template_data ); + + if ( isset( $import_data['session_id'] ) ) { + $new_attachment_callback = function( $attachment_id ) use ( $import_data ) { + $this->set_session_post_meta( $attachment_id, $import_data['session_id'] ); + }; + + add_filter( 'elementor/template_library/import_images/new_attachment', $new_attachment_callback ); + } + + $new_document->import( $template_data ); + + if ( isset( $new_attachment_callback ) ) { + remove_filter( 'elementor/template_library/import_images/new_attachment', $new_attachment_callback ); + } + + $document_id = $new_document->get_main_id(); + + if ( isset( $import_data['session_id'] ) ) { + $this->set_session_post_meta( $document_id, $import_data['session_id'] ); + } + + return $document_id; + } + + private function set_session_post_meta( $post_id, $session_id ) { + update_post_meta( $post_id, '_elementor_import_session_id', $session_id ); + } + + private function set_templates_conditions( $template_data ) { + $conditions = $template_data['import_settings']['conditions'] ?? []; + + if ( empty( $conditions ) ) { + return; + } + + $condition = $conditions[0]; + + $condition = rtrim( implode( '/', $condition ), '/' ); + + /** @var ThemeBuilderModule $theme_builder_module */ + $theme_builder_module = Plugin::instance()->modules_manager->get_modules( 'theme-builder' ); + $conditions_manager = $theme_builder_module->get_conditions_manager(); + + $conflicts = $conditions_manager->get_conditions_conflicts_by_location( + $condition, + $template_data['import_settings']['location'] + ); + + foreach ( $conflicts as $template ) { + $template_document = Plugin::elementor()->documents->get( $template['template_id'] ); + + $template_conditions = $theme_builder_module->get_conditions_manager()->get_document_conditions( $template_document ); + + $this->templates_conditions[ $template['template_id'] ] = $template_conditions; + } + } + + public function array_merge_with_key_preservation( array $base_array, array $additional_array ): array { + return $base_array + $additional_array; + } +} diff --git a/modules/theme-builder/import-export-customization/revert.php b/modules/theme-builder/import-export-customization/revert.php new file mode 100644 index 00000000..43ae95a9 --- /dev/null +++ b/modules/theme-builder/import-export-customization/revert.php @@ -0,0 +1,20 @@ +modules_manager->get_modules( 'theme-builder' ); + + $theme_builder_module->get_conditions_manager()->clear_cache(); + + $old_conditions = $data['runners']['templates']['template_conditions'] ?? []; + + foreach ( $old_conditions as $template_id => $conditions ) { + $theme_builder_module->get_conditions_manager()->save_conditions( $template_id, $conditions ); + } + } +} diff --git a/modules/theme-builder/module.php b/modules/theme-builder/module.php new file mode 100644 index 00000000..ab115681 --- /dev/null +++ b/modules/theme-builder/module.php @@ -0,0 +1,505 @@ +preview->is_preview_mode() || is_preview(); + } + + public static function get_public_post_types( $args = [] ) { + $post_types = Utils::get_public_post_types( $args ); + + // Product form WooCommerce are handled separately. + if ( class_exists( 'woocommerce' ) ) { + unset( $post_types['product'] ); + } + + return $post_types; + } + + public function get_name() { + return 'theme-builder'; + } + + public function get_widgets() { + $widgets = [ + 'Site_Logo', + 'Site_Title', + 'Page_Title', + 'Post_Title', + 'Post_Excerpt', + 'Post_Content', + 'Post_Featured_Image', + 'Archive_Title', + ]; + + if ( class_exists( '\ElementorPro\Modules\Posts\Widgets\Posts' ) ) { + $widgets[] = 'Archive_Posts'; + } + + return $widgets; + } + + /** + * @return Classes\Conditions_Manager + */ + public function get_conditions_manager() { + return $this->get_component( 'conditions' ); + } + + /** + * @return Classes\Locations_Manager + */ + public function get_locations_manager() { + return $this->get_component( 'locations' ); + } + + /** + * @return Classes\Preview_Manager + */ + public function get_preview_manager() { + return $this->get_component( 'preview' ); + } + + /** + * @return Classes\Templates_Types_Manager + */ + public function get_types_manager() { + return $this->get_component( 'templates_types' ); + } + + /** + * @param $post_id + * + * @return Theme_Document + */ + public function get_document( $post_id ) { + $document = null; + + try { + $document = Plugin::elementor()->documents->get( $post_id ); + } catch ( \Exception $e ) { + // Do nothing. + unset( $e ); + } + + if ( ! empty( $document ) && ! $document instanceof Theme_Document ) { + $document = null; + } + + return $document; + } + + public function document_config( $config, $post_id ) { + $document = $this->get_document( $post_id ); + + if ( ! $document ) { + return $config; + } + + $types_manager = $this->get_types_manager(); + $conditions_manager = $this->get_conditions_manager(); + $template_type = $this->get_template_type( $post_id ); + + $config = array_replace_recursive( $config, [ + 'theme_builder' => [ + 'types' => $types_manager->get_types_config(), + 'conditions' => $conditions_manager->get_conditions_config(), + 'template_conditions' => ( new Classes\Template_Conditions() )->get_config(), + 'is_theme_template' => $this->is_theme_template( $post_id ), + 'settings' => [ + 'template_type' => $template_type, + 'location' => $document->get_location(), + 'conditions' => $conditions_manager->get_document_conditions( $document ), + ], + ], + ] ); + + return $config; + } + + public function register_controls( Controls_Manager $controls_manager ) { + $controls_manager->register( new Classes\Conditions_Repeater() ); + $controls_manager->register( new Classes\Control_Media_Preview() ); + } + + public function create_new_dialog_types( $types ) { + /** + * @var Theme_Document[] $document_types + */ + foreach ( $types as $type => $label ) { + $document_type = Plugin::elementor()->documents->get_document_type( $type ); + $instance = new $document_type(); + + if ( $instance instanceof Theme_Document && 'section' !== $type ) { + $types[ $type ] .= $instance->get_location_label(); + } + + if ( Single::class === $document_type ) { + unset( $types[ $type ] ); + } + } + + return $types; + } + + public function print_location_field() { + $locations = $this->get_locations_manager()->get_locations( [ + 'public' => true, + ] ); + + if ( empty( $locations ) ) { + return; + } + ?> +
      + +
      + +
      +
      + false, + ] ); + + if ( empty( $post_types ) ) { + return; + } + ?> +
      + +
      + +
      +
      + id, [ 'elementor_library', 'edit-elementor_library' ] ) ) { + // For column type (Supported/Unsupported) & for `print_location_field`. + $this->get_locations_manager()->register_locations(); + } + } + + /** + * An hack to hide the app menu on before render without remove the app page from system. + * + * @param $menu + * + * @return mixed + */ + public function hide_admin_app_submenu( $menu ) { + remove_submenu_page( Source_Local::ADMIN_MENU_SLUG, App::PAGE_ID ); + + return $menu; + } + + public function admin_columns_content( $column_name, $post_id ) { + if ( 'elementor_library_type' === $column_name ) { + /** @var Document $document */ + $document = Plugin::elementor()->documents->get( $post_id ); + + if ( $document instanceof Theme_Document ) { + $location_label = $document->get_location_label(); + + if ( $location_label ) { + echo ' - ' . esc_html( $location_label ); + } + } + } + } + + public function get_template_type( $post_id ) { + return Source_local::get_template_type( $post_id ); + } + + public function is_theme_template( $post_id ) { + $document = Plugin::elementor()->documents->get( $post_id ); + + return $document instanceof Theme_Document; + } + + public function on_elementor_editor_init() { + Plugin::elementor()->common->add_template( __DIR__ . '/views/panel-template.php' ); + } + + public function add_finder_items( array $categories ) { + $categories['create']['items']['theme-template'] = [ + 'title' => esc_html__( 'Add new theme template', 'elementor-pro' ), + 'icon' => 'plus-circle-o', + 'url' => $this->get_admin_templates_url() . '#add_new', + 'keywords' => [ 'template', 'theme', 'new', 'create' ], + ]; + + return $categories; + } + + /** + * Add New item to admin menu. + * + * @since 3.6.0 + * @access private + */ + private function register_admin_menu( MainMenu $menu ) { + $menu->add_submenu( [ + 'menu_title' => esc_html__( 'Theme Builder', 'elementor-pro' ), + 'menu_slug' => Plugin::elementor()->app->get_settings( 'menu_url' ), + 'index' => 30, + ] ); + } + + /** + * Add New item to admin menu. + * + * Fired by `admin_menu` action. + * + * @since 3.6.0 + * @access private + */ + private function register_admin_menu_legacy( Admin_Menu_Manager $admin_menu ) { + $admin_menu->register( $this->get_admin_templates_url( true ), new Theme_Builder_Menu_Item() ); + } + + public function print_new_theme_builder_promotion( $views ) { + /** @var Source_Local $source */ + $source = Plugin::elementor()->templates_manager->get_source( 'local' ); + + $current_tab_group = $source->get_current_tab_group(); + + if ( self::ADMIN_LIBRARY_TAB_GROUP === $current_tab_group ) { + /** + * @var Admin_Notices $admin_notices + */ + $admin_notices = Plugin::elementor()->admin->get_component( 'admin-notices' ); + + $admin_notices->print_admin_notice( [ + 'title' => esc_html__( 'Meet the new Theme Builder: more intuitive and visual than ever', 'elementor-pro' ), + 'description' => esc_html__( 'With the new Theme Builder you can visually manage every part of your site intuitively, making the task of designing a complete website that much easier', 'elementor-pro' ), + 'button' => [ + 'text' => esc_html__( 'Try it now', 'elementor-pro' ), + 'class' => 'elementor-button e-accent', + 'url' => Plugin::elementor()->app->get_settings( 'menu_url' ), + ], + ] ); + } + + return $views; + } + + private function get_admin_templates_url( $relative = false ) { + $base_url = Source_Local::ADMIN_MENU_SLUG; + + if ( ! $relative ) { + $base_url = admin_url( $base_url ); + } + + return add_query_arg( 'tabs_group', self::ADMIN_LIBRARY_TAB_GROUP, $base_url ); + } + + /** + * Get the conflicts between the active templates' conditions and new templates. + * + * @since 3.8.0 + * + * @param array $templates + * @return array + */ + public function get_conditions_conflicts( array $templates ) : array { + $conflicts = []; + + foreach ( $templates as $template_id => $template ) { + if ( empty( $template['conditions'] ) ) { + continue; + } + + foreach ( $template['conditions'] as $condition ) { + $condition = rtrim( implode( '/', $condition ), '/' ); + $condition_conflicts = $this->get_conditions_manager()->get_conditions_conflicts_by_location( $condition, $template['location'] ); + + if ( $condition_conflicts ) { + $conflicts[ $template_id ] = $condition_conflicts; + } + } + } + + return $conflicts; + } + + /** + * TODO: BC - remove in 3.11.0|4.1.0 + * Add conflicts to import result. + * + * @since 3.7.0 + * + * @param array $result + * @return array + */ + private function add_conflicts_to_import_result( array $result ) { + $manifest_data = $result['manifest']; + + if ( empty( $manifest_data['templates'] ) ) { + return $result; + } + + $result['conflicts'] = $this->get_conditions_conflicts( $manifest_data['templates'] ); + + return $result; + } + + /** + * Add attributes to the document wrapper element. + * + * @param array $attributes - The document's wrapper element attributes. + * @param Document $document + * + * @return array + */ + public function add_document_attributes( array $attributes, Document $document ): array { + $attributes['data-elementor-post-type'] = $document->get_post()->post_type; + + return $attributes; + } + + public function __construct() { + parent::__construct(); + + require __DIR__ . '/api.php'; + + $this->add_component( 'import_export_import', new ImportExportCustomization\Import() ); + $this->add_component( 'import_export_export', new ImportExportCustomization\Export() ); + $this->add_component( 'import_export_revert', new ImportExportCustomization\Revert() ); + + $this->add_component( 'theme_support', new Classes\Theme_Support() ); + $this->add_component( 'conditions', new Classes\Conditions_Manager() ); + $this->add_component( 'templates_types', new Classes\Templates_Types_Manager() ); + $this->add_component( 'preview', new Classes\Preview_Manager() ); + $this->add_component( 'locations', new Classes\Locations_Manager() ); + + add_action( 'elementor/controls/register', [ $this, 'register_controls' ] ); + + // Editor + add_action( 'elementor/editor/init', [ $this, 'on_elementor_editor_init' ] ); + add_filter( 'elementor/document/config', [ $this, 'document_config' ], 10, 2 ); + add_filter( 'elementor/document/wrapper_attributes', [ $this, 'add_document_attributes' ], 10, 2 ); + + // Admin + add_action( 'admin_head', [ $this, 'admin_head' ] ); + add_filter( 'add_menu_classes', [ $this, 'hide_admin_app_submenu' ], 9 /* Before core submenu fixes */ ); + add_action( 'manage_' . Source_Local::CPT . '_posts_custom_column', [ $this, 'admin_columns_content' ], 10, 2 ); + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'print_location_field' ] ); + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'print_post_type_field' ] ); + + if ( Plugin::elementor()->experiments->is_feature_active( 'admin_menu_rearrangement' ) ) { + add_action( 'elementor/admin/menu_registered/elementor', function( MainMenu $menu ) { + $this->register_admin_menu( $menu ); + } ); + } else { + add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu ) { + $this->register_admin_menu_legacy( $admin_menu ); + }, static::ADMIN_MENU_PRIORITY /* After "Popups" */ ); + + // TODO: BC - Remove after `Admin_Menu_Manager` will be the standard. + add_action( 'admin_menu', function () { + if ( did_action( 'elementor/admin/menu/register' ) ) { + return; + } + + add_submenu_page( + Source_Local::ADMIN_MENU_SLUG, + '', + esc_html__( 'Theme Builder', 'elementor-pro' ), + 'publish_posts', + $this->get_admin_templates_url( true ) + ); + }, 22 /* After core promotion menu */ ); + } + + add_filter( 'elementor/template-library/create_new_dialog_types', [ $this, 'create_new_dialog_types' ] ); + add_filter( 'views_edit-' . Source_Local::CPT, [ $this, 'print_new_theme_builder_promotion' ], 9 ); + + // Moved into the IE module \ElementorPro\Core\App\Modules\ImportExport\Module::add_actions + // TODO: remove in 3.10.0 + add_filter( 'elementor/import/stage_1/result', function ( array $result ) { + return $this->add_conflicts_to_import_result( $result ); + }); + + // Common + add_filter( 'elementor/finder/categories', [ $this, 'add_finder_items' ] ); + + add_filter( 'elementor/import-export-customization/export/templates_data', [ $this->get_component( 'import_export_export' ), 'add_theme_builder_to_export' ], 10, 3 ); + add_filter( 'elementor/import-export-customization/import/templates_result', [ $this->get_component( 'import_export_import' ), 'add_theme_builder_to_import' ], 10, 4 ); + add_action( 'elementor/import-export-customization/revert/templates', [ $this->get_component( 'import_export_revert' ), 'revert_theme_builder_templates_conditions' ], 10, 1 ); + } +} diff --git a/modules/theme-builder/skins/post-comments-skin-classic.php b/modules/theme-builder/skins/post-comments-skin-classic.php new file mode 100644 index 00000000..209a9a27 --- /dev/null +++ b/modules/theme-builder/skins/post-comments-skin-classic.php @@ -0,0 +1,490 @@ +start_controls_section( + 'section_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'default' => '[field id="comment-count"]', + 'label_block' => true, + 'dynamic' => [ + 'types' => [ + 'text', + ], + 'apply_on' => 'value', + 'allow_free_text' => true, + 'allow_multiple' => true, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_gravatar', + [ + 'label' => esc_html__( 'Gravatar', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Comments', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 10, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment' => 'margin-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'row_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ffffff', + 'selectors' => [ + '{{WRAPPER}} .elementor-comment' => 'background-color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'row_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment' => 'border-color: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'row_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'placeholder' => '1', + 'selectors' => [ + '{{WRAPPER}} .elementor-comment' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'row_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_meta_style', + [ + 'label' => esc_html__( 'Meta', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'meta_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 0, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-meta' => 'padding-bottom: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'meta_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-meta' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'meta_typography', + 'selector' => '{{WRAPPER}} .elementor-comment .comment-meta', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_content_style', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'content_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-content' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content__typography', + 'selector' => '{{WRAPPER}} .elementor-comment .comment-content', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_reply_button_style', + [ + 'label' => esc_html__( 'Reply Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'tabs_reply_button_style' ); + + $this->start_controls_tab( + 'tab_reply_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'reply_button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'reply_button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-comment .comment-reply-link', + ] + ); + + $this->add_control( + 'reply_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_ACCENT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), [ + 'name' => 'reply_button_border', + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'placeholder' => '1px', + 'default' => '1px', + 'selector' => '{{WRAPPER}} .elementor-comment .comment-reply-link', + ] + ); + + $this->add_control( + 'reply_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'reply_button_text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_reply_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'reply_button_background_hover_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'reply_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-comment .comment-reply-link:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + $this->get_control_id( 'reply_button_border_border!' ) => '', + ], + ] + ); + + $this->add_control( + 'reply_button_hover_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + public function render() { + + Module::instance()->get_preview_manager()->switch_to_preview_query(); + + // Hack to remove template comment form + $comments_template_callback = function() { + return __DIR__ . '/../views/comments-template.php'; + }; + + add_filter( 'comments_template', $comments_template_callback ); + + // The `comments_template` doesn't has an API to pass current widget instance, so make it global + $GLOBALS['post_comment_skin_classic'] = $this; + + comments_template(); + + remove_filter( 'comments_template', $comments_template_callback ); + + unset( $GLOBALS['post_comment_skin_classic'] ); + + Module::instance()->get_preview_manager()->restore_current_query(); + } + + public function comment_callback( $comment, $args, $depth ) { + $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; + $class = 'elementor-comment'; + if ( ! empty( $args['has_children'] ) ) { + $class .= ' parent'; + } + ?> + < id="comment-" > +
      +
      +
      + + %s', get_comment_author_link( $comment ) ), + '', + '' + ); + ?> +
      + + + + comment_approved ) : ?> +

      + +
      + +
      + +
      + + 'div-comment', + 'depth' => $depth, + 'max_depth' => $args['max_depth'], + 'before' => '
      ', + 'after' => '
      ', + ] ) ); + ?> +
      + > + parent->query_posts(); + + $wp_query = $this->parent->get_query(); + + if ( ! $wp_query->found_posts ) { + $this->render_loop_header(); + + $should_escape = true; + + /** + * Should escape 'nothing found' message. + * + * Filters the ability for escaping HTML tags on archive pages that return no + * result. + * + * By default Elementor removes HTML tags from the 'nothing found' message added + * by the user, for security reasons. This hook allows developers to change this + * behaviour. By setting this to `false`, Elementor will increase flexibility + * and allow the user to add HTML tags to the message. + * + * @param bool $should_escape Whether to escape 'nothing found' message. + */ + $should_escape = apply_filters( 'elementor_pro/theme_builder/archive/escape_nothing_found_message', $should_escape ); + + $message = $this->parent->get_settings_for_display( 'nothing_found_message' ); + if ( $should_escape ) { + $message = esc_html( $message ); + } + + ?> +
      + +
      + render_loop_footer(); + + return; + } + + parent::render(); + } +} diff --git a/modules/theme-builder/skins/posts-archive-skin-cards.php b/modules/theme-builder/skins/posts-archive-skin-cards.php new file mode 100644 index 00000000..d466f633 --- /dev/null +++ b/modules/theme-builder/skins/posts-archive-skin-cards.php @@ -0,0 +1,34 @@ +register_core_location( 'header' ); + $manager->register_core_location( 'footer' ); + } + + public function metabox_capability( $capability ) { + if ( Source_Local::CPT === get_post_type() ) { + $capability = 'do_not_allow'; + } + + return $capability; + } + + public function do_header() { + $did_location = Module::instance()->get_locations_manager()->do_location( 'header' ); + if ( $did_location ) { + remove_action( 'generate_header', 'generate_construct_header' ); + remove_action( 'generate_after_header', 'generate_add_navigation_after_header', 5 ); + } + } + + public function do_footer() { + $did_location = Module::instance()->get_locations_manager()->do_location( 'footer' ); + if ( $did_location ) { + remove_action( 'generate_footer', 'generate_construct_footer' ); + remove_action( 'generate_footer', 'generate_construct_footer_widgets', 5 ); + } + } + + public function body_classes( $classes ) { + if ( in_array( 'elementor-template-full-width', $classes ) ) { + $classes[] = 'full-width-content'; + } + + return $classes; + } + + public function __construct() { + add_action( 'elementor/theme/register_locations', [ $this, 'register_locations' ] ); + add_filter( 'generate_metabox_capability', [ $this, 'metabox_capability' ] ); + + add_action( 'generate_header', [ $this, 'do_header' ], 0 ); + add_action( 'generate_footer', [ $this, 'do_footer' ], 0 ); + + add_filter( 'body_class', [ $this, 'body_classes' ], 11 ); + } +} diff --git a/modules/theme-builder/theme-support/safe-mode-theme-support.php b/modules/theme-builder/theme-support/safe-mode-theme-support.php new file mode 100644 index 00000000..1b3ffae3 --- /dev/null +++ b/modules/theme-builder/theme-support/safe-mode-theme-support.php @@ -0,0 +1,34 @@ +register_core_location( 'header' ); + $manager->register_core_location( 'footer' ); + } + + public function do_header() { + elementor_theme_do_location( 'header' ); + } + + public function do_footer() { + elementor_theme_do_location( 'footer' ); + } + + public function __construct() { + add_action( 'elementor/theme/register_locations', [ $this, 'register_locations' ] ); + + add_action( 'elementor/page_templates/canvas/before_content', [ $this, 'do_header' ], 0 ); + add_action( 'elementor/page_templates/canvas/after_content', [ $this, 'do_footer' ], 0 ); + } +} diff --git a/modules/theme-builder/views/comments-template.php b/modules/theme-builder/views/comments-template.php new file mode 100644 index 00000000..2eaa7fb3 --- /dev/null +++ b/modules/theme-builder/views/comments-template.php @@ -0,0 +1,53 @@ + +

      + + + +

      + get_instance_value( 'title' ) ); ?> +

      + + + +
        + [ $skin, 'comment_callback' ], + ] ); + ?> +
      + + + + + +

      get_instance_value( 'title' ) ); ?>

      + + + +

      + + + + + + + + + + diff --git a/modules/theme-builder/views/theme-support-footer.php b/modules/theme-builder/views/theme-support-footer.php new file mode 100644 index 00000000..39607e83 --- /dev/null +++ b/modules/theme-builder/views/theme-support-footer.php @@ -0,0 +1,14 @@ +get_locations_manager(); +$location_manager->do_location( 'footer' ); ?> + + + + + diff --git a/modules/theme-builder/views/theme-support-header.php b/modules/theme-builder/views/theme-support-header.php new file mode 100644 index 00000000..0e6708f0 --- /dev/null +++ b/modules/theme-builder/views/theme-support-header.php @@ -0,0 +1,33 @@ +get_locations_manager(); +?> + +> + + + + + + <?php + // PHPCS - already escaped by WordPress. + echo wp_get_document_title(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> + + + + +> +do_location( 'header' ); +?> diff --git a/modules/theme-builder/widgets/archive-posts.php b/modules/theme-builder/widgets/archive-posts.php new file mode 100644 index 00000000..5a08be26 --- /dev/null +++ b/modules/theme-builder/widgets/archive-posts.php @@ -0,0 +1,166 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-posts' ]; + } + + protected function register_skins() { + $this->add_skin( new Skins\Posts_Archive_Skin_Classic( $this ) ); + $this->add_skin( new Skins\Posts_Archive_Skin_Cards( $this ) ); + $this->add_skin( new Skins\Posts_Archive_Skin_Full_Content( $this ) ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->register_pagination_section_controls(); + + $this->register_advanced_section_controls(); + + $this->update_control( + 'pagination_type', + [ + 'default' => 'numbers', + ] + ); + } + + public function register_advanced_section_controls() { + $this->start_controls_section( + 'section_advanced', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'It seems we can’t find what you’re looking for.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_nothing_found_style', + [ + 'tab' => Controls_Manager::TAB_STYLE, + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'condition' => [ + 'nothing_found_message!' => '', + ], + ] + ); + + $this->add_control( + 'nothing_found_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-posts-nothing-found' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'nothing_found_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-posts-nothing-found', + ] + ); + + $this->end_controls_section(); + } + + public function query_posts() { + global $wp_query; + + $query_vars = $wp_query->query_vars; + + /** + * Posts archive query vars. + * + * Filters the post query variables when the theme loads the posts archive page. + * + * @since 2.0.0 + * + * @param array $query_vars The query variables for the `WP_Query`. + */ + $query_vars = apply_filters( 'elementor/theme/posts_archive/query_posts/query_vars', $query_vars ); + + if ( $query_vars !== $wp_query->query_vars ) { + $this->query = new \WP_Query( $query_vars ); // SQL_CALC_FOUND_ROWS is used. + } else { + $this->query = $wp_query; + } + + Query_Control::add_to_avoid_list( wp_list_pluck( $this->query->posts, 'ID' ) ); + } +} diff --git a/modules/theme-builder/widgets/archive-title.php b/modules/theme-builder/widgets/archive-title.php new file mode 100644 index 00000000..a236e948 --- /dev/null +++ b/modules/theme-builder/widgets/archive-title.php @@ -0,0 +1,40 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/theme-builder/widgets/page-title.php b/modules/theme-builder/widgets/page-title.php new file mode 100644 index 00000000..7088314f --- /dev/null +++ b/modules/theme-builder/widgets/page-title.php @@ -0,0 +1,40 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/theme-builder/widgets/post-content.php b/modules/theme-builder/widgets/post-content.php new file mode 100644 index 00000000..8f35f13e --- /dev/null +++ b/modules/theme-builder/widgets/post-content.php @@ -0,0 +1,120 @@ +start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'text-align: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + // Post CSS should not be printed here because it overrides the already existing post CSS. + $this->render_post_content( false, false ); + } + + public function render_plain_content() {} + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/theme-builder/widgets/post-excerpt.php b/modules/theme-builder/widgets/post-excerpt.php new file mode 100644 index 00000000..2df86fec --- /dev/null +++ b/modules/theme-builder/widgets/post-excerpt.php @@ -0,0 +1,232 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + $optimized_markup = Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ) && ! $this->has_widget_inner_wrapper(); + $widget_container_selector = $optimized_markup ? '' : ' .elementor-widget-container'; + + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'excerpt', + [ + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'dynamic' => [ + 'active' => true, + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'post-excerpt' ), + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + "{{WRAPPER}}{$widget_container_selector}" => 'text-align: {{VALUE}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => "{{WRAPPER}}{$widget_container_selector}", + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'text_shadow', + 'selector' => '{{WRAPPER}}', + ] + ); + + $this->add_responsive_control( + 'paragraph_spacing', + [ + 'label' => esc_html__( 'Paragraph Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'min' => 0.1, + 'max' => 20, + ], + ], + 'selectors' => [ + "{{WRAPPER}}{$widget_container_selector}" => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'separator', + [ + 'type' => Controls_Manager::DIVIDER, + ] + ); + + $this->start_controls_tabs( 'link_colors' ); + + $this->start_controls_tab( + 'colors_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + "{{WRAPPER}}{$widget_container_selector}" => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'link_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} a' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'colors_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'link_hover_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} a:hover, {{WRAPPER}} a:focus' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'link_hover_color_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 's', + ], + 'selectors' => [ + '{{WRAPPER}} a' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function render() { + $this->print_unescaped_setting( 'excerpt' ); + } +} diff --git a/modules/theme-builder/widgets/post-featured-image.php b/modules/theme-builder/widgets/post-featured-image.php new file mode 100644 index 00000000..f19f15d9 --- /dev/null +++ b/modules/theme-builder/widgets/post-featured-image.php @@ -0,0 +1,60 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'image', + [ + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'post-featured-image' ), + ], + ], + [ + 'recursive' => true, + ] + ); + } + + protected function get_html_wrapper_class() { + return parent::get_html_wrapper_class() . ' elementor-widget-' . parent::get_name(); + } +} diff --git a/modules/theme-builder/widgets/post-title.php b/modules/theme-builder/widgets/post-title.php new file mode 100644 index 00000000..299ec8ef --- /dev/null +++ b/modules/theme-builder/widgets/post-title.php @@ -0,0 +1,48 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function get_dynamic_tag_name() { + return 'post-title'; + } + + public function get_common_args() { + return [ + '_css_classes' => [ + 'default' => 'entry-title', + ], + ]; + } +} diff --git a/modules/theme-builder/widgets/site-logo.php b/modules/theme-builder/widgets/site-logo.php new file mode 100644 index 00000000..8bbfd2ca --- /dev/null +++ b/modules/theme-builder/widgets/site-logo.php @@ -0,0 +1,216 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'section_image', + [ + 'label' => esc_html__( 'Site Logo', 'elementor-pro' ), + ] + ); + + $this->update_control( + 'image', + [ + 'label' => esc_html__( 'Site Logo', 'elementor-pro' ), + 'type' => Control_Media_Preview::CONTROL_TYPE, + 'src' => $this->get_site_logo(), + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'site-logo' ), + ], + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'image_size', + [ + 'separator' => 'before', + 'default' => 'full', + ] + ); + + $this->update_control( + 'link_to', + [ + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'site_url' => esc_html__( 'Site URL', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom URL', 'elementor-pro' ), + 'file' => esc_html__( 'Media File', 'elementor-pro' ), + ], + 'default' => 'site_url', + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'caption_source', + [ + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'attachment' => esc_html__( 'Attachment Caption', 'elementor-pro' ), + ], + ] + ); + + $this->remove_control( 'caption' ); + + $this->add_control( + 'change_logo_cta', + [ + 'type' => Controls_Manager::BUTTON, + 'label_block' => true, + 'show_label' => false, + 'button_type' => 'default elementor-button-center', + 'text' => esc_html__( 'Change Site Logo', 'elementor-pro' ), + 'event' => 'elementorProSiteLogo:change', + ], + [ + 'position' => [ + 'of' => 'image', + 'type' => 'control', + 'at' => 'after', + ], + ] + ); + } + + /** + * TODO: Remove this method when Elementor Core 3.11.0 is required. + * Duplicate of render() method from Elementor\Widget_Image class, so it will use the get_link_url() method. + * + * @return void + */ + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['image']['url'] ) ) { + return; + } + + $has_caption = $this->has_caption( $settings ); + + $link = $this->get_link_url( $settings ); + + if ( $link ) { + $this->add_link_attributes( 'link', $link ); + + if ( Plugin::elementor()->editor->is_edit_mode() ) { + $this->add_render_attribute( 'link', 'class', 'elementor-clickable' ); + } + + if ( 'file' === $settings['link_to'] ) { + $this->add_lightbox_data_attributes( 'link', $settings['image']['id'], $settings['open_lightbox'] ); + } + } ?> + +
      + + + print_render_attribute_string( 'link' ); ?>> + + + + + + +
      get_caption( $settings ) ); + ?>
      + + +
      + + Plugin::elementor()->dynamic_tags->get_tag_data_content( null, 'site-url' ) ?? '' ]; + + default: + return [ 'url' => $settings['image']['url'] ]; + } + } + + // TODO: Remove this method when removing the render() method. + private function has_caption( $settings ) { + return ( ! empty( $settings['caption_source'] ) && 'none' !== $settings['caption_source'] ); + } + + // TODO: Remove this method when removing the render() method. + private function get_caption( $settings ) { + $caption = ''; + + if ( ! empty( $settings['caption_source'] ) && 'attachment' === $settings['caption_source'] ) { + $caption = wp_get_attachment_caption( $settings['image']['id'] ); + } + + return $caption; + } + + // Get the site logo from the dynamic tag + private function get_site_logo(): string { + $site_logo = Plugin::elementor()->dynamic_tags->get_tag_data_content( null, 'site-logo' ); + return $site_logo['url'] ?? Utils::get_placeholder_image_src(); + } +} diff --git a/modules/theme-builder/widgets/site-title.php b/modules/theme-builder/widgets/site-title.php new file mode 100644 index 00000000..d6c60598 --- /dev/null +++ b/modules/theme-builder/widgets/site-title.php @@ -0,0 +1,93 @@ +update_control( + 'title', + [ + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'site-title' ), + ], + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'link', + [ + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'site-url' ), + ], + ], + [ + 'recursive' => true, + ] + ); + + $this->add_control( + 'site_identity_notice', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To edit the title of your site, go to %1$sSite Identity%2$s.', 'elementor-pro' ), + '', + '' + ), + ], + [ + 'position' => [ + 'of' => 'title', + 'type' => 'control', + 'at' => 'before', + ], + ] + ); + } + + protected function get_html_wrapper_class() { + return parent::get_html_wrapper_class() . ' elementor-widget-' . parent::get_name(); + } + + public function has_widget_inner_wrapper(): bool { + return ! Plugin::elementor()->experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/theme-builder/widgets/title-widget-base.php b/modules/theme-builder/widgets/title-widget-base.php new file mode 100644 index 00000000..e98432c8 --- /dev/null +++ b/modules/theme-builder/widgets/title-widget-base.php @@ -0,0 +1,62 @@ +documents->get( get_the_ID() ); + if ( $current_doc && 'yes' === $current_doc->get_settings( 'hide_title' ) ) { + return false; + } + + return true; + } + + protected function register_controls() { + parent::register_controls(); + + $dynamic_tag_name = $this->get_dynamic_tag_name(); + + $this->update_control( + 'title', + [ + 'dynamic' => [ + 'default' => ProPlugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, $dynamic_tag_name ), + ], + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'header_size', + [ + 'default' => 'h1', + ] + ); + } + + protected function get_html_wrapper_class() { + return parent::get_html_wrapper_class() . ' elementor-page-title elementor-widget-' . parent::get_name(); + } + + public function render() { + if ( $this->should_show_page_title() ) { + return parent::render(); + } + } +} diff --git a/modules/theme-elements/module.php b/modules/theme-elements/module.php new file mode 100644 index 00000000..f1e3c776 --- /dev/null +++ b/modules/theme-elements/module.php @@ -0,0 +1,86 @@ +is_yoast_seo_active() ) { + $widgets[] = 'Breadcrumbs'; + } + + return $widgets; + } + + public function is_yoast_seo_active() { + return function_exists( 'yoast_breadcrumb' ); + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/theme-elements/assets/scss/frontend.scss` + * to `/assets/css/widget-theme-elements.min.css`. + * + * @return void + */ + public function register_styles() { + $widget_styles = $this->get_widgets_style_list(); + + foreach ( $widget_styles as $widget_style_name ) { + wp_register_style( + $widget_style_name, + $this->get_css_assets_url( $widget_style_name, null, true, true ), + [ 'elementor-frontend' ], + ELEMENTOR_PRO_VERSION + ); + } + } + + private function get_widgets_style_list(): array { + return [ + 'widget-author-box', + 'widget-breadcrumbs', + 'widget-post-info', + 'widget-post-navigation', + 'widget-search-form', + 'widget-sitemap', + ]; + } +} diff --git a/modules/theme-elements/widgets/author-box.php b/modules/theme-elements/widgets/author-box.php new file mode 100644 index 00000000..c0884352 --- /dev/null +++ b/modules/theme-elements/widgets/author-box.php @@ -0,0 +1,1607 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-author-box' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_author_info', + [ + 'label' => esc_html__( 'Author Info', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'source', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'current', + 'options' => [ + 'current' => esc_html__( 'Current Author', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'show_avatar', + [ + 'label' => esc_html__( 'Profile Picture', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'prefix_class' => 'elementor-author-box--avatar-', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + 'condition' => [ + 'source' => 'current', + ], + 'render_type' => 'template', + ] + ); + + // Used by the WordPress `get_avatar_url()` function to set the image size. + $this->add_control( + 'avatar_size', + [ + 'label' => esc_html__( 'Picture Size', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 300, + 'condition' => [ + 'source' => 'current', + 'show_avatar' => 'yes', + ], + ] + ); + + $this->add_control( + 'author_avatar', + [ + 'label' => esc_html__( 'Profile Picture', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'condition' => [ + 'source' => 'custom', + ], + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'show_name', + [ + 'label' => esc_html__( 'Display Name', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'prefix_class' => 'elementor-author-box--name-', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'condition' => [ + 'source' => 'current', + ], + 'render_type' => 'template', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'author_name', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'John Doe', 'elementor-pro' ), + 'condition' => [ + 'source' => 'custom', + ], + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'author_name_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'h4', + ] + ); + + $this->add_control( + 'link_to', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'website' => esc_html__( 'Website', 'elementor-pro' ), + 'posts_archive' => esc_html__( 'Posts Archive', 'elementor-pro' ), + ], + 'condition' => [ + 'source' => 'current', + ], + 'description' => esc_html__( 'Link for the Author Name and Image', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_biography', + [ + 'label' => esc_html__( 'Biography', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'prefix_class' => 'elementor-author-box--biography-', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'condition' => [ + 'source' => 'current', + ], + 'render_type' => 'template', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'show_link', + [ + 'label' => esc_html__( 'Archive Button', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'prefix_class' => 'elementor-author-box--link-', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'no', + 'condition' => [ + 'source' => 'current', + ], + 'render_type' => 'template', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'author_website', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'condition' => [ + 'source' => 'custom', + ], + 'description' => esc_html__( 'Link for the Author Name and Image', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'author_bio', + [ + 'label' => esc_html__( 'Biography', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ), + 'rows' => 3, + 'condition' => [ + 'source' => 'custom', + ], + 'separator' => 'before', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'posts_url', + [ + 'label' => esc_html__( 'Archive Button', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'source' => 'custom', + ], + ] + ); + + $this->add_control( + 'link_text', + [ + 'label' => esc_html__( 'Archive Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'All Posts', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'above' => [ + 'title' => esc_html__( 'Above', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'separator' => 'before', + 'prefix_class' => 'elementor-author-box--layout-image-', + ] + ); + + $this->add_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-author-box--align-', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'image_vertical_align', + [ + 'label' => esc_html__( 'Vertical Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + ], + 'prefix_class' => 'elementor-author-box--image-valign-', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'layout', + 'operator' => '!==', + 'value' => 'above', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'layout', + 'operator' => '!==', + 'value' => 'above', + ], + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'image_size', + [ + 'label' => esc_html__( 'Image Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__avatar img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'image_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body.rtl {{WRAPPER}}.elementor-author-box--layout-image-left .elementor-author-box__avatar, + body:not(.rtl) {{WRAPPER}}:not(.elementor-author-box--layout-image-above) .elementor-author-box__avatar' => 'margin-right: {{SIZE}}{{UNIT}}; margin-left: 0;', + + 'body:not(.rtl) {{WRAPPER}}.elementor-author-box--layout-image-right .elementor-author-box__avatar, + body.rtl {{WRAPPER}}:not(.elementor-author-box--layout-image-above) .elementor-author-box__avatar' => 'margin-left: {{SIZE}}{{UNIT}}; margin-right:0;', + + '{{WRAPPER}}.elementor-author-box--layout-image-above .elementor-author-box__avatar' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'image_border', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__avatar img' => 'border-style: solid', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'image_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#000', + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__avatar img' => 'border-color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'image_border', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'image_border', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'image_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__avatar img' => 'border-width: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + [ + 'name' => 'image_border', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'image_border', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__avatar img' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-author-box__avatar img', + 'fields_options' => [ + 'box_shadow_type' => [ + 'separator' => 'default', + ], + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_avatar', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_avatar[url]', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_text_style', + [ + 'label' => esc_html__( 'Author', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_name_style', + [ + 'label' => esc_html__( 'Name', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_name', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'name_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__name' => 'color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_name', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'name_typography', + 'selector' => '{{WRAPPER}} .elementor-author-box__name', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_name', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'name_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__name' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_name', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_name', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'heading_bio_style', + [ + 'label' => esc_html__( 'Biography', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_biography', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_bio', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'bio_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__bio' => 'color: {{VALUE}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_biography', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_bio', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'bio_typography', + 'selector' => '{{WRAPPER}} .elementor-author-box__bio', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_biography', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_bio', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'bio_gap', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__bio' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'current', + ], + [ + 'name' => 'show_biography', + 'operator' => '===', + 'value' => 'yes', + ], + ], + ], + [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'source', + 'operator' => '===', + 'value' => 'custom', + ], + [ + 'name' => 'author_bio', + 'operator' => '!==', + 'value' => '', + ], + ], + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_button', + [ + 'label' => 'Button', + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'color: {{VALUE}}; border-color: {{VALUE}}', + ], + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .elementor-author-box__button', + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button:hover' => 'border-color: {{VALUE}}; color: {{VALUE}};', + ], + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_background_hover_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button:hover' => 'background-color: {{VALUE}};', + ], + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'transition-duration: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_hover_animation', + [ + 'label' => esc_html__( 'Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'border-width: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'border-radius: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->add_control( + 'button_text_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-author-box__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + 'condition' => [ + 'link_text!' => '', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + $author = []; + $link_tag = 'div'; + $link_url = ''; + $link_target = ''; + $author_name_tag = Utils::validate_html_tag( $settings['author_name_tag'] ); + + $custom_src = ( 'custom' === $settings['source'] ); + + if ( 'current' === $settings['source'] ) { + + $avatar_args['size'] = $settings['avatar_size']; + + $user_id = get_the_author_meta( 'ID' ); + $author['avatar'] = get_avatar_url( $user_id, $avatar_args ); + $author['display_name'] = get_the_author_meta( 'display_name' ); + $author['website'] = get_the_author_meta( 'user_url' ); + $author['bio'] = get_the_author_meta( 'description' ); + $author['posts_url'] = get_author_posts_url( $user_id ); + + } elseif ( $custom_src ) { + + if ( ! empty( $settings['author_avatar']['url'] ) ) { + $avatar_src = $settings['author_avatar']['url']; + + if ( $settings['author_avatar']['id'] ) { + $attachment_image_src = wp_get_attachment_image_src( $settings['author_avatar']['id'], 'medium' ); + + if ( ! empty( $attachment_image_src[0] ) ) { + $avatar_src = $attachment_image_src[0]; + } + } + + $author['avatar'] = $avatar_src; + } + + $author['display_name'] = $settings['author_name']; + $author['website'] = $settings['author_website']['url']; + $author['bio'] = wpautop( $settings['author_bio'] ); + $author['posts_url'] = $settings['posts_url']['url']; + } + + $print_avatar = ( ( ! $custom_src && 'yes' === $settings['show_avatar'] ) || ( $custom_src && ! empty( $author['avatar'] ) ) ); + $print_name = ( ( ! $custom_src && 'yes' === $settings['show_name'] ) || ( $custom_src && ! empty( $author['display_name'] ) ) ); + $print_bio = ( ( ! $custom_src && 'yes' === $settings['show_biography'] ) || ( $custom_src && ! empty( $author['bio'] ) ) ); + $print_link = ( ( ! $custom_src && 'yes' === $settings['show_link'] ) && ! empty( $settings['link_text'] ) || ( $custom_src && ! empty( $author['posts_url'] ) && ! empty( $settings['link_text'] ) ) ); + + if ( ! empty( $settings['link_to'] ) || $custom_src ) { + if ( ( $custom_src || 'website' === $settings['link_to'] ) && ! empty( $author['website'] ) ) { + $link_tag = 'a'; + $link_url = $author['website']; + + if ( $custom_src ) { + $link_target = $settings['author_website']['is_external'] ? '_blank' : ''; + } else { + $link_target = '_blank'; + } + } elseif ( 'posts_archive' === $settings['link_to'] && ! empty( $author['posts_url'] ) ) { + $link_tag = 'a'; + $link_url = $author['posts_url']; + } + + if ( ! empty( $link_url ) ) { + $this->add_render_attribute( 'author_link', 'href', esc_url( $link_url ) ); + + if ( ! empty( $link_target ) ) { + $this->add_render_attribute( 'author_link', 'target', $link_target ); + } + } + } + + $this->add_render_attribute( + 'button', + 'class', [ + 'elementor-author-box__button', + 'elementor-button', + 'elementor-size-xs', + ] + ); + + if ( $print_link ) { + $this->add_render_attribute( 'button', 'href', esc_url( $author['posts_url'] ) ); + } + + if ( $print_link && ! empty( $settings['button_hover_animation'] ) ) { + $this->add_render_attribute( + 'button', + 'class', + 'elementor-animation-' . $settings['button_hover_animation'] + ); + } + + if ( $print_avatar ) { + $this->add_render_attribute( + 'avatar', + [ + 'src' => esc_url( $author['avatar'] ), + 'alt' => ( ! empty( $author['display_name'] ) ) + ? sprintf( + /* translators: %s: Author display name. */ + esc_attr__( 'Picture of %s', 'elementor-pro' ), + $author['display_name'] + ) + : esc_html__( 'Author picture', 'elementor-pro' ), + 'loading' => 'lazy', + ] + ); + } + + ?> +
      + + < print_render_attribute_string( 'author_link' ); ?> class="elementor-author-box__avatar"> + print_render_attribute_string( 'avatar' ); ?>> + > + + +
      + + < print_render_attribute_string( 'author_link' ); ?>> + < class="elementor-author-box__name"> + + > + > + + + +
      + +
      + + + + print_render_attribute_string( 'button' ); ?>> + + + +
      +
      + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-breadcrumbs' ]; + } + + public function get_keywords() { + return [ 'yoast', 'seo', 'breadcrumbs', 'internal links' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_breadcrumbs_content', + [ + 'label' => esc_html__( 'Breadcrumbs', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor%s-align-', + ] + ); + + $this->add_control( + 'html_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'elementor-pro' ), + 'p' => 'p', + 'div' => 'div', + 'nav' => 'nav', + 'span' => 'span', + ], + 'default' => '', + ] + ); + + $this->add_control( + 'html_description', + [ + 'raw' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'Additional settings are available in the Yoast SEO %1$sBreadcrumbs Panel%2$s', 'elementor-pro' ), + sprintf( '', admin_url( 'admin.php?page=wpseo_titles#top#breadcrumbs' ) ), + '' + ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style', + [ + 'label' => esc_html__( 'Breadcrumbs', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'selector' => '{{WRAPPER}}', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}' => 'color: {{VALUE}};', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_breadcrumbs_style' ); + + $this->start_controls_tab( + 'tab_color_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'link_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} a' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_color_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'link_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} a:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + private function get_html_tag() { + $html_tag = $this->get_settings( 'html_tag' ); + + if ( empty( $html_tag ) ) { + $html_tag = 'p'; + } + + return Utils::validate_html_tag( $html_tag ); + } + + protected function render() { + if ( class_exists( '\WPSEO_Breadcrumbs' ) ) { + $html_tag = $this->get_html_tag(); + WPSEO_Breadcrumbs::breadcrumb( '<' . $html_tag . ' id="breadcrumbs">', '' ); + } + + } + + public function get_group_name() { + return 'theme-elements'; + } +} diff --git a/modules/theme-elements/widgets/post-comments.php b/modules/theme-elements/widgets/post-comments.php new file mode 100644 index 00000000..71692d3e --- /dev/null +++ b/modules/theme-elements/widgets/post-comments.php @@ -0,0 +1,129 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Comments', 'elementor-pro' ), + ] + ); + + $this->add_control( + '_skin', + [ + 'type' => Controls_Manager::HIDDEN, + ] + ); + + $this->add_control( + 'skin_temp', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Theme Comments', 'elementor-pro' ), + ], + 'description' => esc_html__( 'The Theme Comments skin uses the currently active theme comments design and layout to display the comment form and comments.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'source_type', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + Module::SOURCE_TYPE_CURRENT_POST => esc_html__( 'Current Post', 'elementor-pro' ), + Module::SOURCE_TYPE_CUSTOM => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => Module::SOURCE_TYPE_CURRENT_POST, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'source_custom', + [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_POST, + ], + 'condition' => [ + 'source_type' => Module::SOURCE_TYPE_CUSTOM, + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + $settings = $this->get_settings(); + + if ( Module::SOURCE_TYPE_CUSTOM === $settings['source_type'] ) { + $post_id = (int) $settings['source_custom']; + Plugin::elementor()->db->switch_to_post( $post_id ); + } + + if ( ! comments_open() && ( Plugin::elementor()->preview->is_preview_mode() || Plugin::elementor()->editor->is_edit_mode() ) ) : + ?> + + db->restore_current_post(); + } + } + + public function get_group_name() { + return 'theme-elements'; + } +} diff --git a/modules/theme-elements/widgets/post-info.php b/modules/theme-elements/widgets/post-info.php new file mode 100644 index 00000000..71be52d5 --- /dev/null +++ b/modules/theme-elements/widgets/post-info.php @@ -0,0 +1,1104 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_style_depends(): array { + $style_depends = [ 'widget-post-info', 'widget-icon-list' ]; + + if ( Icons_Manager::is_migration_allowed() ) { + $style_depends[] = 'elementor-icons-fa-regular'; + $style_depends[] = 'elementor-icons-fa-solid'; + } + + return $style_depends; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_icon', + [ + 'label' => esc_html__( 'Meta Data', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'view', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'inline', + 'options' => [ + 'traditional' => [ + 'title' => esc_html__( 'Default', 'elementor-pro' ), + 'icon' => 'eicon-editor-list-ul', + ], + 'inline' => [ + 'title' => esc_html__( 'Inline', 'elementor-pro' ), + 'icon' => 'eicon-ellipsis-h', + ], + ], + 'render_type' => 'template', + 'classes' => 'elementor-control-start-end', + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'date', + 'options' => [ + 'author' => esc_html__( 'Author', 'elementor-pro' ), + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'time' => esc_html__( 'Time', 'elementor-pro' ), + 'comments' => esc_html__( 'Comments', 'elementor-pro' ), + 'terms' => esc_html__( 'Terms', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + ] + ); + + $repeater->add_control( + 'date_format', + [ + 'label' => esc_html__( 'Date Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'default', + 'options' => [ + 'default' => 'Default', + '0' => _x( 'March 6, 2018 (F j, Y)', 'Date Format', 'elementor-pro' ), + '1' => '2018-03-06 (Y-m-d)', + '2' => '03/06/2018 (m/d/Y)', + '3' => '06/03/2018 (d/m/Y)', + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => 'date', + ], + ] + ); + + $repeater->add_control( + 'custom_date_format', + [ + 'label' => esc_html__( 'Custom Date Format', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => 'F j, Y', + 'condition' => [ + 'type' => 'date', + 'date_format' => 'custom', + ], + 'description' => sprintf( + /* translators: %s: Allowed data letters (see: http://php.net/manual/en/function.date.php). */ + esc_html__( 'Use the letters: %s', 'elementor-pro' ), + 'l D d j S F m M n Y y' + ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'time_format', + [ + 'label' => esc_html__( 'Time Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'default', + 'options' => [ + 'default' => 'Default', + '0' => '3:31 pm (g:i a)', + '1' => '3:31 PM (g:i A)', + '2' => '15:31 (H:i)', + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'condition' => [ + 'type' => 'time', + ], + ] + ); + $repeater->add_control( + 'custom_time_format', + [ + 'label' => esc_html__( 'Custom Time Format', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => 'g:i a', + 'placeholder' => 'g:i a', + 'condition' => [ + 'type' => 'time', + 'time_format' => 'custom', + ], + 'description' => sprintf( + /* translators: %s: Allowed time letters (see: http://php.net/manual/en/function.time.php). */ + esc_html__( 'Use the letters: %s', 'elementor-pro' ), + 'g G H i a A' + ), + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'taxonomy', + [ + 'label' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'label_block' => true, + 'default' => [], + 'options' => $this->get_taxonomies(), + 'condition' => [ + 'type' => 'terms', + ], + ] + ); + + $repeater->add_control( + 'text_prefix', + [ + 'label' => esc_html__( 'Before', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'type!' => 'custom', + ], + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $repeater->add_control( + 'show_avatar', + [ + 'label' => esc_html__( 'Avatar', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'type' => 'author', + ], + ] + ); + + $repeater->add_responsive_control( + 'avatar_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} {{CURRENT_ITEM}} .elementor-icon-list-icon' => 'width: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'show_avatar' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'comments_custom_strings', + [ + 'label' => esc_html__( 'Custom Format', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => false, + 'condition' => [ + 'type' => 'comments', + ], + ] + ); + + $repeater->add_control( + 'string_no_comments', + [ + 'label' => esc_html__( 'No Comments', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'No Comments', 'elementor-pro' ), + 'condition' => [ + 'comments_custom_strings' => 'yes', + 'type' => 'comments', + ], + ] + ); + + $repeater->add_control( + 'string_one_comment', + [ + 'label' => esc_html__( 'One Comment', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'One Comment', 'elementor-pro' ), + 'condition' => [ + 'comments_custom_strings' => 'yes', + 'type' => 'comments', + ], + ] + ); + + $repeater->add_control( + 'string_comments', + [ + 'label' => esc_html__( 'Comments', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( '%s Comments', 'elementor-pro' ), + 'condition' => [ + 'comments_custom_strings' => 'yes', + 'type' => 'comments', + ], + ] + ); + + $repeater->add_control( + 'custom_text', + [ + 'label' => esc_html__( 'Custom', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'label_block' => true, + 'condition' => [ + 'type' => 'custom', + ], + ] + ); + + $repeater->add_control( + 'link', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'type!' => 'time', + ], + ] + ); + + $repeater->add_control( + 'custom_url', + [ + 'label' => esc_html__( 'Custom URL', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'type' => 'custom', + ], + ] + ); + + $repeater->add_control( + 'show_icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'default' => esc_html__( 'Default', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'default', + 'condition' => [ + 'show_avatar!' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'selected_icon', + [ + 'label' => esc_html__( 'Choose Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'condition' => [ + 'show_icon' => 'custom', + 'show_avatar!' => 'yes', + ], + ] + ); + + $this->add_control( + 'icon_list', + [ + 'label' => '', + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'type' => 'author', + 'selected_icon' => [ + 'value' => 'far fa-user-circle', + 'library' => 'fa-regular', + ], + ], + [ + 'type' => 'date', + 'selected_icon' => [ + 'value' => 'fas fa-calendar', + 'library' => 'fa-solid', + ], + ], + [ + 'type' => 'time', + 'selected_icon' => [ + 'value' => 'far fa-clock', + 'library' => 'fa-regular', + ], + ], + [ + 'type' => 'comments', + 'selected_icon' => [ + 'value' => 'far fa-comment-dots', + 'library' => 'fa-regular', + ], + ], + ], + 'title_field' => '{{{ elementor.helpers.renderIcon( this, selected_icon, {}, "i", "panel" ) || \'\' }}} {{{ type }}}', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_icon_list', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child)' => 'padding-bottom: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:first-child)' => 'margin-top: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item' => 'margin-right: calc({{SIZE}}{{UNIT}}/2); margin-left: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items' => 'margin-right: calc(-{{SIZE}}{{UNIT}}/2); margin-left: calc(-{{SIZE}}{{UNIT}}/2)', + 'body.rtl {{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:after' => 'left: calc(-{{SIZE}}{{UNIT}}/2)', + 'body:not(.rtl) {{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:after' => 'right: calc(-{{SIZE}}{{UNIT}}/2)', + ], + ] + ); + + $this->add_responsive_control( + 'icon_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'prefix_class' => 'elementor%s-align-', + ] + ); + + $this->add_control( + 'divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'content: ""', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + ], + 'default' => 'solid', + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child):after' => 'border-top-style: {{VALUE}};', + '{{WRAPPER}} .elementor-icon-list-items.elementor-inline-items .elementor-icon-list-item:not(:last-child):after' => 'border-left-style: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-items:not(.elementor-inline-items) .elementor-icon-list-item:not(:last-child):after' => 'border-top-width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-inline-items .elementor-icon-list-item:not(:last-child):after' => 'border-left-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'divider_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + '%' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => [ + 'divider' => 'yes', + 'view!' => 'inline', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'divider_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + '%' => [ + 'min' => 1, + 'max' => 100, + ], + ], + 'condition' => [ + 'divider' => 'yes', + 'view' => 'inline', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ddd', + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-item:not(:last-child):after' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_icon_style', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-icon i' => 'color: {{VALUE}};', + '{{WRAPPER}} .elementor-icon-list-icon svg' => 'fill: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + ] + ); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 14, + ], + 'range' => [ + 'px' => [ + 'min' => 6, + ], + 'em' => [ + 'max' => 0.6, + ], + 'rem' => [ + 'max' => 0.6, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-icon' => 'width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-icon-list-icon i' => 'font-size: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-icon-list-icon svg' => '--e-icon-list-icon-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_text_style', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'text_indent', + [ + 'label' => esc_html__( 'Indent', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-icon-list-text' => 'padding-left: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}} .elementor-icon-list-text' => 'padding-right: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-icon-list-text, {{WRAPPER}} .elementor-icon-list-text a' => 'color: {{VALUE}}', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'icon_typography', + 'selector' => '{{WRAPPER}} .elementor-icon-list-item', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->end_controls_section(); + } + + protected function get_taxonomies() { + $taxonomies = get_taxonomies( [ + 'show_in_nav_menus' => true, + ], 'objects' ); + + $options = [ + '' => esc_html__( 'Choose', 'elementor-pro' ), + ]; + + foreach ( $taxonomies as $taxonomy ) { + $options[ $taxonomy->name ] = $taxonomy->label; + } + + return $options; + } + + protected function get_meta_data( $repeater_item ) { + $item_data = []; + + switch ( $repeater_item['type'] ) { + case 'author': + $item_data['text'] = get_the_author_meta( 'display_name' ); + $item_data['icon'] = 'fa fa-user-circle-o'; // Default icon. + $item_data['selected_icon'] = [ + 'value' => 'far fa-user-circle', + 'library' => 'fa-regular', + ]; // Default icons. + $item_data['itemprop'] = 'author'; + + if ( 'yes' === $repeater_item['link'] ) { + $item_data['url'] = [ + 'url' => get_author_posts_url( get_the_author_meta( 'ID' ) ), + ]; + } + + if ( 'yes' === $repeater_item['show_avatar'] ) { + $item_data['image'] = get_avatar_url( get_the_author_meta( 'ID' ), 96 ); + } + + break; + + case 'date': + $custom_date_format = empty( $repeater_item['custom_date_format'] ) ? 'F j, Y' : $repeater_item['custom_date_format']; + + $format_options = [ + 'default' => 'F j, Y', + '0' => 'F j, Y', + '1' => 'Y-m-d', + '2' => 'm/d/Y', + '3' => 'd/m/Y', + 'custom' => $custom_date_format, + ]; + + $item_data['text'] = get_the_time( $format_options[ $repeater_item['date_format'] ] ); + $item_data['icon'] = 'fa fa-calendar'; // Default icon + $item_data['selected_icon'] = [ + 'value' => 'fas fa-calendar', + 'library' => 'fa-solid', + ]; // Default icons. + $item_data['itemprop'] = 'datePublished'; + + if ( 'yes' === $repeater_item['link'] ) { + $item_data['url'] = [ + 'url' => get_day_link( get_post_time( 'Y' ), get_post_time( 'm' ), get_post_time( 'j' ) ), + ]; + } + break; + + case 'time': + $custom_time_format = empty( $repeater_item['custom_time_format'] ) ? 'g:i a' : $repeater_item['custom_time_format']; + + $format_options = [ + 'default' => 'g:i a', + '0' => 'g:i a', + '1' => 'g:i A', + '2' => 'H:i', + 'custom' => $custom_time_format, + ]; + $item_data['text'] = get_the_time( $format_options[ $repeater_item['time_format'] ] ); + $item_data['icon'] = 'fa fa-clock-o'; // Default icon + $item_data['selected_icon'] = [ + 'value' => 'far fa-clock', + 'library' => 'fa-regular', + ]; // Default icons. + break; + + case 'comments': + if ( comments_open() ) { + $default_strings = [ + 'string_no_comments' => esc_html__( 'No Comments', 'elementor-pro' ), + 'string_one_comment' => esc_html__( 'One Comment', 'elementor-pro' ), + 'string_comments' => esc_html__( '%s Comments', 'elementor-pro' ), + ]; + + if ( 'yes' === $repeater_item['comments_custom_strings'] ) { + if ( ! empty( $repeater_item['string_no_comments'] ) ) { + $default_strings['string_no_comments'] = $repeater_item['string_no_comments']; + } + + if ( ! empty( $repeater_item['string_one_comment'] ) ) { + $default_strings['string_one_comment'] = $repeater_item['string_one_comment']; + } + + if ( ! empty( $repeater_item['string_comments'] ) ) { + $default_strings['string_comments'] = $repeater_item['string_comments']; + } + } + + $num_comments = (int) get_comments_number(); // get_comments_number returns only a numeric value + + if ( 0 === $num_comments ) { + $item_data['text'] = $default_strings['string_no_comments']; + } else { + $item_data['text'] = sprintf( _n( $default_strings['string_one_comment'], $default_strings['string_comments'], $num_comments, 'elementor-pro' ), $num_comments ); + } + + if ( 'yes' === $repeater_item['link'] ) { + $item_data['url'] = [ + 'url' => get_comments_link(), + ]; + } + $item_data['icon'] = 'fa fa-commenting-o'; // Default icon + $item_data['selected_icon'] = [ + 'value' => 'far fa-comment-dots', + 'library' => 'fa-regular', + ]; // Default icons. + $item_data['itemprop'] = 'commentCount'; + } + break; + + case 'terms': + $item_data['icon'] = 'fa fa-tags'; // Default icon + $item_data['selected_icon'] = [ + 'value' => 'fas fa-tags', + 'library' => 'fa-solid', + ]; // Default icons. + $item_data['itemprop'] = 'about'; + + $taxonomy = $repeater_item['taxonomy']; + $terms = wp_get_post_terms( get_the_ID(), $taxonomy ); + foreach ( $terms as $term ) { + $item_data['terms_list'][ $term->term_id ]['text'] = $term->name; + if ( 'yes' === $repeater_item['link'] ) { + $item_data['terms_list'][ $term->term_id ]['url'] = get_term_link( $term ); + } + } + break; + + case 'custom': + $item_data['text'] = $repeater_item['custom_text']; + $item_data['icon'] = 'fa fa-info-circle'; // Default icon. + $item_data['selected_icon'] = [ + 'value' => 'far fa-tags', + 'library' => 'fa-regular', + ]; // Default icons. + + if ( 'yes' === $repeater_item['link'] && ! empty( $repeater_item['custom_url'] ) ) { + $item_data['url'] = $repeater_item['custom_url']; + } + + break; + } + + $item_data['type'] = $repeater_item['type']; + + if ( ! empty( $repeater_item['text_prefix'] ) ) { + $item_data['text_prefix'] = esc_html( $repeater_item['text_prefix'] ); + } + + return $item_data; + } + + protected function render_item( $repeater_item ) { + $item_data = $this->get_meta_data( $repeater_item ); + $repeater_index = $repeater_item['_id']; + + if ( empty( $item_data['text'] ) && empty( $item_data['terms_list'] ) ) { + return; + } + + $has_link = false; + $link_key = 'link_' . $repeater_index; + $item_key = 'item_' . $repeater_index; + + $this->add_render_attribute( $item_key, 'class', + [ + 'elementor-icon-list-item', + 'elementor-repeater-item-' . $repeater_item['_id'], + ] + ); + + $active_settings = $this->get_active_settings(); + + if ( 'inline' === $active_settings['view'] ) { + $this->add_render_attribute( $item_key, 'class', 'elementor-inline-item' ); + } + + if ( ! empty( $item_data['url']['url'] ) ) { + $has_link = true; + + $this->add_link_attributes( $link_key, $item_data['url'] ); + } + + if ( ! empty( $item_data['itemprop'] ) ) { + $this->add_render_attribute( $item_key, 'itemprop', $item_data['itemprop'] ); + } + + ?> +
    • print_render_attribute_string( $item_key ); ?>> + + print_render_attribute_string( $link_key ); ?>> + + render_item_icon_or_image( $item_data, $repeater_item, $repeater_index ); ?> + render_item_text( $item_data, $repeater_index ); ?> + + + +
    • + + + add_render_attribute( + $image_data, + [ + 'class' => 'elementor-avatar', + 'src' => $item_data['image'], + 'alt' => sprintf( + /* translators: %s: Author name. */ + esc_attr__( 'Picture of %s', 'elementor-pro' ), + $item_data['text'] + ), + 'loading' => 'lazy', + ] + ); + ?> + print_render_attribute_string( $image_data ); ?>> + + 'true' ] ); + else : ?> + + + + + get_repeater_setting_key( 'text', 'icon_list', $repeater_index ); + + $this->add_render_attribute( $repeater_setting_key, 'class', [ 'elementor-icon-list-text', 'elementor-post-info__item', 'elementor-post-info__item--type-' . $item_data['type'] ] ); + if ( ! empty( $item['terms_list'] ) ) { + $this->add_render_attribute( $repeater_setting_key, 'class', 'elementor-terms-list' ); + } + + ?> + print_render_attribute_string( $repeater_setting_key ); ?>> + + + + + + + %s', $item_data['text'] ) + : $item_data['text']; + + echo wp_kses( $content, [ + 'a' => [ + 'href' => [], + 'title' => [], + 'rel' => [], + ], + 'time' => [], + ] ); + ?> + + + get_settings_for_display(); + + ob_start(); + if ( ! empty( $settings['icon_list'] ) ) { + foreach ( $settings['icon_list'] as $repeater_item ) { + $this->render_item( $repeater_item ); + } + } + $items_html = ob_get_clean(); + + if ( empty( $items_html ) ) { + return; + } + + if ( 'inline' === $settings['view'] ) { + $this->add_render_attribute( 'icon_list', 'class', 'elementor-inline-items' ); + } + + $this->add_render_attribute( 'icon_list', 'class', [ 'elementor-icon-list-items', 'elementor-post-info' ] ); + ?> +
        print_render_attribute_string( 'icon_list' ); ?>> + + +
      + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-post-navigation' ]; + } + + private function get_recommended_icons( $direction ): array { + return [ + 'fa-regular' => [ + "arrow-alt-circle-$direction", + "caret-square-$direction", + ], + 'fa-solid' => [ + "angle-double-$direction", + "angle-$direction", + "arrow-alt-circle-$direction", + "arrow-circle-$direction", + "arrow-$direction", + "caret-$direction", + "caret-square-$direction", + "chevron-circle-$direction", + "chevron-$direction", + "long-arrow-alt-$direction", + ], + ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_post_navigation_content', + [ + 'label' => esc_html__( 'Post Navigation', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'prev_label', + [ + 'label' => esc_html__( 'Previous Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Previous', 'elementor-pro' ), + 'condition' => [ + 'show_label' => 'yes', + ], + ] + ); + + $this->add_control( + 'next_label', + [ + 'label' => esc_html__( 'Next Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Next', 'elementor-pro' ), + 'condition' => [ + 'show_label' => 'yes', + ], + 'ai' => [ + 'active' => false, + ], + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'show_arrow', + [ + 'label' => esc_html__( 'Arrows', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + if ( is_rtl() ) { + $previous_direction = 'right'; + $next_direction = 'left'; + } else { + $previous_direction = 'left'; + $next_direction = 'right'; + } + + $this->add_control( + 'arrow_previous_icon', + [ + 'label' => esc_html__( 'Previous Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'skin' => 'inline', + 'label_block' => false, + 'default' => [ + 'value' => "fas fa-angle-$previous_direction", + 'library' => 'fa-solid', + ], + 'recommended' => $this->get_recommended_icons( $previous_direction ), + 'condition' => [ + 'show_arrow' => 'yes', + ], + ] + ); + + $this->add_control( + 'arrow_next_icon', + [ + 'label' => esc_html__( 'Next Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'skin' => 'inline', + 'label_block' => false, + 'default' => [ + 'value' => "fas fa-angle-$next_direction", + 'library' => 'fa-solid', + ], + 'recommended' => $this->get_recommended_icons( $next_direction ), + 'condition' => [ + 'show_arrow' => 'yes', + ], + ] + ); + + $this->add_control( + 'show_title', + [ + 'label' => esc_html__( 'Post Title', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'show_borders', + [ + 'label' => esc_html__( 'Borders', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'prefix_class' => 'elementor-post-navigation-borders-', + 'separator' => 'before', + ] + ); + + // Filter out post type without taxonomies + $post_type_options = []; + $post_type_taxonomies = []; + foreach ( Utils::get_public_post_types() as $post_type => $post_type_label ) { + $taxonomies = Utils::get_taxonomies( [ 'object_type' => $post_type ], false ); + if ( empty( $taxonomies ) ) { + continue; + } + + $post_type_options[ $post_type ] = $post_type_label; + $post_type_taxonomies[ $post_type ] = []; + foreach ( $taxonomies as $taxonomy ) { + $post_type_taxonomies[ $post_type ][ $taxonomy->name ] = $taxonomy->label; + } + } + + $this->add_control( + 'in_same_term', + [ + 'label' => esc_html__( 'In same Term', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $post_type_options, + 'default' => '', + 'multiple' => true, + 'label_block' => true, + 'description' => esc_html__( 'Indicates whether next post must be within the same taxonomy term as the current post, this lets you set a taxonomy per each post type', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + foreach ( $post_type_options as $post_type => $post_type_label ) { + $this->add_control( + $post_type . '_taxonomy', + [ + 'label' => $post_type_label . ' ' . esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $post_type_taxonomies[ $post_type ], + 'default' => '', + 'condition' => [ + 'in_same_term' => $post_type, + ], + ] + ); + } + + $this->end_controls_section(); + + $this->start_controls_section( + 'label_style', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_label' => 'yes', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_label_style' ); + + $this->start_controls_tab( + 'label_color_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'label_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--label' => 'color: {{VALUE}};', + '{{WRAPPER}} span.post-navigation__next--label' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'label_color_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'label_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--label:hover' => 'color: {{VALUE}};', + '{{WRAPPER}} span.post-navigation__next--label:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'label_hover_color_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--label' => 'transition-duration: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} span.post-navigation__next--label' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'label_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'selector' => '{{WRAPPER}} span.post-navigation__prev--label, {{WRAPPER}} span.post-navigation__next--label', + 'exclude' => [ 'line_height' ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'title_style', + [ + 'label' => esc_html__( 'Post Title', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_title' => 'yes', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_post_navigation_style' ); + + $this->start_controls_tab( + 'tab_color_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--title, {{WRAPPER}} span.post-navigation__next--title' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_color_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--title:hover, {{WRAPPER}} span.post-navigation__next--title:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'hover_color_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} span.post-navigation__prev--title' => 'transition-duration: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} span.post-navigation__next--title' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, + ], + 'selector' => '{{WRAPPER}} span.post-navigation__prev--title, {{WRAPPER}} span.post-navigation__next--title', + 'exclude' => [ 'line_height' ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'arrow_style', + [ + 'label' => esc_html__( 'Arrow', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_arrow' => 'yes', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_post_navigation_arrow_style' ); + + $this->start_controls_tab( + 'arrow_color_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'arrow_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .post-navigation__arrow-wrapper' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'arrow_color_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'arrow_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .post-navigation__arrow-wrapper:hover' => 'color: {{VALUE}}; fill: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'arrow_hover_color_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .post-navigation__arrow-wrapper' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'arrow_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 300, + ], + 'em' => [ + 'max' => 30, + ], + 'rem' => [ + 'max' => 30, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .post-navigation__arrow-wrapper' => 'font-size: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'arrow_padding', + [ + 'label' => esc_html__( 'Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post-navigation__link a ' => 'gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'borders_section_style', + [ + 'label' => esc_html__( 'Borders', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'show_borders!' => '', + ], + ] + ); + + $this->add_control( + 'sep_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + //'default' => '#D4D4D4', + 'selectors' => [ + '{{WRAPPER}} .elementor-post-navigation__separator' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .elementor-post-navigation' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'borders_width', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post-navigation__separator' => 'width: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-post-navigation' => 'border-block-width: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .elementor-post-navigation__next.elementor-post-navigation__link' => 'width: calc(50% - ({{SIZE}}{{UNIT}} / 2))', + '{{WRAPPER}} .elementor-post-navigation__prev.elementor-post-navigation__link' => 'width: calc(50% - ({{SIZE}}{{UNIT}} / 2))', + ], + ] + ); + + $this->add_control( + 'borders_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-post-navigation' => 'padding: {{SIZE}}{{UNIT}} 0;', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + $prev_label = ''; + $next_label = ''; + $prev_arrow = ''; + $next_arrow = ''; + + if ( 'yes' === $settings['show_label'] ) { + $prev_label = '' . $settings['prev_label'] . ''; + $next_label = '' . $settings['next_label'] . ''; + } + + if ( 'yes' === $settings['show_arrow'] ) { + $is_new = Icons_Manager::is_migration_allowed(); + $migrated_prev_icon = isset( $settings['__fa4_migrated']['arrow_previous_icon'] ); + $migrated_next_icon = isset( $settings['__fa4_migrated']['arrow_next_icon'] ); + + if ( $is_new || $migrated_prev_icon ) { + ob_start(); + Icons_Manager::render_icon( $settings['arrow_previous_icon'], [ 'aria-hidden' => 'true' ] ); + $prev_icon = ob_get_clean(); + } else { + $prev_icon = "get_render_attribute_string('arrow_previous_icon') } aria-hidden='true'>"; + } + + if ( $is_new || $migrated_next_icon ) { + ob_start(); + Icons_Manager::render_icon( $settings['arrow_next_icon'], [ 'aria-hidden' => 'true' ] ); + $next_icon = ob_get_clean(); + } else { + $next_icon = "get_render_attribute_string('arrow_next_icon') } aria-hidden='true'>"; + } + + $prev_arrow = '' . $prev_icon . '' . esc_html__( 'Prev', 'elementor-pro' ) . ''; + $next_arrow = '' . $next_icon . '' . esc_html__( 'Next', 'elementor-pro' ) . ''; + } + + $prev_title = ''; + $next_title = ''; + + if ( 'yes' === $settings['show_title'] ) { + $prev_title = '%title'; + $next_title = '%title'; + } + + $in_same_term = false; + $taxonomy = 'category'; + $post_type = get_post_type( get_queried_object_id() ); + + if ( ! empty( $settings['in_same_term'] ) && is_array( $settings['in_same_term'] ) && in_array( $post_type, $settings['in_same_term'] ) ) { + if ( isset( $settings[ $post_type . '_taxonomy' ] ) ) { + $in_same_term = true; + $taxonomy = $settings[ $post_type . '_taxonomy' ]; + } + } + ?> + + experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function show_in_panel(): bool { + return false; + } + + public function get_style_depends(): array { + $style_depends = [ 'widget-search-form' ]; + + if ( Icons_Manager::is_migration_allowed() ) { + $style_depends[] = 'elementor-icons-fa-solid'; + } + + return $style_depends; + } + + protected function register_controls() { + $this->start_controls_section( + 'search_content', + [ + 'label' => esc_html__( 'Search Form', 'elementor-pro' ), + ] + ); + + $this->add_deprecation_message( + '3.24.0', + esc_html__( 'You are currently editing a Search Form Widget in its old version. Any new Search widget dragged into the canvas will be the new Search widget, with the improved search capabilities.', 'elementor-pro' ), + 'search' + ); + + $this->add_control( + 'skin', + [ + 'label' => esc_html__( 'Skin', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'classic', + 'options' => [ + 'classic' => esc_html__( 'Classic', 'elementor-pro' ), + 'minimal' => esc_html__( 'Minimal', 'elementor-pro' ), + 'full_screen' => esc_html__( 'Full Screen', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-search-form--skin-', + 'render_type' => 'template', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'placeholder', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'separator' => 'before', + 'default' => esc_html__( 'Search', 'elementor-pro' ) . '...', + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'heading_button_content', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'button_type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'icon', + 'options' => [ + 'icon' => esc_html__( 'Icon', 'elementor-pro' ), + 'text' => esc_html__( 'Text', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-search-form--button-type-', + 'render_type' => 'template', + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Search', 'elementor-pro' ), + 'condition' => [ + 'button_type' => 'text', + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'search', + 'options' => [ + 'search' => [ + 'title' => esc_html__( 'Search', 'elementor-pro' ), + 'icon' => 'eicon-search', + ], + 'arrow' => [ + 'title' => esc_html__( 'Arrow', 'elementor-pro' ), + 'icon' => 'eicon-arrow-right', + ], + ], + 'render_type' => 'template', + 'prefix_class' => 'elementor-search-form--icon-', + 'condition' => [ + 'button_type' => 'icon', + 'skin' => 'classic', + ], + ] + ); + + $this->add_control( + 'size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 50, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__container' => 'min-height: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .elementor-search-form__submit' => 'min-width: {{SIZE}}{{UNIT}}', + 'body:not(.rtl) {{WRAPPER}} .elementor-search-form__icon' => 'padding-left: calc({{SIZE}}{{UNIT}} / 3)', + 'body.rtl {{WRAPPER}} .elementor-search-form__icon' => 'padding-right: calc({{SIZE}}{{UNIT}} / 3)', + '{{WRAPPER}} .elementor-search-form__input, {{WRAPPER}}.elementor-search-form--button-type-text .elementor-search-form__submit' => 'padding-left: calc({{SIZE}}{{UNIT}} / 3); padding-right: calc({{SIZE}}{{UNIT}} / 3)', + ], + 'condition' => [ + 'skin!' => 'full_screen', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'toggle_button_content', + [ + 'label' => esc_html__( 'Toggle', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'skin' => 'full_screen', + ], + ] + ); + + $this->add_control( + 'toggle_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'center', + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form' => 'text-align: {{VALUE}}', + ], + 'condition' => [ + 'skin' => 'full_screen', + ], + ] + ); + + $this->add_control( + 'toggle_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 33, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-size: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'skin' => 'full_screen', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_input_style', + [ + 'label' => esc_html__( 'Input', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'icon_size_minimal', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__icon' => '--e-search-form-icon-size-minimal: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'skin' => 'minimal', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'overlay_background_color', + [ + 'label' => esc_html__( 'Overlay Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-search-form--skin-full_screen .elementor-search-form__container' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'skin' => 'full_screen', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'input_typography', + 'selector' => '{{WRAPPER}} input[type="search"].elementor-search-form__input', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->start_controls_tabs( 'tabs_input_colors' ); + + $this->start_controls_tab( + 'tab_input_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'input_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__input, + {{WRAPPER}} .elementor-search-form__icon, + {{WRAPPER}} .elementor-lightbox .dialog-lightbox-close-button, + {{WRAPPER}} .elementor-lightbox .dialog-lightbox-close-button:hover, + {{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input' => 'color: {{VALUE}}; fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'input_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form__container' => 'background-color: {{VALUE}}', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'skin!' => 'full_screen', + ], + ] + ); + + $this->add_control( + 'input_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form__container' => 'border-color: {{VALUE}}', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-search-form__container', + 'fields_options' => [ + 'box_shadow_type' => [ + 'separator' => 'default', + ], + ], + 'condition' => [ + 'skin!' => 'full_screen', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_input_focus', + [ + 'label' => esc_html__( 'Focus', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'input_text_color_focus', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form--focus .elementor-search-form__input, + {{WRAPPER}} .elementor-search-form--focus .elementor-search-form__icon, + {{WRAPPER}} .elementor-lightbox .dialog-lightbox-close-button:hover, + {{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input:focus' => 'color: {{VALUE}}; fill: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'input_background_color_focus', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form--focus .elementor-search-form__container' => 'background-color: {{VALUE}}', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input:focus' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'skin!' => 'full_screen', + ], + ] + ); + + $this->add_control( + 'input_border_color_focus', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form--focus .elementor-search-form__container' => 'border-color: {{VALUE}}', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input:focus' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'input_box_shadow_focus', + 'selector' => '{{WRAPPER}} .elementor-search-form--focus .elementor-search-form__container', + 'fields_options' => [ + 'box_shadow_type' => [ + 'separator' => 'default', + ], + ], + 'condition' => [ + 'skin!' => 'full_screen', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form__container' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'default' => [ + 'size' => 3, + ], + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-search-form--skin-full_screen) .elementor-search-form__container' => 'border-radius: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-search-form--skin-full_screen input[type="search"].elementor-search-form__input' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'skin' => 'classic', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .elementor-search-form__submit', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'condition' => [ + 'button_type' => 'text', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_button_colors' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit' => '--e-search-form-submit-text-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_SECONDARY, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit:hover' => '--e-search-form-submit-text-color: {{VALUE}}', + '{{WRAPPER}} .elementor-search-form__submit:focus' => '--e-search-form-submit-text-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit:hover' => 'background-color: {{VALUE}}', + '{{WRAPPER}} .elementor-search-form__submit:focus' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_responsive_control( + 'icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit' => '--e-search-form-submit-icon-size: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'button_type' => 'icon', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'button_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 10, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__submit' => 'min-width: calc( {{SIZE}} * {{size.SIZE}}{{size.UNIT}} )', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_toggle_style', + [ + 'label' => esc_html__( 'Toggle', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'skin' => 'full_screen', + ], + ] + ); + + $this->start_controls_tabs( 'tabs_toggle_color' ); + + $this->start_controls_tab( + 'tab_toggle_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'toggle_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_toggle_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'toggle_color_hover', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle:hover' => '--e-search-form-toggle-color: {{VALUE}}', + '{{WRAPPER}} .elementor-search-form__toggle:focus' => '--e-search-form-toggle-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle:hover' => '--e-search-form-toggle-background-color: {{VALUE}}', + '{{WRAPPER}} .elementor-search-form__toggle:focus' => '--e-search-form-toggle-background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'toggle_icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-icon-size: calc({{SIZE}}em / 100)', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'toggle_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-border-width: {{SIZE}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'toggle_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-search-form__toggle' => '--e-search-form-toggle-border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + $this->add_render_attribute( + 'form', + [ + 'class' => 'elementor-search-form', + 'action' => esc_url( home_url() ), + 'method' => 'get', + ] + ); + + $this->add_render_attribute( + 'container', + [ + 'class' => 'elementor-search-form__container', + ] + ); + + $this->add_render_attribute( + 'label', + [ + 'class' => 'elementor-screen-only', + 'for' => 'elementor-search-form-' . $this->get_id(), + ] + ); + + $this->add_render_attribute( + 'input', + [ + 'id' => 'elementor-search-form-' . $this->get_id(), + 'placeholder' => $settings['placeholder'], + 'class' => 'elementor-search-form__input', + 'type' => 'search', + 'name' => 's', + 'value' => get_search_query(), + ] + ); + + // Set the selected icon. + $icon_class = 'search'; + + if ( 'icon' === $settings['button_type'] && 'arrow' === $settings['icon'] ) { + $icon_class = is_rtl() ? 'arrow-left' : 'arrow-right'; + } + + $this->add_render_attribute( 'icon', 'class', 'fa fa-' . $icon_class ); + + $icon = [ + 'value' => 'fas fa-' . $icon_class, + 'library' => 'fa-solid', + ]; + ?> + +
      print_render_attribute_string( 'form' ); ?>> + + +
      + render_search_icon( $icon, [ 'aria-hidden' => 'true' ] ); ?> +
      + +
      print_render_attribute_string( 'container' ); ?>> + + + +
      + render_search_icon( $icon, [ 'aria-hidden' => 'true' ] ); ?> + +
      + + + print_render_attribute_string( 'input' ); ?>> + + + + + + + +
      + 'eicons', + 'value' => 'eicon-close', + ], [ 'aria-hidden' => 'true' ] ); + ?> +
      + +
      +
      +
      + + <# + view.addRenderAttribute( + 'form', + { + 'class': 'elementor-search-form', + 'action': '', + 'method': 'get', + } + ); + + view.addRenderAttribute( + 'container', + { + 'class': 'elementor-search-form__container', + } + ); + + view.addRenderAttribute( + 'label', + { + 'class': 'elementor-screen-only', + 'for': 'elementor-search-form-get_id() ); ?>', + } + ); + + view.addRenderAttribute( + 'input', + { + 'id': 'elementor-search-form-get_id() ); ?>', + 'placeholder': settings.placeholder, + 'class': 'elementor-search-form__input', + 'type': 'search', + 'name': 's', + } + ); + + var iconClass = 'fa fas fa-search'; + + if ( 'arrow' === settings.icon ) { + if ( elementorCommon.config.isRTL ) { + iconClass = 'fa fas fa-arrow-left'; + } else { + iconClass = 'fa fas fa-arrow-right'; + } + } + #> + +
      + <# if ( 'full_screen' === settings.skin ) { #> +
      + +
      + <# } #> +
      + + + <# if ( 'minimal' === settings.skin ) { #> +
      + + +
      + <# } #> + + + + <# if ( 'classic' === settings.skin ) { #> + + <# } #> +
      +
      +
      + experiments->is_feature_active( 'e_font_icon_svg' ) ) { + $icon_html = Icons_Manager::render_font_icon( $icon, $attributes ); + + Utils::print_unescaped_internal_string( sprintf( '
      %s
      ', $icon_html ) ); + } else { + $migration_allowed = Icons_Manager::is_migration_allowed(); + + if ( ! $migration_allowed || ! Icons_Manager::render_icon( $icon, [ 'aria-hidden' => 'true' ] ) ) { + Utils::print_unescaped_internal_string( sprintf( '', esc_attr( $this->get_render_attribute_string( 'icon' ) ) ) ); + } + } + } + + public function get_group_name() { + return 'theme-elements'; + } +} diff --git a/modules/theme-elements/widgets/sitemap.php b/modules/theme-elements/widgets/sitemap.php new file mode 100644 index 00000000..ad246a24 --- /dev/null +++ b/modules/theme-elements/widgets/sitemap.php @@ -0,0 +1,755 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-sitemap' ]; + } + + private function register_sitemap_tab() { + $this->start_controls_section( + 'sitemap_section', + [ + 'label' => esc_html__( 'Sitemap', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->register_post_type_controls(); + + $this->add_control( + 'sitemap_layout_divider', + [ + 'type' => Controls_Manager::DIVIDER, + ] + ); + + $this->register_layout_controls(); + + $this->end_controls_section(); + + $this->register_additional_settings_section(); + } + + private function register_additional_settings_section() { + $this->start_controls_section( + 'sitemap_query_section', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'sitemap_exclude', + [ + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'current_post' => esc_html__( 'Current Post', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + 'label_block' => true, + ] + ); + + $this->add_control( + 'sitemap_exclude_ids', + [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Query_Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'autocomplete' => [ + 'object' => Query_Module::QUERY_OBJECT_POST, + ], + 'condition' => [ + 'sitemap_exclude' => 'manual_selection', + ], + ] + ); + + $this->add_control( + 'sitemap_password_protected', + [ + 'label' => esc_html__( 'Protected Posts', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + } + + private function register_layout_controls() { + $this->add_responsive_control( + 'sitemap_columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '4', + 'tablet_default' => '2', + 'mobile_default' => '1', + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-section' => 'flex-basis: calc( 1 / {{VALUE}} * 100% );', + ], + ] + ); + + $this->add_control( + 'sitemap_title_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + 'p' => 'p', + ], + 'default' => 'h2', + ] + ); + + $this->add_control( + 'sitemap_add_nofollow', + [ + 'label' => esc_html__( 'Add nofollow', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + } + + private function register_post_type_controls() { + $supported_taxonomies = []; + + $public_types = Pro_Utils::get_public_post_types(); + + foreach ( $public_types as $type => $title ) { + $taxonomies = get_object_taxonomies( $type, 'objects' ); + foreach ( $taxonomies as $key => $tax ) { + if ( ! in_array( $tax->name, $supported_taxonomies ) ) { + $label = $tax->label . ' (' . $tax->name . ')'; + $supported_taxonomies[ $tax->name ] = $label; + } + } + } + + $repeater = new Repeater(); + + $repeater->add_control( + 'sitemap_type_selector', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_type', + 'options' => [ + 'post_type' => esc_html__( 'Post Type', 'elementor-pro' ), + 'taxonomy' => esc_html__( 'Taxonomy', 'elementor-pro' ), + ], + ] + ); + + $repeater->add_control( + 'sitemap_source_post_type', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'page', + 'options' => $public_types, + 'condition' => [ + 'sitemap_type_selector' => 'post_type', + ], + ] + ); + + $repeater->add_control( + 'sitemap_source_taxonomy', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'category', + 'options' => $supported_taxonomies, + 'condition' => [ + 'sitemap_type_selector' => 'taxonomy', + ], + ] + ); + + $repeater->add_control( + 'sitemap_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'sitemap_orderby_post_type', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__( 'Date', 'elementor-pro' ), + 'post_title' => esc_html__( 'Title', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + ], + 'condition' => [ + 'sitemap_type_selector' => 'post_type', + ], + ] + ); + + $repeater->add_control( + 'sitemap_orderby_taxonomy', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'name', + 'options' => [ + 'id' => esc_html__( 'ID', 'elementor-pro' ), + 'name' => esc_html__( 'Name', 'elementor-pro' ), + ], + 'condition' => [ + 'sitemap_type_selector' => 'taxonomy', + ], + ] + ); + + $repeater->add_control( + 'sitemap_order', + [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + ] + ); + + $repeater->add_control( + 'sitemap_hide_empty', + [ + 'label' => esc_html__( 'Hide Empty', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'sitemap_type_selector' => 'taxonomy', + ], + ] + ); + + $repeater->add_control( + 'sitemap_hierarchical', + [ + 'label' => esc_html__( 'Hierarchical View', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'no', + ] + ); + + $repeater->add_control( + 'sitemap_depth', + [ + 'label' => esc_html__( 'Depth', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '0', + 'options' => [ + '0' => esc_html__( 'All', 'elementor-pro' ), + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'condition' => [ + 'sitemap_hierarchical' => 'yes', + ], + ] + ); + + $this->add_control( + 'sitemap_items', + [ + 'label' => '', + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'sitemap_type_selector' => 'post_type', + 'sitemap_title' => esc_html__( 'Pages', 'elementor-pro' ), + 'sitemap_source_post_type' => 'page', + ], + [ + 'sitemap_type_selector' => 'taxonomy', + 'sitemap_title' => esc_html__( 'Categories', 'elementor-pro' ), + 'sitemap_source_taxonomy' => 'category', + ], + ], + 'title_field' => '{{{ sitemap_title }}}', + ] + ); + } + + private function register_style_tab() { + $this->start_controls_section( + 'section_sitemap_style', + [ + 'label' => esc_html__( 'List', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'sitemap_list_indent', + [ + 'label' => esc_html__( 'Indent', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-sitemap-section ul' => 'margin-left: {{SIZE}}{{UNIT}};', + 'body.rtl {{WRAPPER}} .elementor-sitemap-section ul' => 'margin-right: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sitemap_section_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-section' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sitemap_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sitemap_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-title' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sitemap_title_typography', + 'selector' => '{{WRAPPER}} .elementor-sitemap-title', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_control( + 'sitemap_list_style', + [ + 'label' => esc_html__( 'List Item', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sitemap_list_item_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-item, {{WRAPPER}} span.elementor-sitemap-list, {{WRAPPER}} .elementor-sitemap-item a' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sitemap_list_item_typography', + 'selector' => '{{WRAPPER}} .elementor-sitemap-item, {{WRAPPER}} span.elementor-sitemap-list, {{WRAPPER}} .elementor-sitemap-item a', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'sitemap_bullet_style', + [ + 'label' => esc_html__( 'Bullet', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sitemap_bullet_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-item' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_control( + 'sitemap_list_item_bullet_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'disc', + 'options' => [ + 'disc' => [ + 'title' => esc_html__( 'Disc', 'elementor-pro' ), + 'icon' => 'eicon-circle', + ], + 'circle' => [ + 'title' => esc_html__( 'Circle', 'elementor-pro' ), + 'icon' => 'eicon-circle-o', + ], + 'square' => [ + 'title' => esc_html__( 'Square', 'elementor-pro' ), + 'icon' => 'eicon-square', + ], + 'none' => [ + 'title' => esc_html__( 'None', 'elementor-pro' ), + 'icon' => 'eicon-ban', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-sitemap-list, {{WRAPPER}} .elementor-sitemap-list .children' => 'list-style-type: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function register_controls() { + $this->register_sitemap_tab(); + $this->register_style_tab(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( empty( $settings['sitemap_items'] ) ) { + return; + } + + $title_tag = $settings['sitemap_title_tag']; + + $posts_query = [ + 'post__not_in' => $settings['sitemap_exclude_ids'], + 'has_password' => 'yes' === $settings['sitemap_password_protected'] ? null : false, + ]; + + $this->add_render_attribute( [ + 'category_link' => [ + 'class' => 'elementor-sitemap-category-title', + ], + 'wrapper' => [ + 'class' => 'elementor-sitemap-wrap', + ], + ] ); + + if ( 'yes' === $settings['sitemap_add_nofollow'] ) { + $this->add_render_attribute( 'a', 'rel', 'nofollow' ); + } + + echo '
      print_render_attribute_string( 'wrapper' ); + echo '>'; + foreach ( $settings['sitemap_items'] as $sitemap_item ) { + // PHPCS - `render_sitemap_item` is safe. + echo $this->render_sitemap_item( $sitemap_item, $title_tag, $posts_query ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + echo '
      '; + } + + private function get_list_title( $current_title, $item_type, $is_taxonomy ) { + if ( '' !== $current_title ) { + return $current_title; + } + + if ( $is_taxonomy ) { + $obj = get_taxonomy( $item_type ); + if ( false === $obj ) { + return ''; + } + return $obj->label; + } + + $obj = get_post_type_object( $item_type ); + if ( null === $obj ) { + return ''; + } + if ( '' === $obj->labels->name ) { + return $obj->labels->singular_name; + } + + return $obj->labels->name; + } + + private function render_sitemap_item( $sitemap_item, $title_tag, $query_args ) { + $hierarchical = 'yes' === $sitemap_item['sitemap_hierarchical']; + $max_depth = $sitemap_item['sitemap_depth']; + $query_args['orderby'] = $sitemap_item['sitemap_orderby_post_type']; + $query_args['order'] = $sitemap_item['sitemap_order']; + $is_taxonomy = 'taxonomy' === $sitemap_item['sitemap_type_selector']; + $item_type = $is_taxonomy ? $sitemap_item['sitemap_source_taxonomy'] : $sitemap_item['sitemap_source_post_type']; + $title = $this->get_list_title( $sitemap_item['sitemap_title'], $item_type, $is_taxonomy ); + + $this->add_render_attribute( [ + 'section' . $item_type => [ + 'class' => [ + 'elementor-sitemap-section', + ], + ], + 'list' . $item_type => [ + 'class' => [ + 'elementor-sitemap-list', + 'elementor-sitemap-' . $item_type . '-list', + ], + ], + $title_tag . $item_type => [ + 'class' => [ + 'elementor-sitemap-title', + 'elementor-sitemap-' . $item_type . '-title', + ], + ], + 'item' . $item_type => [ + 'class' => [ + 'elementor-sitemap-item', + 'elementor-sitemap-item-' . $item_type, + ], + ], + ] ); + + $items_html = ''; + + if ( $is_taxonomy ) { + $items_html .= $this->sitemap_html_taxonomies( $item_type, $hierarchical, $max_depth, $sitemap_item, $query_args ); + } else { + $items_html .= $this->sitemap_html_post_types( $item_type, $hierarchical, $max_depth, $query_args ); + } + + $title = empty( $title ) ? '' : sprintf( '<%s %s>%s', Utils::validate_html_tag( $title_tag ), $this->get_render_attribute_string( $title_tag . $item_type ), $title ); + + $html = sprintf( '
      %s', $this->get_render_attribute_string( 'section' . $item_type ), $title ); + if ( empty( $items_html ) ) { + $html .= sprintf( '%s', $this->get_render_attribute_string( 'list' . $item_type ), esc_html__( 'None', 'elementor-pro' ) ); + } else { + $html .= sprintf( '
        %s
      ', $this->get_render_attribute_string( 'list' . $item_type ), $items_html ); + } + $html .= '
      '; + + return $html; + } + + private function sitemap_html_taxonomies( $taxonomy, $hierarchical, $max_depth, $item_settings, $query_args ) { + $query_args['hide_empty'] = 'yes' === $item_settings['sitemap_hide_empty']; + $query_args['show_option_none'] = ''; + $query_args['taxonomy'] = $taxonomy; + $query_args['title_li'] = ''; + $query_args['echo'] = false; + $query_args['depth'] = $max_depth; + $query_args['hierarchical'] = $hierarchical; + $query_args['orderby'] = $item_settings['sitemap_orderby_taxonomy']; + + $taxonomy_list = wp_list_categories( $query_args ); + $taxonomy_list = $this->add_sitemap_item_classes( 'item' . $taxonomy, $taxonomy_list ); + + return $taxonomy_list; + } + + /** + * @param string $post_type + * @param array $query_args + * + * @return \WP_Query + */ + private function query_by_post_type( $post_type, $query_args ) { + $args = [ + 'posts_per_page' => -1, + 'update_post_meta_cache' => false, + 'post_type' => $post_type, + 'filter' => 'ids', + 'post_status' => 'publish', + ]; + + $args = array_merge( $query_args, $args ); + + $query = new \WP_Query( $args ); + + return $query; + } + + /** + * @param string $post_type + * @param bool $hierarchical + * @param int $depth + * @param array $query_args + * + * @return string + */ + private function sitemap_html_post_types( $post_type, $hierarchical, $depth, $query_args ) { + $html = ''; + + $query_result = $this->query_by_post_type( $post_type, $query_args ); + + if ( empty( $query_result ) ) { + return ''; + } + + if ( $query_result->have_posts() ) { + if ( ! $hierarchical ) { + $depth = -1; + } + $walker = new \Walker_Page(); + $walker->tree_type = $post_type; + $walker_str = $walker->walk( $query_result->posts, $depth ); + $html .= $this->add_sitemap_item_classes( 'item' . $post_type, $walker_str ); + } + + return $html; + } + + private function add_sitemap_item_classes( $element, $str ) { + $element_str = $this->get_render_attribute_string( $element ); + /** remove trailing " */ + $element_str = substr_replace( $element_str, ' ', -1, 1 ); + $source = [ + 'class="', + ]; + $replace = [ + $element_str, + ]; + + if ( 'yes' === $this->get_settings_for_display( 'sitemap_add_nofollow' ) ) { + $source[] = 'href='; + $replace[] = 'rel="nofollow" href='; + } + + return str_replace( $source, $replace, $str ); + } + + public function get_group_name() { + return 'theme-elements'; + } +} + + diff --git a/modules/tiers/admin-menu-items/base-promotion-item.php b/modules/tiers/admin-menu-items/base-promotion-item.php new file mode 100644 index 00000000..3a8cba5c --- /dev/null +++ b/modules/tiers/admin-menu-items/base-promotion-item.php @@ -0,0 +1,71 @@ + $this->get_promotion_title(), + 'description' => $this->get_promotion_description(), + 'image' => $this->get_image_url(), + 'upgrade_text' => $this->get_cta_text(), + 'upgrade_url' => $this->get_cta_url(), + ]; + + $config = Filtered_Promotions_Manager::get_filtered_promotion_data( $config, 'elementor-pro/advanced-' . $this->get_name() . '-pro-widget/promotion', 'upgrade_url' ); + + ?> +
      +
      + + +

      + +

      + + + + +
      +
      + get_content_lines() ) ) { + ?> +
        + get_content_lines() as $item ) { ?> +
      • + +
      + get_promotion_data(); + ?> +
      +
      +

      + + + + + + + + +
      +

      +
      + + +
      + + +
      + $this->get_promotion_title(), + 'cta_url' => $this->get_cta_url(), + 'cta_text' => $this->get_cta_text(), + 'video_url' => $this->get_video_url(), + 'lines' => $this->get_lines(), + 'side_note' => $this->get_side_note(), + ]; + + return Filtered_Promotions_Manager::get_filtered_promotion_data( $config, 'elementor-pro/advanced-' . $this->get_name() . '-pro-widget/promotion', 'cta_url' ); + } +} diff --git a/modules/tiers/module.php b/modules/tiers/module.php new file mode 100644 index 00000000..fc06d558 --- /dev/null +++ b/modules/tiers/module.php @@ -0,0 +1,53 @@ + + + 'Custom Fonts', + 'custom_icons' => 'Custom Icons', + ]; + } + + public function get_custom_fonts() : array { + return [ + 'value' => count( Module::get_fonts_usage() ), + ]; + } + + public function get_custom_icons() : array { + return [ + 'value' => count( Module::get_icons_usage() ), + ]; + } +} diff --git a/modules/usage/integrations-reporter.php b/modules/usage/integrations-reporter.php new file mode 100644 index 00000000..4f5d30c3 --- /dev/null +++ b/modules/usage/integrations-reporter.php @@ -0,0 +1,49 @@ + '', + ]; + } + + public function get_integrations() : array { + $usage_integrations_text = ''; + + $integrations = Module::instance()->get_integrations_usage(); + + foreach ( array_keys( $integrations ) as $integration ) { + $usage_integrations_text .= '' . $integration . '' . esc_html__( 'Active', 'elementor-pro' ) . ''; + } + + return [ + 'value' => $usage_integrations_text, + ]; + } + + public function get_raw_integrations() : array { + $usage_integrations = PHP_EOL; + + $integrations = Module::instance()->get_integrations_usage(); + + foreach ( array_keys( $integrations ) as $integration ) { + $usage_integrations .= "\t" . $integration . ': ' . esc_html__( 'Active', 'elementor-pro' ) . PHP_EOL; + } + + return [ + 'value' => $usage_integrations, + ]; + } +} diff --git a/modules/usage/module.php b/modules/usage/module.php new file mode 100644 index 00000000..ef11ae89 --- /dev/null +++ b/modules/usage/module.php @@ -0,0 +1,190 @@ +settings->get_tabs(); + $integrations = $settings_tab['integrations']['sections']; + + foreach ( $integrations as $integration_name => $integration_data ) { + $integration_options = []; + $integration_fields_count = count( $integration_data['fields'] ); + + foreach ( $integration_data['fields'] as $field_name => $field_data ) { + $integration_options [] = get_option( 'elementor_' . $field_name ); + } + /** + * array_filter will clear all empty array values. + * if all the values filled then the count should be the same. + */ + if ( count( array_filter( $integration_options ) ) === $integration_fields_count ) { + $usage[ $integration_name ] = true; + } + } + + return $usage; + } + + /** + * Get fonts usage. + * + * Retrieve the number of Elementor fonts variants saved. + * + * @access public + * @static + * + * @return array The number of Elementor fonts variants. + */ + public static function get_fonts_usage() { + $usage = []; + $query = new \WP_Query( [ + 'posts_per_page' => -1, + 'post_type' => 'elementor_font', + ] ); + + $post_index = 0; + foreach ( $query->get_posts() as $post ) { + $elementor_font_files = get_post_meta( $post->ID, Custom_Fonts::FONT_META_KEY ); + + if ( ! empty( $elementor_font_files ) ) { + foreach ( $elementor_font_files as $elementor_font_index => $elementor_font_file ) { + $current = & $usage[ $post_index ]; + + foreach ( $elementor_font_file as $elementor_font_variant_index => $elementor_font_variant ) { + $current_variant = & $current[ 'variant_' . $elementor_font_variant_index ]; + + foreach ( [ 'weight', 'style' ] as $font_prop ) { + $current_variant[ $font_prop ] = $elementor_font_variant[ 'font_' . $font_prop ]; + } + + $current_variant['types'] = []; + foreach ( [ 'woff', 'woff2', 'ttf', 'svg', 'eot' ] as $font_ext ) { + if ( isset( $elementor_font_variant[ $font_ext ] ) && strlen( $elementor_font_variant[ $font_ext ]['url'] ) ) { + $current_variant['types'][] = $font_ext; + } + } + } + } + + $post_index++; + } + } + + return $usage; + } + + /** + * Get icons usage. + * + * Retrieve the number of Elementor icons saved. + * + * @access public + * @static + * + * @return array The number of Elementor icons. + */ + public static function get_icons_usage() { + $usage = []; + $query = new \WP_Query( [ + 'posts_per_page' => -1, + 'post_type' => 'elementor_icons', + ] ); + + $index = 0; + foreach ( $query->get_posts() as $post ) { + $elementor_custom_icon_set_config = get_post_meta( $post->ID, Custom_Icons::META_KEY ); + + if ( isset( $elementor_custom_icon_set_config[0] ) ) { + $elementor_custom_icon_set_config = json_decode( $elementor_custom_icon_set_config[0] ); + + $usage[ $index ] = (int) $elementor_custom_icon_set_config->count; + + $index++; + } + } + + return $usage; + } + + /** + * Add's tracking data. + * + * Called on elementor/tracker/send_tracking_data_params. + * + * @param array $params + * + * @return array + */ + public function add_tracking_data( $params ) { + unset( $params['is_first_time'] ); + + $params['install_time_pro'] = Plugin::instance()->license_admin->get_installed_time(); + + $params['usages']['integrations'] = $this->get_integrations_usage(); + $params['usages']['icons'] = $this->get_icons_usage(); + $params['usages']['fonts'] = $this->get_fonts_usage(); + + return $params; + } + + public function register_system_info_reporters() { + System_Info::add_report( 'features', [ + 'file_name' => __DIR__ . '/features-reporter.php', + 'class_name' => __NAMESPACE__ . '\Features_Reporter', + ] ); + + System_Info::add_report( 'integrations', [ + 'file_name' => __DIR__ . '/integrations-reporter.php', + 'class_name' => __NAMESPACE__ . '\Integrations_Reporter', + ] ); + } + + /** + * Usage module constructor. + * + * Initializing Elementor usage module. + * + * @access public + */ + public function __construct() { + add_filter( 'elementor/tracker/send_tracking_data_params', [ $this, 'add_tracking_data' ] ); + + add_action( 'admin_init', [ $this, 'register_system_info_reporters' ], 60 ); + } +} diff --git a/modules/variables/classes/style-schema.php b/modules/variables/classes/style-schema.php new file mode 100644 index 00000000..e6cf27a4 --- /dev/null +++ b/modules/variables/classes/style-schema.php @@ -0,0 +1,104 @@ +blacklist, true ) ) { + return true; + } + + return false; + } + + public function augment( array $schema ): array { + foreach ( $schema as $css_property => $prop_type ) { + if ( $this->ignore( $css_property ) ) { + continue; + } + + $schema[ $css_property ] = $this->update( $prop_type ); + } + + return $schema; + } + + private function update( $prop_type ) { + if ( $prop_type instanceof Size_Prop_Type ) { + return $this->update_size( $prop_type ); + } + + if ( $prop_type instanceof Union_Prop_Type ) { + return $this->update_union( $prop_type ); + } + + if ( $prop_type instanceof Object_Prop_Type ) { + return $this->update_object( $prop_type ); + } + + if ( $prop_type instanceof Array_Prop_Type ) { + return $this->update_array( $prop_type ); + } + + return $prop_type; + } + + private function update_size( Size_Prop_Type $size_prop_type ): Union_Prop_Type { + return Union_Prop_Type::create_from( $size_prop_type ) + ->add_prop_type( Size_Variable_Prop_Type::make() ); + } + + private function update_array( Array_Prop_Type $array_prop_type ): Array_Prop_Type { + return $array_prop_type->set_item_type( + $this->update( $array_prop_type->get_item_type() ) + ); + } + + private function update_object( Object_Prop_Type $object_prop_type ): Object_Prop_Type { + return $object_prop_type->set_shape( + $this->augment( $object_prop_type->get_shape() ) + ); + } + + private function update_union( Union_Prop_Type $union_prop_type ): Union_Prop_Type { + $new_union = Union_Prop_Type::make(); + $dependencies = $union_prop_type->get_dependencies(); + $new_union->set_dependencies( $dependencies ); + + foreach ( $union_prop_type->get_prop_types() as $prop_type ) { + $updated = $this->update( $prop_type ); + + if ( $updated instanceof Union_Prop_Type ) { + foreach ( $updated->get_prop_types() as $updated_prop_type ) { + $new_union->add_prop_type( $updated_prop_type ); + } + + continue; + } + + $new_union->add_prop_type( $updated ); + } + + return $new_union; + } +} diff --git a/modules/variables/hooks.php b/modules/variables/hooks.php new file mode 100644 index 00000000..b0fe0cae --- /dev/null +++ b/modules/variables/hooks.php @@ -0,0 +1,59 @@ +register_styles_transformers() + ->register_packages() + ->filter_for_style_schema() + ->register_size_variable_types(); + + return $this; + } + + private function register_size_variable_types() { + add_action( 'elementor/variables/register', function ( Variable_Types_Registry $registry ) { + $registry->register( Size_Variable_Prop_Type::get_key(), new Size_Variable_Prop_Type() ); + } ); + + return $this; + } + + private function register_styles_transformers() { + add_action( 'elementor/atomic-widgets/styles/transformers/register', function ( $registry ) { + $registry->register( Size_Variable_Prop_Type::get_key(), new Global_Variable_Transformer() ); + } ); + + return $this; + } + + private function register_packages() { + add_filter( 'elementor-pro/editor/v2/packages', function ( $packages ) { + return array_merge( $packages, self::PACKAGES ); + } ); + + return $this; + } + + private function filter_for_style_schema() { + add_filter( 'elementor/atomic-widgets/styles/schema', function ( array $schema ) { + return ( new Style_Schema() )->augment( $schema ); + } ); + + return $this; + } +} diff --git a/modules/variables/module.php b/modules/variables/module.php new file mode 100644 index 00000000..2f5523e6 --- /dev/null +++ b/modules/variables/module.php @@ -0,0 +1,59 @@ + self::EXPERIMENT_NAME, + 'title' => esc_html__( 'Size Variables', 'elementor-pro' ), + 'description' => esc_html__( 'Allows the use of size variables within supported controls. Note: This feature requires both the "Atomic Widgets" and "Variables" experiments to be enabled.', 'elementor-pro' ), + 'hidden' => true, + 'default' => ExperimentsManager::STATE_ACTIVE, + 'release_status' => ExperimentsManager::RELEASE_STATUS_ALPHA, + ]; + } + + private function hooks() { + return new Hooks(); + } + + private function is_supported_by_license() { + return API::is_licence_has_feature( 'size-variable', API::BC_VALIDATION_CALLBACK ); + } + + public function __construct() { + parent::__construct(); + + if ( ! $this->is_experiment_active() || ! $this->is_supported_by_license() ) { + return; + } + + $this->hooks()->register(); + } + + private function is_experiment_active(): bool { + return class_exists( 'Elementor\\Modules\\Variables\\Module' ) + && Plugin::elementor()->experiments->is_feature_active( self::EXPERIMENT_NAME ) + && Plugin::elementor()->experiments->is_feature_active( AtomicWidgetsModule::EXPERIMENT_NAME ) + && Plugin::elementor()->experiments->is_feature_active( VariablesModule::EXPERIMENT_NAME ); + } +} diff --git a/modules/variables/prop-types/size-variable-prop-type.php b/modules/variables/prop-types/size-variable-prop-type.php new file mode 100644 index 00000000..ca0fdbda --- /dev/null +++ b/modules/variables/prop-types/size-variable-prop-type.php @@ -0,0 +1,15 @@ +breakpoints->has_custom_breakpoints(); + + wp_register_style( + 'widget-video-playlist', + Plugin::get_frontend_file_url( "widget-video-playlist{$direction_suffix}.min.css", $has_custom_breakpoints ), + [ 'elementor-frontend' ], + $has_custom_breakpoints ? null : ELEMENTOR_PRO_VERSION + ); + } +} diff --git a/modules/video-playlist/widgets/video-playlist.php b/modules/video-playlist/widgets/video-playlist.php new file mode 100644 index 00000000..346b6f59 --- /dev/null +++ b/modules/video-playlist/widgets/video-playlist.php @@ -0,0 +1,2332 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-video-playlist' ]; + } + + protected function register_controls() { + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $this->start_controls_section( + 'section_playlist', + [ + 'label' => esc_html__( 'Playlist', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tabs_direction', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => 'vertical', + 'options' => [ + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + 'vertical' => esc_html__( 'Vertical', 'elementor-pro' ), + ], + 'prefix_class' => 'e-tabs-view-', + ] + ); + + $this->add_control( + 'playlist_title', + [ + 'label' => esc_html__( 'Playlist Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Playlist', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Playlist', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'playlist_title_tag', + [ + 'label' => esc_html__( 'HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'h2', + 'condition' => [ + 'playlist_title!' => '', + ], + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'type', + [ + 'label' => esc_html__( 'Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'youtube', + 'options' => [ + 'youtube' => esc_html__( 'YouTube', 'elementor-pro' ), + 'vimeo' => esc_html__( 'Vimeo', 'elementor-pro' ), + 'hosted' => esc_html__( 'Self Hosted', 'elementor-pro' ), + 'section' => esc_html__( 'Section', 'elementor-pro' ), + ], + ] + ); + + $repeater->add_control( + 'youtube_url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Paste URL', 'elementor-pro' ) . ' (YouTube)', + 'label_block' => true, + 'condition' => [ + 'type' => 'youtube', + ], + ] + ); + + $repeater->add_control( + 'vimeo_url', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::POST_META_CATEGORY, + TagsModule::URL_CATEGORY, + ], + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Enter your URL', 'elementor-pro' ) . ' (Vimeo)', + 'default' => 'https://vimeo.com/235215203', + 'label_block' => true, + 'condition' => [ + 'type' => 'vimeo', + ], + ] + ); + + $repeater->add_control( + 'vimeo_fetch_data', + [ + 'type' => Controls_Manager::BUTTON, + 'label_block' => true, + 'text' => esc_html__( 'Get Video Data', 'elementor-pro' ), + 'event' => 'elementorPlaylistWidget:fetchVideoData', + 'condition' => [ + 'type' => [ 'youtube', 'vimeo' ], + ], + ] + ); + + $repeater->add_control( + 'is_external_url', + [ + 'label' => esc_html__( 'External URL', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'type' => 'hosted', + ], + ] + ); + + $repeater->add_control( + 'hosted_url', + [ + 'label' => esc_html__( 'Choose File', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::MEDIA_CATEGORY, + ], + ], + 'media_types' => [ 'video' ], + 'condition' => [ + 'type' => 'hosted', + 'is_external_url' => '', + ], + ] + ); + + $repeater->add_control( + 'external_url', + [ + 'label' => esc_html__( 'URL', 'elementor-pro' ), + 'type' => Controls_Manager::URL, + 'autocomplete' => false, + 'options' => false, + 'label_block' => true, + 'show_label' => false, + 'dynamic' => [ + 'active' => true, + 'categories' => [ + TagsModule::POST_META_CATEGORY, + TagsModule::URL_CATEGORY, + ], + ], + 'media_types' => [ 'video' ], + 'placeholder' => esc_html__( 'Enter your URL', 'elementor-pro' ), + 'condition' => [ + 'type' => 'hosted', + 'is_external_url' => 'yes', + ], + ] + ); + + $repeater->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Title', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Add Your Text Here', 'elementor-pro' ), + 'label_block' => true, + ] + ); + + $repeater->add_control( + 'section_html_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'h3', + 'condition' => [ + 'type' => 'section', + ], + ] + ); + + $repeater->add_control( + 'video_html_tag', + [ + 'label' => esc_html__( 'Title HTML Tag', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'h1' => 'H1', + 'h2' => 'H2', + 'h3' => 'H3', + 'h4' => 'H4', + 'h5' => 'H5', + 'h6' => 'H6', + 'div' => 'div', + 'span' => 'span', + ], + 'default' => 'h4', + 'condition' => [ + 'type!' => 'section', + ], + ] + ); + + $repeater->add_control( + 'duration', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => '1:05', + 'default' => '', + 'ai' => [ + 'active' => false, + ], + 'condition' => [ + 'type!' => 'section', + ], + ] + ); + + $repeater->add_control( + 'thumbnail', + [ + 'label' => esc_html__( 'Thumbnail', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'dynamic' => [ + 'active' => true, + ], + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'condition' => [ + 'type!' => 'section', + ], + ] + ); + + $repeater->add_control( + 'inner_tab_is_content_visible', + [ + 'label' => esc_html__( 'Contents Tabs ', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'show', + 'default' => '', + 'condition' => [ + 'type' => [ 'youtube', 'hosted', 'vimeo' ], + ], + ] + ); + + $repeater->start_controls_tabs( 'video_tabs' ); + + $repeater->start_controls_tab( + 'inner_tab_1', + [ + 'label' => esc_html__( 'Tab #1', 'elementor-pro' ), + 'condition' => [ + 'type' => [ 'youtube', 'hosted', 'vimeo' ], + 'inner_tab_is_content_visible' => 'show', + ], + ] + ); + + $repeater->add_control( + 'inner_tab_content_1', + [ + 'label' => '', + 'type' => Controls_Manager::WYSIWYG, + 'default' => '

      ' . esc_html__( 'Add some content for each one of your videos, like a description, transcript or external links.To add, remove or edit tab names, go to Tabs.', 'elementor-pro' ) . '

      ', + 'condition' => [ + 'type' => [ 'youtube', 'hosted', 'vimeo' ], + 'inner_tab_is_content_visible' => 'show', + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( + 'inner_tab_2', + [ + 'label' => esc_html__( 'Tab #2', 'elementor-pro' ), + 'condition' => [ + 'type' => [ 'youtube', 'hosted', 'vimeo' ], + 'inner_tab_is_content_visible' => 'show', + ], + ] + ); + + $repeater->add_control( + 'inner_tab_content_2', + [ + 'label' => '', + 'type' => Controls_Manager::WYSIWYG, + 'condition' => [ + 'type' => [ 'youtube', 'hosted', 'vimeo' ], + 'inner_tab_is_content_visible' => 'show', + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $this->add_control( + 'tabs', + [ + 'label' => esc_html__( 'Playlist Items', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'default' => [ + [ + 'title' => esc_html__( 'Sample Video', 'elementor-pro' ), + 'youtube_url' => 'https://www.youtube.com/watch?v=XHOmBV4js_E', + 'duration' => '0:16', + 'thumbnail' => [ 'url' => 'https://img.youtube.com/vi/XHOmBV4js_E/maxresdefault.jpg' ], + ], + [ + 'title' => esc_html__( 'Sample Video', 'elementor-pro' ), + 'youtube_url' => 'https://www.youtube.com/watch?v=XHOmBV4js_E', + 'duration' => '0:16', + 'thumbnail' => [ 'url' => 'https://img.youtube.com/vi/XHOmBV4js_E/maxresdefault.jpg' ], + ], + [ + 'title' => esc_html__( 'Sample Video', 'elementor-pro' ), + 'youtube_url' => 'https://www.youtube.com/watch?v=XHOmBV4js_E', + 'duration' => '0:16', + 'thumbnail' => [ 'url' => 'https://img.youtube.com/vi/XHOmBV4js_E/maxresdefault.jpg' ], + ], + ], + 'frontend_available' => true, + 'title_field' => '{{{ title }}}', + 'separator' => 'before', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_inner_tab', + [ + 'label' => esc_html__( 'Tabs', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'inner_tab_title_1', + [ + 'label' => esc_html__( 'Tab 1 Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Tab #1', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Name', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'inner_tab_title_2', + [ + 'label' => esc_html__( 'Tab 2 Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Tab #2', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Name', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'inner_tab_is_content_collapsible', + [ + 'label' => esc_html__( 'Collapsible', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'collapsible', + 'default' => '', + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'inner_tab_label_show_more', + [ + 'label' => esc_html__( 'Read More Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Show More', 'elementor-pro' ), + 'default' => esc_html__( 'Show More', 'elementor-pro' ), + 'condition' => [ + 'inner_tab_is_content_collapsible' => 'collapsible', + ], + ] + ); + + $this->add_control( + 'inner_tab_label_show_less', + [ + 'label' => esc_html__( 'Read Less Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'placeholder' => esc_html__( 'Show Less', 'elementor-pro' ), + 'default' => esc_html__( 'Show Less', 'elementor-pro' ), + 'condition' => [ + 'inner_tab_is_content_collapsible' => 'collapsible', + ], + ] + ); + + $this->add_responsive_control( + 'inner_tab_collapsible_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'default' => [ + 'size' => 54, + ], + 'range' => [ + 'px' => [ + 'min' => 50, + 'max' => 500, + ], + 'em' => [ + 'min' => 5, + 'max' => 50, + ], + 'rem' => [ + 'min' => 5, + 'max' => 50, + ], + ], + 'render_type' => 'template', + 'selectors' => [ + '{{WRAPPER}} .e-inner-tabs-content-wrapper .collapsible .e-inner-tab-text' => 'height: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'inner_tab_is_content_collapsible' => 'collapsible', + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_image_overlay', + [ + 'label' => esc_html__( 'Image Overlay', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'show_image_overlay', + [ + 'label' => esc_html__( 'Image Overlay', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'image_overlay', + [ + 'label' => esc_html__( 'Choose Image', 'elementor-pro' ), + 'type' => Controls_Manager::MEDIA, + 'default' => [ + 'url' => Utils::get_placeholder_image_src(), + ], + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'show_image_overlay' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Image_Size::get_type(), + [ + 'name' => 'image_overlay', + 'default' => 'full', + 'condition' => [ + 'show_image_overlay' => 'yes', + ], + ] + ); + + $this->add_control( + 'show_play_icon', + [ + 'label' => esc_html__( 'Play Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'far fa-play-circle', + 'library' => 'fa-regular', + ], + 'label_block' => false, + 'skin' => 'inline', + 'condition' => [ + 'show_image_overlay' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_autoplay', + [ + 'label' => esc_html__( 'Autoplay', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'autoplay_on_load', + [ + 'label' => esc_html__( 'On Load', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay_next', + [ + 'label' => esc_html__( 'Next Up', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'show_watched_indication', + [ + 'label' => esc_html__( 'Indicate Watched', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'show_video_count', + [ + 'label' => esc_html__( 'Video Count', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_duration', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'show_thumbnail', + [ + 'label' => esc_html__( 'Thumbnails', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'play_icon', + [ + 'label' => esc_html__( 'Play Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-play-circle', + 'library' => 'fa-solid', + ], + 'label_block' => false, + 'skin' => 'inline', + ] + ); + + $this->add_control( + 'watched_icon', + [ + 'label' => esc_html__( 'Watched Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon', + 'default' => [ + 'value' => 'fas fa-check-circle', + 'library' => 'fa-solid', + ], + 'label_block' => false, + 'skin' => 'inline', + ] + ); + + $this->add_control( + 'lazy_load', + [ + 'label' => esc_html__( 'Lazy Load', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'separator' => 'before', + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'tabs_alignment', + [ + 'label' => esc_html__( 'Video Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'default' => 'end', + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-$start", + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-$end", + ], + ], + 'prefix_class' => 'elementor-layout-', + ] + ); + + $this->add_responsive_control( + 'layout_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 200, + 'max' => 1200, + ], + 'em' => [ + 'min' => 20, + 'max' => 120, + ], + 'rem' => [ + 'min' => 20, + 'max' => 120, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-main-area' => 'height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_top_bar', + [ + 'label' => esc_html__( 'Top Bar', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_playlist_name', + [ + 'label' => esc_html__( 'Playlist Name', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'playlist_name_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-header' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'playlist_name_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-header .e-tabs-title' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'playlist_name_typography', + 'selector' => '{{WRAPPER}} .e-tabs-header .e-tabs-title', + ] + ); + + $this->add_control( + 'heading_videos_amount', + [ + 'label' => esc_html__( 'Video Count', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'videos_amount_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-header .e-tabs-videos-count' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-header .e-tabs-header-right-side i' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-header .e-tabs-header-right-side svg' => 'fill: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'videos_amount_typography', + 'selector' => '{{WRAPPER}} .e-tabs-header .e-tabs-videos-count', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_videos', + [ + 'label' => esc_html__( 'Videos', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'playlist_tabs' ); + + $this->start_controls_tab( + 'playlist_tabs_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_tab_normal', + [ + 'label' => esc_html__( 'Item', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'normal_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items .e-tab-title:not(:where( .e-active ))' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-items-wrapper' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-items-wrapper .shadow-bottom' => 'background: linear-gradient(180deg, transparent 0%, {{VALUE}} 100%)', + '{{WRAPPER}} .e-tabs-wrapper .e-tabs-items-wrapper .shadow-top' => 'background: linear-gradient(0deg, transparent 0%, {{VALUE}} 100%);', + ], + ] + ); + + $this->add_control( + 'normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items .e-tab-title .e-tab-title-text' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items .e-tab-title .e-tab-title-text button' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'normal_typography', + 'selector' => '{{WRAPPER}} .e-tabs-items .e-tab-title .e-tab-title-text button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'heading_duration_normal', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'normal_duration_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items .e-tab-title .e-tab-duration' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'normal_duration_typography', + 'selector' => '{{WRAPPER}} .e-tab-title .e-tab-duration', + ] + ); + + $this->add_control( + 'heading_icon_normal', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'normal_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title i' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title svg' => 'fill: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title svg path' => 'fill: {{VALUE}};', + ], + ] + ); + + // Default shadow values for the icon. + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'normal_icon_top_text_shadow', + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html__( 'Shadow', 'elementor-pro' ), + ], + 'text_shadow' => [ + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title i' => 'text-shadow: {{HORIZONTAL}}px {{VERTICAL}}px {{BLUR}}px {{COLOR}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title svg' => 'filter: drop-shadow({{HORIZONTAL}}px {{VERTICAL}}px {{BLUR}}px {{COLOR}});', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'normal_icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 30, + ], + 'em' => [ + 'min' => 1, + 'max' => 3, + ], + 'rem' => [ + 'min' => 1, + 'max' => 3, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--playlist-item-icon-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_separator_normal', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'normal_separator_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title' => 'border-style: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'normal_separator_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 10, + ], + 'em' => [ + 'max' => 1, + ], + 'rem' => [ + 'max' => 1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title' => 'border-width: 0 0 {{SIZE}}{{UNIT}} 0;', + ], + 'condition' => [ + 'normal_separator_style!' => '', + ], + ] + ); + + $this->add_control( + 'normal_separator_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'normal_separator_style!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'playlist_tabs_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_tab_active', + [ + 'label' => esc_html__( 'Item', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'active_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover )' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'active_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#556068', + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) .e-tab-title-text' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) .e-tab-title-text button' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'active_typography', + 'selector' => '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) .e-tab-title-text button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'heading_duration_active', + [ + 'label' => esc_html__( 'Duration', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'active_duration_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) .e-tab-duration' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'active_duration_typography', + 'selector' => '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) .e-tab-duration', + ] + ); + + $this->add_control( + 'heading_icon_active', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'active_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) i' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) svg' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) svg path' => 'fill: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'active_icon_top_text_shadow', + 'fields_options' => [ + 'text_shadow_type' => [ + 'label' => esc_html__( 'Shadow', 'elementor-pro' ), + ], + ], + 'selector' => '{{WRAPPER}} .e-tab-title:where( .e-active, :hover ) i, {{WRAPPER}} .e-tab-title:where( .e-active, :hover ) svg', + ] + ); + + $this->add_responsive_control( + 'active_icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 10, + 'max' => 30, + ], + 'em' => [ + 'min' => 1, + 'max' => 3, + ], + 'rem' => [ + 'min' => 1, + 'max' => 3, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) span i' => 'font-size: {{SIZE}}{{UNIT}}', + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title:where( .e-active, :hover ) span svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'heading_separator_active', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'active_separator_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title.e-active' => 'border-style: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'active_separator_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 10, + ], + 'em' => [ + 'max' => 1, + ], + 'rem' => [ + 'max' => 1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title.e-active' => 'border-width: 0 0 {{SIZE}}{{UNIT}} 0;', + ], + 'condition' => [ + 'active_separator_style!' => '', + ], + ] + ); + + $this->add_control( + 'active_separator_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-tab-title.e-active' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'active_separator_style!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_sections', + [ + 'label' => esc_html__( 'Sections', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_section', + [ + 'label' => esc_html__( 'Section', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'section_background', + [ + 'label' => esc_html__( 'Background', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'section_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'section_typography', + 'selector' => '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title', + ] + ); + + $this->add_control( + 'section_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'solid', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title' => 'border-style: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'section_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'section_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-items-wrapper .e-section-title' => 'border-color: {{VALUE}};', + ], + ] + ); + $this->end_controls_section(); + + $this->start_controls_section( + 'section_inner_tab_style', + [ + 'label' => esc_html__( 'Tabs', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'inner_tab_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper' => '--inner-tabs-border-height: {{SIZE}}{{UNIT}};', + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active' => 'border-width: 0 0 {{SIZE}}{{UNIT}} 0;', + ], + ] + ); + + $this->add_control( + 'inner_tab_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper' => '--inner-tabs-border-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'inner_tab_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-active' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content' => 'background-color: {{VALUE}};', + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-title' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'heading_inner_tab_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'inner_tab_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'inner_tab_active_title_color', + [ + 'label' => esc_html__( 'Active Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active a' => 'color: {{VALUE}};', + '{{WRAPPER}} .e-tabs .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title.e-inner-tab-active' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'inner_tab_title_typography', + 'selector' => '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-wrapper .e-inner-tab-title a', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_control( + 'heading_inner_tab_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'inner_tab_content_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'inner_tab_content_typography', + 'selector' => '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content .e-inner-tab-text', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + ] + ); + + $this->add_responsive_control( + 'inner_tab_content_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'heading_inner_tab_show_more', + [ + 'label' => esc_html__( 'Show More', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'inner_tab_show_more_color' ); + + $this->start_controls_tab( + 'inner_tab_normal_show_more', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'inner_tab_normal_show_more_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content button' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'inner_tab_hover_show_more', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'inner_tab_hover_show_more_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content button:hover' => 'color: {{VALUE}};', + ], + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + ] + ); + + $this->add_control( + 'inner_tab_hover_show_more_color_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 's', 'ms', 'custom' ], + 'default' => [ + 'unit' => 'ms', + ], + 'selectors' => [ + '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content button' => 'transition-duration: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'inner_tab_show_more_typography', + 'selector' => '{{WRAPPER}} .e-tabs-inner-tabs .e-inner-tabs-content-wrapper .e-inner-tab-content button', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + ] + ); + + $this->end_controls_section(); + } + + private function create_playlist_item_tabs_array( $playlist_item, $playlist_item_index, $tab_1_title, $tab_2_title ) { + $playlist_item_tabs_array = []; + $is_already_activated_tab = false; + + $playlist_item_tabs_content = [ + $playlist_item['inner_tab_content_1'], + $playlist_item['inner_tab_content_2'], + ]; + + $playlist_item_tabs_title = [ + $tab_1_title, + $tab_2_title, + ]; + + foreach ( $playlist_item_tabs_content as $index => $playlist_item_tab_content ) { + $playlist_item_tab_content_object = new \stdClass(); + $playlist_item_tab_content_object->tab_title = $playlist_item_tabs_title[ $index ]; + $playlist_item_tab_content_object->tab_content = $playlist_item_tab_content; + + $tab_index = $index + 1; + $playlist_item_tab_content_object->tab_content_setting_key = $this->get_repeater_setting_key( 'inner_tab_content_' . $tab_index, 'tabs', $playlist_item_index ); + + if ( $playlist_item_tab_content ) { + $playlist_item_tab_content_object->tab_attribute = ! $is_already_activated_tab ? '' : 'hidden'; + $playlist_item_tab_content_object->tab_class = ! $is_already_activated_tab ? 'e-inner-tab-active' : ''; + $is_already_activated_tab = true; + } + + $playlist_item_tabs_array [] = $playlist_item_tab_content_object; + } + + return $playlist_item_tabs_array; + } + + private function create_playlist_item_video_attributes( $index, $id_int, $playlist_item, $video_url = '' ) { + $html_attributes_object = new \stdClass(); + $tab_count = $index + 1; + + // The first tab will be activated and not hidden like the second tab. + $hidden = 1 === $tab_count ? false : 'hidden'; + + $html_attributes_object->attributes = [ + 'id' => 'e-tab-content-' . $id_int . $tab_count, + 'class' => [ 'e-tab-content', 'elementor-clearfix' ], + 'data-tab' => $tab_count, + 'role' => 'tabpanel', + 'aria-labelledby' => 'e-tab-title-' . $id_int . $tab_count, + 'tabindex' => '0', + 'data-video-url' => $video_url, + 'data-video-type' => $playlist_item['type'], + 'data-video-title' => $playlist_item['title'], + 'data-video-duration' => $playlist_item['duration'], + ]; + + if ( $hidden ) { + $html_attributes_object->attributes['hidden'] = $hidden; + } + + return $html_attributes_object; + } + + private function create_playlist_item_title_attributes( $index, $id_int ) { + $html_attributes_object = new \stdClass(); + $tab_count = $index + 1; + + $html_attributes_object->attributes = [ + 'id' => 'e-tab-title-' . $id_int . $tab_count, + 'class' => [ 'e-tab-title', 'e-tab-desktop-title' ], + 'aria-selected' => 1 === $tab_count ? 'true' : 'false', + 'data-tab' => $tab_count, + 'role' => 'tab', + 'tabindex' => 1 === $tab_count ? '0' : '-1', + 'aria-controls' => 'e-tab-content-' . $id_int . $tab_count, + ]; + + return $html_attributes_object; + } + + private function create_playlist_items_array( $playlist_items ) { + $playlist_items_array = []; + $id_int = substr( $this->get_id_int(), 0, 3 ); + + foreach ( $playlist_items as $index => $playlist_item ) { + $playlist_item_object = new \stdClass(); + $playlist_item_object->video_url = ''; + $playlist_item_object->show_overlay_image = false; + $playlist_item_object->is_inner_tabs_visible = $playlist_item['inner_tab_is_content_visible']; + + switch ( $playlist_item['type'] ) { + case 'youtube': + case 'vimeo': + case 'hosted': + $playlist_item_object->type = $playlist_item['type']; + $playlist_item_object->video_title = $playlist_item['title']; + $playlist_item_object->video_html_tag = Utils::validate_html_tag( $playlist_item['video_html_tag'] ); + + if ( $playlist_item['youtube_url'] && 'youtube' === $playlist_item['type'] ) { + $playlist_item_object->video_url = $playlist_item['youtube_url']; + } elseif ( $playlist_item['vimeo_url'] && 'vimeo' === $playlist_item['type'] ) { + $playlist_item_object->video_url = $playlist_item['vimeo_url']; + } elseif ( $playlist_item['external_url'] && 'hosted' === $playlist_item['type'] && 'yes' === $playlist_item['is_external_url'] ) { + $playlist_item_object->video_url = $playlist_item['external_url']['url']; + } elseif ( $playlist_item['hosted_url'] && 'hosted' === $playlist_item['type'] && 'yes' !== $playlist_item['is_external_url'] ) { + $playlist_item_object->video_url = $playlist_item['hosted_url']['url']; + } + + $playlist_item_object->tab_collapsible = $this->get_settings_for_display( 'inner_tab_is_content_collapsible' ); + $playlist_item_object->read_more_label = $this->get_settings_for_display( 'inner_tab_label_show_more' ); + $playlist_item_object->read_less_label = $this->get_settings_for_display( 'inner_tab_label_show_less' ); + + $playlist_item_object->video_duration = ''; + if ( $this->get_settings_for_display( 'show_duration' ) ) { + $playlist_item_object->video_duration = $playlist_item['duration']; + } + + $playlist_item_object->video_thumbnail = ''; + if ( $this->get_settings_for_display( 'show_thumbnail' ) ) { + $playlist_item_object->video_thumbnail = $playlist_item['thumbnail']['url']; + } + + $playlist_item_object->html_attributes_title = $this->create_playlist_item_title_attributes( $index, $id_int ); + + $playlist_item_object->tabs = []; + if ( $playlist_item['inner_tab_content_1'] || $playlist_item['inner_tab_content_2'] ) { + $tab_1_title = $this->get_settings_for_display( 'inner_tab_title_1' ); + $tab_2_title = $this->get_settings_for_display( 'inner_tab_title_2' ); + if ( $playlist_item_object->is_inner_tabs_visible ) { + $playlist_item_object->tabs = $this->create_playlist_item_tabs_array( $playlist_item, $index, $tab_1_title, $tab_2_title ); + } + } + + if ( 0 === $index && 'yes' !== $this->get_settings_for_display( 'autoplay_on_load' ) && $this->get_settings_for_display( 'show_image_overlay' ) ) { + $playlist_item_object->show_overlay_image = true; + } + + break; + case 'section': + $playlist_item_object->type = $playlist_item['type']; + $playlist_item_object->section_title = $playlist_item['title']; + $playlist_item_object->section_html_tag = Utils::validate_html_tag( $playlist_item['section_html_tag'] ); + $playlist_item_object->video_title = ''; + break; + } + + $playlist_item_object->html_attributes_video = $this->create_playlist_item_video_attributes( $index, $id_int, $playlist_item, $playlist_item_object->video_url ); + + $playlist_items_array [] = $playlist_item_object; + } + + return $playlist_items_array; + } + + private function count_video_items( $playlist_items ) { + $filtered_playlist_items = $playlist_items; + foreach ( $filtered_playlist_items as $key => $tab ) { + if ( 'section' === $tab['type'] ) { + unset( $filtered_playlist_items[ $key ] ); + } + } + return count( $filtered_playlist_items ); + } + + private function prepare_video_playlist_data_object() { + $settings = $this->get_settings_for_display(); + $playlist_items = $settings['tabs']; + + $playlist_object = new \stdClass(); + $playlist_object->playlist_name = $settings['playlist_title']; + $playlist_object->playlist_title_tag = Utils::validate_html_tag( $settings['playlist_title_tag'] ); + $playlist_object->is_show_video_count = $settings['show_video_count']; + + if ( $playlist_object->is_show_video_count ) { + $playlist_object->video_count = $this->count_video_items( $playlist_items ); + } + + $playlist_object->show_thumbnails = $settings['show_thumbnail']; + $playlist_object->play_icon = $settings['play_icon']; + $playlist_object->watched_icon = $settings['watched_icon']; + $playlist_object->playlist_items = $this->create_playlist_items_array( $playlist_items ); + $playlist_object->is_image_overlay = $settings['show_image_overlay']; + $playlist_object->image_overlay_icon = $settings['show_play_icon']; + + $image_overlay = $settings['image_overlay']; + if ( ! empty( $image_overlay['url'] ) ) { + $playlist_object->image_overlay_image = Group_Control_Image_Size::get_attachment_image_src( $image_overlay['id'], 'image_overlay', $settings ); + if ( ! $playlist_object->image_overlay_image[1] ) { + $playlist_object->image_overlay_image = $image_overlay['url']; + } + } + + return $playlist_object; + } + + protected function render() { + $playlist_object = $this->prepare_video_playlist_data_object(); + ?> + +
      +
      +
      +
      + <playlist_title_tag ); ?> class="e-tabs-title" id="e-playlist-get_id() ); ?>">playlist_name; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?>playlist_title_tag ); ?>> +
      + is_show_video_count ) : ?> + video_count ); ?> + + 'eicons', + 'value' => 'eicon-caret-down', + ], + [ + 'aria-hidden' => 'true', + 'class' => [ + 'e-tabs-toggle-videos-display-button', + 'rotate-down', + ], + ] + ); + ?> +
      +
      +
      +
      + playlist_items as $item ) : ?> + type ) : ?> + <section_html_tag ); ?> class="e-section-title">section_title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?>section_html_tag ); ?>> + +
      html_attributes_title->attributes ); ?>> + show_thumbnails ) : ?> +
      + video_thumbnail ) : ?> + <?php echo esc_attr( $item->video_title ); ?> + + play_icon, [ 'aria-hidden' => 'true' ] ); ?> + watched_icon, [ 'aria-hidden' => 'true' ] ); ?> +
      + + play_icon, [ 'aria-hidden' => 'true' ] ); ?> + watched_icon, [ 'aria-hidden' => 'true' ] ); ?> + + <video_html_tag ); ?> class="e-tab-title-text"> + + video_html_tag ); ?>> + video_duration ) : ?> + video_duration ); ?> + +
      + + +
      + + +
      +
      + +
      + playlist_items as $item ) : ?> +
      html_attributes_video->attributes ); ?>> +
      + show_overlay_image ) : ?> +
      + image_overlay_icon['value'] ) ) : ?> +
      + image_overlay_icon, [ 'aria-hidden' => 'true' ] ); ?> +
      + +
      + +
      + +
      +
      + +
      + playlist_items as $item ) : ?> + is_inner_tabs_visible ) : ?> +
      html_attributes_video->attributes ); ?>> + tabs ) > 0 ) : ?> +
      + tabs as $tab ) : + if ( $tab->tab_content ) { ?> + + + +
      +
      + tabs as $tab ) : + if ( $tab->tab_content ) { ?> +
      + + tab_title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
      +
      tab_attribute ); ?> class="e-inner-tab-content tab_class ); ?> tab_collapsible ); ?>"> +
      + add_inline_editing_attributes( $tab->tab_content_setting_key, 'advanced' ); ?> +
      print_render_attribute_string( $tab->tab_content_setting_key ); ?>> + + parse_text_editor( $tab->tab_content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
      +
      +
      + + + +
      +
      + + +
      + +
      + + +
      +
      + + <# + + function createPlaylistItemTabsArray( playlistItem, playlistItemIndex, tab1Title, tab2Title ) { + var playlistItemTabsArray = []; + var isAlreadyActivatedTab = false; + + var playlistItemTabsContent = [ + playlistItem.inner_tab_content_1, + playlistItem.inner_tab_content_2, + ]; + + var playlistItemTabsTitle = [ + tab1Title, + tab2Title, + ]; + + playlistItemTabsContent.forEach( function( playlistItemTabContent, index ) { + var playlistItemTabContentObject = {}; + playlistItemTabContentObject.tab_title = playlistItemTabsTitle[ index ]; + playlistItemTabContentObject.tab_content = playlistItemTabContent; + + var tabIndex = index + 1; + playlistItemTabContentObject.tabContentSettingKey = view.getRepeaterSettingKey( 'inner_tab_content_' + tabIndex, 'tabs', playlistItemIndex ); + + if ( playlistItemTabContent ) { + playlistItemTabContentObject.tabAttribute = ! isAlreadyActivatedTab ? '' : 'hidden'; + playlistItemTabContentObject.tabClass = ! isAlreadyActivatedTab ? 'e-inner-tab-active' : ''; + isAlreadyActivatedTab = true; + } + + playlistItemTabsArray.push(playlistItemTabContentObject); + } ); + + return playlistItemTabsArray; + } + + function createPlaylistItemVideoAttributes( index, id, playlistItem, videoUrl ) { + var videoUrl = videoUrl ? videoUrl : ''; + var htmlAttributesObject = {}; + var tabCount = index + 1; + + // The first tab will be activated and not hidden like the second tab. + var hidden = 1 === tabCount ? false : 'hidden'; + + htmlAttributesObject.attributes = { + 'id' : 'e-tab-content-' + id + tabCount, + 'class' : [ 'e-tab-content', 'elementor-clearfix' ], + 'data-tab' : tabCount, + 'role' : 'tabpanel', + 'aria-labelledby' : 'e-tab-title-' + id + tabCount, + 'tabindex' : '0', + 'data-video-url' : videoUrl, + 'data-video-type' : playlistItem.type, + 'data-video-title' : playlistItem.title, + 'data-video-duration' : playlistItem.duration, + }; + + if ( hidden ) { + htmlAttributesObject.attributes.hidden = hidden; + } + + return htmlAttributesObject; + } + + function createPlaylistItemTitleAttributes( index, id ) { + var htmlAttributesObject = {}; + var tabCount = index + 1; + + htmlAttributesObject.attributes = { + 'id' : 'e-tab-title-' + id + tabCount, + 'class' : [ 'e-tab-title', 'e-tab-desktop-title' ], + 'aria-selected' : 1 === tabCount ? 'true' : 'false', + 'data-tab' : tabCount, + 'role' : 'tab', + 'tabindex' : 1 === tabCount ? '0' : '-1', + 'aria-controls' : 'e-tab-content-' + id + tabCount, + }; + + return htmlAttributesObject; + } + + function createPlaylistItemsArray( playlistItems ) { + var playlistItemsArray = []; + id = view.getIDInt().toString().substr( 0, 3 ) + + playlistItems.forEach( function( playlistItem, index ) { + var playlistItemObject = {}; + playlistItemObject.videoUrl = ''; + playlistItemObject.showOverlayImage = false; + playlistItemObject.isInnerTabsVisible = playlistItem.inner_tab_is_content_visible; + + switch ( playlistItem.type ) { + case 'youtube': + case 'vimeo': + case 'hosted': + playlistItemObject.type = playlistItem.type; + playlistItemObject.videoTitle = playlistItem.title; + playlistItemObject.videoHtmlTag = elementor.helpers.validateHTMLTag( playlistItem.video_html_tag ); + + if ( playlistItem.youtube_url && 'youtube' === playlistItem.type ) { + playlistItemObject.videoUrl = playlistItem.youtube_url; + } else if ( playlistItem.vimeo_url && 'vimeo' === playlistItem.type ) { + playlistItemObject.videoUrl = playlistItem.vimeo_url; + } else if ( playlistItem.external_url && 'hosted' === playlistItem.type && 'yes' === playlistItem.is_external_url ) { + playlistItemObject.videoUrl = playlistItem.external_url.url; + } else if ( playlistItem.hosted_url && 'hosted' === playlistItem.type && 'yes' !== playlistItem.is_external_url ) { + playlistItemObject.videoUrl = playlistItem.hosted_url.url; + } + + playlistItemObject.tabCollapsible = settings.inner_tab_is_content_collapsible; + playlistItemObject.readMoreLabel = settings.inner_tab_label_show_more; + playlistItemObject.readLessLabel = settings.inner_tab_label_show_less; + + playlistItemObject.videoDuration = ''; + if ( settings.show_duration ) { + playlistItemObject.videoDuration = playlistItem.duration; + } + + playlistItemObject.videoThumbnail = ''; + if ( settings.show_thumbnail ) { + playlistItemObject.videoThumbnail = playlistItem.thumbnail.url; + } + + playlistItemObject.htmlAttributesTitle = createPlaylistItemTitleAttributes( index, id ); + + playlistItemObject.tabs = []; + if ( playlistItem.inner_tab_content_1 || playlistItem.inner_tab_content_2 ) { + var tab1Title = settings.inner_tab_title_1; + var tab2Title = settings.inner_tab_title_2; + if ( playlistItemObject.isInnerTabsVisible ) { + playlistItemObject.tabs = createPlaylistItemTabsArray( playlistItem, index, tab1Title, tab2Title ); + } + } + + if ( (0 === index) && (settings.autoplay_on_load !== 'yes') && settings.show_image_overlay ) { + playlistItemObject.showOverlayImage = true; + } + + break; + case 'section': + playlistItemObject.type = playlistItem.type; + playlistItemObject.sectionTitle = playlistItem.title; + playlistItemObject.sectionHtmlTag = elementor.helpers.validateHTMLTag( playlistItem.section_html_tag ); + playlistItemObject.isInnerTabsVisible = false; + break; + } + + playlistItemObject.htmlAttributesVideo = createPlaylistItemVideoAttributes( index, id, playlistItem, elementor.helpers.sanitizeUrl( playlistItemObject.videoUrl ) ); + + playlistItemsArray.push(playlistItemObject); + } ); + + return playlistItemsArray; + } + + function countVideoItems( playlistItems ) { + var filteredPlaylistItems = playlistItems.filter(function(playlistItem) { + return 'section' !== playlistItem.type + }); + + return filteredPlaylistItems.length; + } + + function prepare_video_playlist_data_object() { + var playlistItems = settings.tabs + + playlistObject = {}; + playlistObject.playlistName = settings.playlist_title; + playlistObject.playlistNameHTMLTag = elementor.helpers.validateHTMLTag( settings.playlist_title_tag ); + playlistObject.isShowVideoCount = settings.show_video_count; + + if( playlistObject.isShowVideoCount ) { + playlistObject.videoCount = countVideoItems( playlistItems ); + } + + playlistObject.showThumbnails = settings.show_thumbnail; + playlistObject.playIcon = settings.play_icon; + playlistObject.watchedIcon = settings.watched_icon; + playlistObject.playlistItems = createPlaylistItemsArray( playlistItems ); + playlistObject.isImageOverlay = !settings.autoplay_on_load && settings.show_image_overlay ? true : false; + playlistObject.imageOverlayIcon = settings.show_play_icon; + + playlistObject.imageOverlayImage = ''; + imageOverlay = settings.image_overlay; + if ( imageOverlay.url && settings.image_overlay.id && playlistObject.isImageOverlay ) { + var image_overlay_object = { + id: settings.image_overlay.id, + url: settings.image_overlay.url, + size: settings.image_overlay_size, + dimension: settings.image_overlay_custom_dimension, + model: view.getEditModel() + }; + + playlistObject.imageOverlayImage = elementor.imagesManager.getImageUrl( image_overlay_object ); + } else { + playlistObject.imageOverlayImage = imageOverlay.url; + } + + return playlistObject; + } + + var playlistObject = prepare_video_playlist_data_object(); + + var watchedIconHTML = elementor.helpers.renderIcon( view, playlistObject.watchedIcon, { 'aria-hidden': true }, 'i' , 'object' ); + var playIconHTML = elementor.helpers.renderIcon( view, playlistObject.playIcon, { 'aria-hidden': true }, 'i' , 'object' ); + var overlayImagePlayIconHTML = elementor.helpers.renderIcon( view, playlistObject.imageOverlayIcon, { 'aria-hidden': true }, 'i' , 'object' ); + #> +
      +
      +
      +
      + <{{ playlistObject.playlistNameHTMLTag }} class="e-tabs-title" id="e-playlist-get_id() ); ?>"> + {{{ playlistObject.playlistName }}} + +
      + <# if ( playlistObject.isShowVideoCount ) { #> + {{{ playlistObject.videoCount }}} Videos + <# } #> + +
      +
      +
      +
      + <# _.each( playlistObject.playlistItems, function( item, index ) { #> + <# if ( 'section' === item.type ) { #> + <{{ item.sectionHtmlTag }} class="e-section-title"> + {{{ item.sectionTitle }}} + + <# } else { #> + <# + var tabTitleKey = item.htmlAttributesTitle.attributes.id; + view.addRenderAttribute(tabTitleKey, item.htmlAttributesTitle.attributes); + #> +
      + <# if ( playlistObject.showThumbnails ) { #> +
      + <# if ( item.videoThumbnail ) { #> + + <# } #> + {{{ playIconHTML.value }}} + {{{ watchedIconHTML.value }}} +
      + <# } else { #> + {{{ playIconHTML.value }}} + {{{ watchedIconHTML.value }}} + <# } #> + <{{ item.videoHtmlTag }} class="e-tab-title-text"> + + + <# if ( item.videoDuration ) { #> + {{{ item.videoDuration }}} + <# } #> +
      + <# } #> + <# } ); #> +
      + + +
      +
      + +
      + <# _.each( playlistObject.playlistItems, function( item, index ) { #> + + <# + var tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs', index ); + view.addRenderAttribute(tabContentKey, item.htmlAttributesVideo.attributes); + #> +
      +
      + <# if ( item.showOverlayImage ) { #> +
      + <# if ( playlistObject.imageOverlayIcon.value ) { #> +
      + {{{ overlayImagePlayIconHTML.value }}} +
      + <# } #> +
      + <# } #> +
      + <# } ); #> +
      +
      + +
      + <# _.each( playlistObject.playlistItems, function( item, index ) { #> + <# if ( item.isInnerTabsVisible ) { #> + <# + var tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'inner-tabs', index ); + view.addRenderAttribute(tabContentKey, item.htmlAttributesVideo.attributes); + #> +
      + <# if ( item.tabs.length > 0 ) { #> +
      + <# _.each( item.tabs, function( tab ) { #> + <# if ( tab.tab_content ) { #> + + <# } #> + <# }); #> +
      +
      + <# _.each( item.tabs, function( tab ) { #> +
      + {{{ tab.tab_title }}} +
      +
      +
      + <# view.addInlineEditingAttributes( tab.tabContentSettingKey, 'advanced' ); #> +
      + {{{ tab.tab_content }}} +
      +
      +
      + + +
      +
      + <# } ); #> +
      + <# } #> +
      + <# } #> + <# } ); #> +
      +
      + get_query_results(); + + if ( empty( $result->total ) ) { + return ''; + } + + return parent::get_content(); + } +} diff --git a/modules/woocommerce/classes/current-query-renderer.php b/modules/woocommerce/classes/current-query-renderer.php new file mode 100644 index 00000000..10a85cca --- /dev/null +++ b/modules/woocommerce/classes/current-query-renderer.php @@ -0,0 +1,85 @@ +settings = $settings; + $this->type = $type; + $this->attributes = $this->parse_attributes( [ + 'paginate' => $settings['paginate'], + 'cache' => false, + ] ); + $this->query_args = $this->parse_query_args(); + } + + /** + * Override the original `get_query_results` + * with modifications that: + * 1. Remove `pre_get_posts` action if `is_added_product_filter`. + * + * @return bool|mixed|object + */ + protected function get_query_results() { + $query = $GLOBALS['wp_query']; + + $paginated = ! $query->get( 'no_found_rows' ); + + // Check is_object to indicate it's called the first time. + if ( ! empty( $query->posts ) && is_object( $query->posts[0] ) ) { + $query->posts = array_map( function ( $post ) { + return $post->ID; + }, $query->posts ); + } + + $results = (object) array( + 'ids' => wp_parse_id_list( $query->posts ), + 'total' => $paginated ? (int) $query->found_posts : count( $query->posts ), + 'total_pages' => $paginated ? (int) $query->max_num_pages : 1, + 'per_page' => (int) $query->get( 'posts_per_page' ), + 'current_page' => $paginated ? (int) max( 1, $query->get( 'paged', 1 ) ) : 1, + ); + + return $results; + } + + protected function parse_query_args() { + $settings = &$this->settings; + + if ( ! is_page( wc_get_page_id( 'shop' ) ) ) { + $query_args = $GLOBALS['wp_query']->query_vars; + } + + add_action( "woocommerce_shortcode_before_{$this->type}_loop", function () { + wc_set_loop_prop( 'is_shortcode', false ); + } ); + + if ( 'yes' === $settings['paginate'] ) { + $page = get_query_var( 'paged', 1 ); + + if ( 1 < $page ) { + $query_args['paged'] = $page; + } + + if ( 'yes' !== $settings['allow_order'] ) { + remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 ); + } + + if ( 'yes' !== $settings['show_result_count'] ) { + remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 ); + } + } + + // Always query only IDs. + $query_args['fields'] = 'ids'; + + return $query_args; + } + +} diff --git a/modules/woocommerce/classes/products-renderer.php b/modules/woocommerce/classes/products-renderer.php new file mode 100644 index 00000000..64afd41a --- /dev/null +++ b/modules/woocommerce/classes/products-renderer.php @@ -0,0 +1,350 @@ +settings_key_prefix = static::QUERY_CONTROL_NAME . '_'; + $this->settings = $settings; + $this->type = $type; + $this->attributes = $this->parse_attributes( [ + 'columns' => ! empty( $settings['columns'] ) ? $settings['columns'] : self::DEFAULT_COLUMNS_AND_ROWS, + 'rows' => ! empty( $settings['rows'] ) ? $settings['rows'] : self::DEFAULT_COLUMNS_AND_ROWS, + 'paginate' => $settings['paginate'], + 'cache' => false, + ] ); + $this->query_args = $this->parse_query_args(); + } + + /** + * Override the original `get_query_results` + * with modifications that: + * 1. Remove `pre_get_posts` action if `is_added_product_filter`. + * + * @return bool|mixed|object + */ + + protected function get_query_results() { + $results = parent::get_query_results(); + // Start edit. + if ( $this->is_added_product_filter ) { + remove_action( 'pre_get_posts', [ wc()->query, 'product_query' ] ); + } + // End edit. + + return $results; + } + + public function parse_query_args() { + $settings = &$this->settings; + + $query_args = [ + 'post_type' => 'product', + 'post_status' => 'publish', + 'ignore_sticky_posts' => true, + 'no_found_rows' => false === wc_string_to_bool( $this->attributes['paginate'] ), + 'orderby' => $settings[ $this->settings_key_prefix . 'orderby' ], + 'order' => strtoupper( $settings[ $this->settings_key_prefix . 'order' ] ), + ]; + + $query_args['meta_query'] = WC()->query->get_meta_query(); + $query_args['tax_query'] = []; + + if ( 'yes' === $settings['paginate'] && 'yes' === $settings['allow_order'] && ! is_front_page() ) { + $ordering_args = WC()->query->get_catalog_ordering_args(); + } else { + $ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] ); + } + + if ( in_array( $this->settings[ $this->settings_key_prefix . 'post_type' ], [ 'related_products', 'upsells', 'cross_sells' ], true ) ) { + $query_args['post_type'] = [ 'product', 'product_variation' ]; + } + + $query_args['orderby'] = $ordering_args['orderby']; + $query_args['order'] = $ordering_args['order']; + + if ( $this->orderby_option_needs_meta_key( $query_args['orderby'] ) ) { + $ordering_args['meta_key'] = $this->get_orderby_meta_key( $query_args['orderby'] ); + $query_args['orderby'] = 'meta_value_num'; + } + + if ( $ordering_args['meta_key'] ) { + $query_args['meta_key'] = $ordering_args['meta_key']; + } + + // fallback to the widget's default settings in case settings was left empty: + $rows = $this->attributes['rows']; + $columns = $this->attributes['columns']; + $query_args['posts_per_page'] = $settings['posts_per_page'] ?? intval( $columns * $rows ); + + $this->set_visibility_query_args( $query_args ); + + $this->set_featured_query_args( $query_args ); + + $this->set_sale_products_query_args( $query_args ); + + $this->set_single_product_query_args( $query_args ); + + $this->set_ids_query_args( $query_args ); + + // Set specific types query args. + if ( method_exists( $this, "set_{$this->type}_query_args" ) ) { + $this->{"set_{$this->type}_query_args"}( $query_args ); + } + + $this->set_terms_query_args( $query_args ); + + $this->set_authors_query_args( $query_args ); + + $this->set_exclude_query_args( $query_args ); + + $this->set_pagination_args( $query_args ); + + $query_args = apply_filters( 'woocommerce_shortcode_products_query', $query_args, $this->attributes, $this->type ); + + // Always query only IDs. + $query_args['fields'] = 'ids'; + + return $query_args; + } + + protected function orderby_option_needs_meta_key( $orderby ) { + return in_array( $orderby, [ 'price', 'rating', 'popularity' ] ); + } + + protected function get_orderby_meta_key( $orderby ) { + switch ( $orderby ) { + case 'price': + return '_price'; + case 'rating': + return '_wc_average_rating'; + case 'popularity': + return 'total_sales'; + default: + return 'menu_order title'; + } + } + + protected function set_ids_query_args( &$query_args ) { + if ( 'by_id' !== $this->settings[ $this->settings_key_prefix . 'post_type' ] ) { + return; + } + + $this->set_by_id_query_args( $query_args ); + } + + protected function set_by_id_query_args( &$query_args ) { + $post__in = $this->settings[ $this->settings_key_prefix . 'posts_ids' ]; + + if ( empty( $post__in ) ) { + return; + } + + $this->set_post_in_query_args( $query_args, $post__in ); + } + + protected function set_post_in_query_args( &$query_args, $post__in ) { + $query_args['post__in'] = isset( $query_args['post__in'] ) ? array_merge( $post__in, $query_args['post__in'] ) : $post__in; + remove_action( 'pre_get_posts', [ wc()->query, 'product_query' ] ); + } + + private function set_terms_query_args( &$query_args ) { + if ( ! $this->is_include_query_type( 'terms' ) ) { + return; + } + + $tax_query = []; + + if ( ! empty( $this->settings[ $this->settings_key_prefix . 'include_term_ids' ] ) ) { + $terms = []; + foreach ( $this->settings[ $this->settings_key_prefix . 'include_term_ids' ] as $id ) { + $term_data = get_term_by( 'term_taxonomy_id', $id ); + $taxonomy = $term_data->taxonomy; + $terms[ $taxonomy ][] = $id; + } + foreach ( $terms as $taxonomy => $ids ) { + $query = [ + 'taxonomy' => $taxonomy, + 'field' => 'term_taxonomy_id', + 'terms' => $ids, + ]; + + $tax_query[] = $query; + } + } + + if ( ! empty( $tax_query ) ) { + $query_args['tax_query'] = array_merge( $query_args['tax_query'], $tax_query ); + } + } + + private function set_authors_query_args( &$query_args ) { + if ( ! $this->is_include_query_type( 'authors' ) ) { + return; + } + + if ( ! empty( $this->settings[ $this->settings_key_prefix . 'include_authors' ] ) ) { + $query_args['author__in'] = $this->settings[ $this->settings_key_prefix . 'include_authors' ]; + } + } + + protected function set_featured_query_args( &$query_args ) { + if ( 'featured' !== $this->settings[ $this->settings_key_prefix . 'post_type' ] ) { + return; + } + + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + $query_args['tax_query'][] = [ + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => [ $product_visibility_term_ids['featured'] ], + ]; + } + + protected function set_sale_products_query_args( &$query_args ) { + if ( 'sale' !== $this->settings[ $this->settings_key_prefix . 'post_type' ] ) { + return; + } + + parent::set_sale_products_query_args( $query_args ); + } + + protected function set_single_product_query_args( &$query_args ) { + if ( ! in_array( $this->settings[ $this->settings_key_prefix . 'post_type' ], [ 'related_products', 'upsells', 'cross_sells' ], true ) ) { + return; + } + + global $product; + + $this->set_post_in_query_args( $query_args, [ 0 ] ); + + switch ( $this->settings[ $this->settings_key_prefix . 'post_type' ] ) { + case 'related_products': + if ( ! $product ) { + return; + } + + $products = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $query_args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' ); + break; + case 'upsells': + if ( ! $product ) { + return; + } + + $products = array_filter( array_map( 'wc_get_product', $product->get_upsell_ids() ), 'wc_products_array_filter_visible' ); + break; + case 'cross_sells': + if ( is_checkout() ) { + return; + } + + $products = array_filter( array_map( 'wc_get_product', WC()->cart->get_cross_sells() ), 'wc_products_array_filter_visible' ); + break; + } + + if ( empty( $products ) ) { + return; + } + + $post__in = array_map( function ( $product ) { + return $product->get_id(); + }, $products ); + + $this->set_post_in_query_args( $query_args, $post__in ); + } + + protected function set_exclude_query_args( &$query_args ) { + if ( empty( $this->settings[ $this->settings_key_prefix . 'exclude' ] ) ) { + return; + } + $post__not_in = []; + if ( in_array( 'current_post', $this->settings[ $this->settings_key_prefix . 'exclude' ], true ) ) { + if ( is_singular() ) { + $post__not_in[] = get_queried_object_id(); + } + } + + if ( in_array( 'manual_selection', $this->settings[ $this->settings_key_prefix . 'exclude' ] ) && ! empty( $this->settings[ $this->settings_key_prefix . 'exclude_ids' ] ) ) { + $post__not_in = array_merge( $post__not_in, $this->settings[ $this->settings_key_prefix . 'exclude_ids' ] ); + } + + $query_args['post__not_in'] = empty( $query_args['post__not_in'] ) ? $post__not_in : array_merge( $query_args['post__not_in'], $post__not_in ); + + /** + * WC populates `post__in` with the ids of the products that are on sale. + * Since WP_Query ignores `post__not_in` once `post__in` exists, the ids are filtered manually, using `array_diff`. + */ + if ( in_array( $this->settings[ $this->settings_key_prefix . 'post_type' ], [ 'sale', 'related_products', 'upsells', 'cross_sells' ] ) ) { + $query_args['post__in'] = array_diff( $query_args['post__in'], $query_args['post__not_in'] ); + } + + if ( in_array( 'terms', $this->settings[ $this->settings_key_prefix . 'exclude' ] ) && ! empty( $this->settings[ $this->settings_key_prefix . 'exclude_term_ids' ] ) ) { + $terms = []; + foreach ( $this->settings[ $this->settings_key_prefix . 'exclude_term_ids' ] as $to_exclude ) { + $term_data = get_term_by( 'term_taxonomy_id', $to_exclude ); + $terms[ $term_data->taxonomy ][] = $to_exclude; + } + $tax_query = []; + foreach ( $terms as $taxonomy => $ids ) { + $tax_query[] = [ + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $ids, + 'operator' => 'NOT IN', + ]; + } + if ( empty( $query_args['tax_query'] ) ) { + $query_args['tax_query'] = $tax_query; + } else { + $query_args['tax_query']['relation'] = 'AND'; + $query_args['tax_query'][] = $tax_query; + } + } + } + + protected function set_pagination_args( &$query_args ) { + if ( 'yes' !== $this->settings['paginate'] ) { + return; + } + + $this->set_paged_args( $query_args ); + + if ( 'yes' !== $this->settings['allow_order'] || is_front_page() ) { + remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 ); + } + + if ( 'yes' !== $this->settings['show_result_count'] ) { + remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 ); + } + } + + protected function set_paged_args( &$query_args ) { + $page = max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) ); + $page = absint( empty( $_GET['product-page'] ) ? $page : $_GET['product-page'] ); + + if ( 1 === $page ) { + return; + } + + $query_args['paged'] = $page; + } + + private function is_include_query_type( $type ) { + return ( + ! empty( $this->settings[ $this->settings_key_prefix . 'include' ] ) + && in_array( $type, $this->settings[ $this->settings_key_prefix . 'include' ], true ) + ); + } +} diff --git a/modules/woocommerce/conditions/product-archive.php b/modules/woocommerce/conditions/product-archive.php new file mode 100644 index 00000000..81d8e2c9 --- /dev/null +++ b/modules/woocommerce/conditions/product-archive.php @@ -0,0 +1,61 @@ +post_type, 'objects' ); + $this->post_taxonomies = wp_filter_object_list( $taxonomies, [ + 'public' => true, + 'show_in_nav_menus' => true, + ] ); + + parent::__construct( $data ); + } + + public static function get_type() { + return 'archive'; + } + + public function get_name() { + return 'product_archive'; + } + + public static function get_priority() { + return 40; + } + + public function get_label() { + return esc_html__( 'Product Archive', 'elementor-pro' ); + } + + public function get_all_label() { + return esc_html__( 'All Product Archives', 'elementor-pro' ); + } + + public function register_sub_conditions() { + $this->register_sub_condition( new Shop_page() ); + $this->register_sub_condition( new Product_Search() ); + + foreach ( $this->post_taxonomies as $slug => $object ) { + $condition = new ThemeBuilder\Conditions\Taxonomy( [ + 'object' => $object, + ] ); + $this->register_sub_condition( $condition ); + } + } + + public function check( $args ) { + return is_shop() || is_product_taxonomy() || Module::is_product_search(); + } +} diff --git a/modules/woocommerce/conditions/product-search.php b/modules/woocommerce/conditions/product-search.php new file mode 100644 index 00000000..45a8b467 --- /dev/null +++ b/modules/woocommerce/conditions/product-search.php @@ -0,0 +1,32 @@ + 'product', + ] ); + + $this->register_sub_condition( $product_archive ); + $this->register_sub_condition( $product_single ); + } + + public function check( $args ) { + return is_woocommerce() || Module::is_product_search(); + } +} diff --git a/modules/woocommerce/documents/product-archive.php b/modules/woocommerce/documents/product-archive.php new file mode 100644 index 00000000..5352f0b2 --- /dev/null +++ b/modules/woocommerce/documents/product-archive.php @@ -0,0 +1,170 @@ + esc_html__( 'What is a Products Archive Template?', 'elementor-pro' ), + 'content' => esc_html__( 'A products archive template allows you to easily design the layout and style of your WooCommerce shop page or other product archive pages - those pages that show a list of products, which may be filtered by terms such as categories, tags, etc.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple products archive templates, and assign each to different categories of products. This gives you the freedom to customize the appearance for each type of product being shown.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-products-archive', + 'video_url' => 'https://www.youtube.com/embed/cQLeirgkguA', + ]; + } + + public function enqueue_scripts() { + // In preview mode it's not a real Woocommerce page - enqueue manually. + if ( Plugin::elementor()->preview->is_preview_mode( $this->get_main_id() ) ) { + wp_enqueue_script( 'woocommerce' ); + } + } + + public function get_container_attributes() { + $attributes = parent::get_container_attributes(); + + $attributes['class'] .= ' product'; + + return $attributes; + } + + public function filter_body_classes( $body_classes ) { + $body_classes = parent::filter_body_classes( $body_classes ); + + if ( get_the_ID() === $this->get_main_id() || Plugin::elementor()->preview->is_preview_mode( $this->get_main_id() ) ) { + $body_classes[] = 'woocommerce'; + } + + return $body_classes; + } + + public static function get_preview_as_default() { + return 'post_type_archive/product'; + } + + public static function get_preview_as_options() { + $post_type_archives = []; + $taxonomies = []; + $post_type = 'product'; + + $post_type_object = get_post_type_object( $post_type ); + + $post_type_archives[ 'post_type_archive/' . $post_type ] = $post_type_object->label . ' ' . esc_html__( 'Archive', 'elementor-pro' ); + + $post_type_taxonomies = get_object_taxonomies( $post_type, 'objects' ); + + $post_type_taxonomies = wp_filter_object_list( $post_type_taxonomies, [ + 'public' => true, + 'show_in_nav_menus' => true, + ] ); + + foreach ( $post_type_taxonomies as $slug => $object ) { + $taxonomies[ 'taxonomy/' . $slug ] = $object->label . ' ' . esc_html__( 'Archive', 'elementor-pro' ); + } + + $options = [ + 'search' => esc_html__( 'Search Results', 'elementor-pro' ), + ]; + + $options += $taxonomies + $post_type_archives; + + return [ + 'archive' => [ + 'label' => esc_html__( 'Archive', 'elementor-pro' ), + 'options' => $options, + ], + ]; + } + + public function __construct( array $data = [] ) { + parent::__construct( $data ); + + add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ], 11 ); + } + + protected static function get_editor_panel_categories() { + $categories = [ + 'woocommerce-elements-archive' => [ + 'title' => esc_html__( 'Product Archive', 'elementor-pro' ), + ], + // Move to top as active. + 'woocommerce-elements' => [ + 'title' => esc_html__( 'WooCommerce', 'elementor-pro' ), + 'active' => true, + ], + ]; + + $categories += parent::get_editor_panel_categories(); + + unset( $categories['theme-elements-archive'] ); + + return $categories; + } + + public static function get_editor_panel_config() { + $config = parent::get_editor_panel_config(); + $config['widgets_settings']['theme-archive-title']['categories'][] = 'woocommerce-elements-archive'; + + return $config; + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'preview_type', + [ + 'default' => 'post_type_archive/product', + ] + ); + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'product archive'; + + return $config; + } +} diff --git a/modules/woocommerce/documents/product-post.php b/modules/woocommerce/documents/product-post.php new file mode 100644 index 00000000..d6a30335 --- /dev/null +++ b/modules/woocommerce/documents/product-post.php @@ -0,0 +1,77 @@ + static::get_type(), + ] ); + } + + protected static function get_editor_panel_categories() { + $categories = parent::get_editor_panel_categories(); + + unset( $categories['theme-elements-single'] ); + + $categories = Utils::array_inject( + $categories, + 'theme-elements', + [ + 'woocommerce-elements-single' => [ + 'title' => esc_html__( 'Product', 'elementor-pro' ), + 'active' => false, + ], + ] + ); + + return $categories; + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'single product'; + + return $config; + } +} diff --git a/modules/woocommerce/documents/product.php b/modules/woocommerce/documents/product.php new file mode 100644 index 00000000..b7ce28c4 --- /dev/null +++ b/modules/woocommerce/documents/product.php @@ -0,0 +1,198 @@ + esc_html__( 'What is a Single Product Template?', 'elementor-pro' ), + 'content' => esc_html__( 'A single product template allows you to easily design the layout and style of WooCommerce single product pages, and apply that template to various conditions that you assign.', 'elementor-pro' ), + 'tip' => esc_html__( 'You can create multiple single product templates, and assign each to different types of products, enabling a custom design for each group of similar products.', 'elementor-pro' ), + 'docs' => 'https://go.elementor.com/app-theme-builder-product', + 'video_url' => 'https://www.youtube.com/embed/PjhoB1RWkBM', + ]; + } + + public static function get_editor_panel_config() { + $config = parent::get_editor_panel_config(); + $config['widgets_settings']['woocommerce-product-content'] = [ + 'show_in_panel' => true, + ]; + + return $config; + } + + public function enqueue_scripts() { + // In preview mode it's not a real Product page - enqueue manually. + if ( Plugin::elementor()->preview->is_preview_mode( $this->get_main_id() ) ) { + global $product; + + if ( is_singular( 'product' ) ) { + $product = wc_get_product(); + } + + if ( current_theme_supports( 'wc-product-gallery-zoom' ) ) { + wp_enqueue_script( 'zoom' ); + } + if ( current_theme_supports( 'wc-product-gallery-slider' ) ) { + wp_enqueue_script( 'flexslider' ); + } + if ( current_theme_supports( 'wc-product-gallery-lightbox' ) ) { + wp_enqueue_script( 'photoswipe-ui-default' ); + wp_enqueue_style( 'photoswipe-default-skin' ); + add_action( 'wp_footer', 'woocommerce_photoswipe' ); + } + wp_enqueue_script( 'wc-single-product' ); + + wp_enqueue_style( 'photoswipe' ); + wp_enqueue_style( 'photoswipe-default-skin' ); + wp_enqueue_style( 'photoswipe-default-skin' ); + wp_enqueue_style( 'woocommerce_prettyPhoto_css' ); + } + } + + public function get_depended_widget() { + return Plugin::elementor()->widgets_manager->get_widget_types( 'woocommerce-product-data-tabs' ); + } + + public function get_container_attributes() { + $attributes = parent::get_container_attributes(); + + $attributes['class'] .= ' product'; + + return $attributes; + } + + public function filter_body_classes( $body_classes ) { + $body_classes = parent::filter_body_classes( $body_classes ); + + if ( get_the_ID() === $this->get_main_id() || Plugin::elementor()->preview->is_preview_mode( $this->get_main_id() ) ) { + $body_classes[] = 'woocommerce'; + } + + return $body_classes; + } + + public function before_get_content() { + parent::before_get_content(); + + global $product; + if ( ! is_object( $product ) ) { + $product = wc_get_product( get_the_ID() ); + } + + do_action( 'woocommerce_before_single_product' ); + } + + public function after_get_content() { + parent::after_get_content(); + + do_action( 'woocommerce_after_single_product' ); + } + + public function print_content() { + if ( post_password_required() ) { + // PHPCS - It's a safe WP template function + echo get_the_password_form(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return; + } + + parent::print_content(); + } + + public function __construct( array $data = [] ) { + parent::__construct( $data ); + + add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ], 11 ); + } + + protected static function get_editor_panel_categories() { + $categories = [ + 'woocommerce-elements-single' => [ + 'title' => esc_html__( 'Product', 'elementor-pro' ), + + ], + // Move to top as active. + 'woocommerce-elements' => [ + 'title' => esc_html__( 'WooCommerce', 'elementor-pro' ), + 'active' => true, + ], + ]; + + $categories += parent::get_editor_panel_categories(); + + unset( $categories['theme-elements-single'] ); + + return $categories; + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'preview_type', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => 'single/product', + ] + ); + + $latest_posts = get_posts( [ + 'posts_per_page' => 1, + 'post_type' => 'product', + ] ); + + if ( ! empty( $latest_posts ) ) { + $this->update_control( + 'preview_id', + [ + 'default' => $latest_posts[0]->ID, + ] + ); + } + } + + protected function get_remote_library_config() { + $config = parent::get_remote_library_config(); + + $config['category'] = 'single product'; + + return $config; + } +} diff --git a/modules/woocommerce/module.php b/modules/woocommerce/module.php new file mode 100644 index 00000000..0300c449 --- /dev/null +++ b/modules/woocommerce/module.php @@ -0,0 +1,1690 @@ + 'Products', + 'wc-products' => 'Products_Deprecated', + 'woocommerce-product-add-to-cart' => 'Product_Add_To_Cart', + 'wc-elements' => 'Elements', + 'wc-categories' => 'Categories', + 'woocommerce-product-price' => 'Product_Price', + 'woocommerce-product-title' => 'Product_Title', + 'woocommerce-product-images' => 'Product_Images', + 'woocommerce-product-upsell' => 'Product_Upsell', + 'woocommerce-product-short-description' => 'Product_Short_Description', + 'woocommerce-product-meta' => 'Product_Meta', + 'woocommerce-product-stock' => 'Product_Stock', + 'woocommerce-product-rating' => 'Product_Rating', + 'woocommerce-product-data-tabs' => 'Product_Data_Tabs', + 'woocommerce-product-related' => 'Product_Related', + 'woocommerce-breadcrumb' => 'Breadcrumb', + 'wc-add-to-cart' => 'Add_To_Cart', + 'wc-archive-products' => 'Archive_Products', + 'woocommerce-archive-products' => 'Archive_Products_Deprecated', + 'woocommerce-product-additional-information' => 'Product_Additional_Information', + 'woocommerce-menu-cart' => 'Menu_Cart', + 'woocommerce-product-content' => 'Product_Content', + 'woocommerce-archive-description' => 'Archive_Description', + 'woocommerce-checkout-page' => 'Checkout', + 'woocommerce-cart' => 'Cart', + 'woocommerce-my-account' => 'My_Account', + 'woocommerce-purchase-summary' => 'Purchase_Summary', + 'woocommerce-notices' => 'Notices', + 'wc-single-elements' => 'Single_Elements', + ]; + const WIDGET_HAS_CUSTOM_BREAKPOINTS = true; + + protected $docs_types = []; + protected $use_mini_cart_template; + protected $woocommerce_notices_elements = []; + + public static function is_active() { + return class_exists( 'woocommerce' ); + } + + public static function is_product_search() { + return is_search() && 'product' === get_query_var( 'post_type' ); + } + + /** + * @param $settings + * @param string $icon + * @return void + */ + public static function render_menu_icon( $settings, string $icon ) { + if ( ! empty( $settings['icon'] ) && 'custom' === $settings['icon'] ) { + self::render_custom_menu_icon( $settings ); + } else { + Icons_Manager::render_icon( [ + 'library' => 'eicons', + 'value' => 'eicon-' . $icon, + ] ); + } + } + + /** + * @param $settings + * @return void + */ + private static function render_custom_menu_icon( $settings ) { + if ( empty( $settings['menu_icon_svg'] ) ) { + echo ''; // Default Custom icon. + } else { + Icons_Manager::render_icon( $settings['menu_icon_svg'], [ + 'class' => 'e-toggle-cart-custom-icon', + 'aria-hidden' => 'true', + ] ); + } + } + + public function get_name() { + return 'woocommerce'; + } + + public function get_widgets() { + return API::filter_active_features( static::WIDGET_NAME_CLASS_NAME_MAP ); + } + + const RECOMMENDED_POSTS_WIDGET_NAMES = [ + 'theme-post-featured-image', + 'woocommerce-product-title', + 'woocommerce-product-add-to-cart', + 'woocommerce-product-price', + 'woocommerce-product-rating', + 'woocommerce-product-stock', + 'woocommerce-product-meta', + 'woocommerce-product-short-description', + 'woocommerce-product-content', + 'woocommerce-product-data-tabs', + 'woocommerce-product-additional-information', + ]; + + // 'WC page name' => 'Elementor widget name' + const WC_STATUS_PAGES_MAPPED_TO_WIDGETS = [ + 'Cart' => 'woocommerce-cart', + 'Checkout' => 'woocommerce-checkout-page', + 'My account' => 'woocommerce-my-account', + ]; + + public function add_product_post_class( $classes ) { + $classes[] = 'product'; + + return $classes; + } + + public function add_products_post_class_filter() { + add_filter( 'post_class', [ $this, 'add_product_post_class' ] ); + } + + public function remove_products_post_class_filter() { + remove_filter( 'post_class', [ $this, 'add_product_post_class' ] ); + } + + public function register_tags() { + if ( ! API::is_licence_has_feature( static::DYNAMIC_TAGS_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + return; + } + + $tags = [ + 'Product_Gallery', + 'Product_Image', + 'Product_Price', + 'Product_Rating', + 'Product_Sale', + 'Product_Content', + 'Product_Short_Description', + 'Product_SKU', + 'Product_Stock', + 'Product_Terms', + 'Product_Title', + 'Category_Image', + 'Woocommerce_Add_To_Cart', + ]; + + /** @var \Elementor\Core\DynamicTags\Manager $module */ + $module = Plugin::elementor()->dynamic_tags; + + $module->register_group( self::WOOCOMMERCE_GROUP, [ + 'title' => esc_html__( 'WooCommerce', 'elementor-pro' ), + ] ); + + foreach ( $tags as $tag ) { + $tag = 'ElementorPro\\Modules\\Woocommerce\\tags\\' . $tag; + + $module->register( new $tag() ); + } + } + + public function register_wc_hooks() { + wc()->frontend_includes(); + } + + /** + * @param Conditions_Manager $conditions_manager + */ + public function register_conditions( $conditions_manager ) { + $woocommerce_condition = new Woocommerce(); + + $conditions_manager->get_condition( 'general' )->register_sub_condition( $woocommerce_condition ); + } + + /** + * @param Documents_Manager $documents_manager + */ + public function register_documents( $documents_manager ) { + if ( API::is_licence_has_feature( static::SINGLE_PRODUCT_TEMPLATE_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->docs_types = [ + 'product-post' => Product_Post::get_class_full_name(), + ]; + + $this->docs_types['product'] = Product::get_class_full_name(); + } + + if ( API::is_licence_has_feature( static::ARCHIVE_PRODUCT_TEMPLATE_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->docs_types['product-archive'] = Product_Archive::get_class_full_name(); + } + + foreach ( $this->docs_types as $type => $class_name ) { + $documents_manager->register_document_type( $type, $class_name ); + } + } + + public static function render_menu_cart_toggle_button( $settings ) { + if ( null === WC()->cart ) { + return; + } + $product_count = WC()->cart->get_cart_contents_count(); + $sub_total = WC()->cart->get_cart_subtotal(); + $icon = ! empty( $settings['icon'] ) ? $settings['icon'] : 'cart-medium'; + ?> + + cart ) { + return; + } + + $widget_cart_is_hidden = apply_filters( 'woocommerce_widget_cart_is_hidden', false ); + $is_edit_mode = Plugin::elementor()->editor->is_edit_mode(); + ?> +
      + +
      + + +
      + +
      + +
      + 'e-close-cart-custom-icon', + 'aria-hidden' => 'true', + ] ); + } + ?> +
      + editor->set_edit_mode( true ); + } + + foreach ( $templates as $id ) { + $this->get_all_fragments( $id, $all_fragments ); + } + + wp_send_json( [ 'fragments' => $all_fragments ] ); + } + + /** + * Get All Fragments. + * + * @since 3.7.0 + * + * @param $id + * @param $all_fragments + * @return void + */ + public function get_all_fragments( $id, &$all_fragments ) { + $fragments_in_document = $this->get_fragments_in_document( $id ); + + if ( $fragments_in_document ) { + $all_fragments += $fragments_in_document; + } + } + + /** + * Get Fragments In Document. + * + * A general function that will return any needed fragments for a Post. + * + * @since 3.7.0 + * @access public + * + * @param int $id + * + * @return mixed $fragments + */ + public function get_fragments_in_document( $id ) { + $document = Plugin::elementor()->documents->get( $id ); + + if ( ! is_object( $document ) ) { + return false; + } + + $fragments = []; + + $data = $document->get_elements_data(); + + Plugin::elementor()->db->iterate_data( + $data, + $this->get_fragments_handler( $fragments ) + ); + + return ! empty( $fragments ) ? $fragments : false; + } + + /** + * Get Fragments Handler. + * + * @since 3.7.0 + * + * @param array $fragments + * @return void + */ + public function get_fragments_handler( array &$fragments ) { + return function ( $element ) use ( &$fragments ) { + if ( ! isset( $element['widgetType'] ) ) { + return; + } + + $fragment_data = $this->get_fragment_data( $element ); + $total_fragments = count( $fragment_data ) / 2; + + for ( $i = 0; $i < $total_fragments; $i++ ) { + $fragments[ $fragment_data['selector'][ $i ] ] = $fragment_data['html'][ $i ]; + } + }; + } + + /** + * Empty Cart Fragments + * + * When the Cart is emptied, the selected 'Empty Cart Template' needs to be added as an item + * in the WooCommerce `$fragments` array, so that WC will push the custom Template content into the DOM. + * This is done to prevent the need for a page refresh after the cart is cleared. + * + * @since 3.7.0 + * + * @param array $fragments + * @return array + */ + public function empty_cart_fragments( $fragments ) { + // Only do this when the cart is empty. + if ( WC()->cart->get_cart_contents_count() !== 0 ) { + return $fragments; + } + + $document = Plugin::elementor()->documents->get( url_to_postid( wp_get_referer() ) ); + + if ( is_object( $document ) ) { + $data = $document->get_elements_data(); + + Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$fragments ) { + if ( + isset( $element['widgetType'] ) + && 'woocommerce-cart' === $element['widgetType'] + && ( isset( $element['settings']['additional_template_switch'] ) && 'active' === $element['settings']['additional_template_switch'] ) + && ( isset( $element['settings']['additional_template_select'] ) && 0 < $element['settings']['additional_template_select'] ) + ) { + $fragments[ 'div.elementor-element-' . $element['id'] . ' .elementor-widget-container' ] = '
      ' . do_shortcode( '[elementor-template id="' . $element['settings']['additional_template_select'] . '"]' ) . '
      '; + } + } ); + } + + return $fragments; + } + + public function maybe_init_cart() { + $has_cart = is_a( WC()->cart, 'WC_Cart' ); + + if ( ! $has_cart ) { + $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' ); + WC()->session = new $session_class(); + WC()->session->init(); + WC()->cart = new \WC_Cart(); + WC()->customer = new \WC_Customer( get_current_user_id(), true ); + } + } + + public function localized_settings_frontend( $settings ) { + $has_cart = is_a( WC()->cart, 'WC_Cart' ); + + if ( $has_cart ) { + $settings['woocommerce']['menu_cart'] = [ + 'cart_page_url' => wc_get_cart_url(), + 'checkout_page_url' => wc_get_checkout_url(), + 'fragments_nonce' => wp_create_nonce( self::MENU_CART_FRAGMENTS_ACTION ), + ]; + } + return $settings; + } + + public function theme_template_include( $need_override_location, $location ) { + if ( is_product() && 'single' === $location ) { + $need_override_location = true; + } + + return $need_override_location; + } + + public function add_loop_recommended_widgets( $config, $post_id ) { + if ( ! $this->is_source_set_to_products( $post_id ) ) { + return $config; + } + + $config = $this->add_woocommerce_widgets_to_recommended( $config ); + return $this->hide_woocommerce_widgets_in_loop_document( $config ); + } + + /** + * Add plugin path to wc template search path. + * Based on: https://www.skyverge.com/blog/override-woocommerce-template-file-within-a-plugin/ + * @param $template + * @param $template_name + * @param $template_path + * + * @return string + */ + public function woocommerce_locate_template( $template, $template_name, $template_path ) { + + if ( self::TEMPLATE_MINI_CART !== $template_name ) { + return $template; + } + + if ( ! $this->use_mini_cart_template ) { + return $template; + } + + $plugin_path = plugin_dir_path( __DIR__ ) . 'woocommerce/wc-templates/'; + + if ( file_exists( $plugin_path . $template_name ) ) { + $template = $plugin_path . $template_name; + } + + return $template; + } + + /** + * WooCommerce/WordPress widget(s), some of the widgets have css classes that used by final selectors. + * before this filter, all those widgets were warped by `.elementor-widget-container` without chain original widget + * classes, now they will be warped by div with the original css classes. + * + * @param array $default_widget_args + * @param \Elementor\Widget_WordPress $widget + * + * @return array $default_widget_args + */ + public function woocommerce_wordpress_widget_css_class( $default_widget_args, $widget ) { + $widget_instance = $widget->get_widget_instance(); + + if ( ! empty( $widget_instance->widget_cssclass ) ) { + $default_widget_args['before_widget'] .= '
      '; + $default_widget_args['after_widget'] .= '
      '; + } + + return $default_widget_args; + } + + public function register_admin_fields( Settings $settings ) { + if ( ! API::is_licence_has_feature( static::MENU_CART_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + return; + } + + $settings->add_section( Settings::TAB_INTEGRATIONS, 'woocommerce', [ + 'callback' => function() { + echo '

      ' . esc_html__( 'WooCommerce', 'elementor-pro' ) . '

      '; + }, + 'fields' => [ + self::OPTION_NAME_USE_MINI_CART => [ + 'label' => esc_html__( 'Mini Cart Template', 'elementor-pro' ), + 'field_args' => [ + 'type' => 'select', + 'std' => 'initial', + 'options' => [ + 'initial' => '', // Relevant until either menu-cart widget is used or option is explicitly set to 'no'. + 'no' => esc_html__( 'Disable', 'elementor-pro' ), + 'yes' => esc_html__( 'Enable', 'elementor-pro' ), + ], + 'desc' => esc_html__( 'Set to `Disable` in order to use your Theme\'s or WooCommerce\'s mini-cart template instead of Elementor\'s.', 'elementor-pro' ), + ], + ], + ], + ] ); + } + + /** + * Load Widget Before WooCommerce Ajax. + * + * When outputting the complex WooCommerce shortcodes (which we use in our widgets) e.g. Checkout, Cart, etc. WC + * immediately does more ajax calls and retrieves updated html fragments based on the data in the forms that may + * be autofilled by the current user's browser e.g. the Payment section holding the "Place order" button. + * + * This function runs before these ajax calls. Using the `elementorPageId` and `elementorWidgetId` querystring + * appended to the forms `_wp_http_referer` url field, or the referer page ID, it loads the relevant Elementor widget. + * The rendered Elementor widget replaces the default WooCommerce template used to refresh WooCommerce elements in the page. + * + * This is necessary for example in the Checkout Payment section where we modify the Terms & Conditions text + * using settings from the widget or when updating shipping methods on the Cart. + * + * @since 3.5.0 + */ + public function load_widget_before_wc_ajax() { + // Make sure is a WooCommerce ajax call. + $wc_ajax = ProUtils::_unstable_get_super_global_value( $_GET, 'wc-ajax' ); + if ( ! $wc_ajax ) { + return; + } + + // Only handle relevant WC AJAX calls + if ( ! in_array( $wc_ajax, [ 'update_order_review', 'update_shipping_method' ], true ) ) { + return; + } + + // Security checks. + switch ( $wc_ajax ) { + case 'update_order_review': + check_ajax_referer( 'update-order-review', 'security' ); + break; + case 'update_shipping_method': + check_ajax_referer( 'update-shipping-method', 'security' ); + break; + } + + $page_id = false; + $widget_id = false; + + // Try to get the `$page_id` and `$widget_id` we added as a query string to `_wp_http_referer` in `post_data`. + // This is only available when a form is submitted. + $raw_post_data = ProUtils::_unstable_get_super_global_value( $_POST, 'post_data' ); + if ( $raw_post_data ) { + $raw_post_data = html_entity_decode( $raw_post_data ); + + parse_str( $raw_post_data, $post_data ); + + if ( isset( $post_data['_wp_http_referer'] ) ) { + $wp_http_referer = wp_unslash( $post_data['_wp_http_referer'] ); + + $wp_http_referer_query_string = wp_parse_url( $wp_http_referer, PHP_URL_QUERY ); + if ( ! empty( $wp_http_referer_query_string ) ) { + parse_str( $wp_http_referer_query_string, $wp_http_referer_query_string ); + + if ( isset( $wp_http_referer_query_string['elementorPageId'] ) ) { + $page_id = $wp_http_referer_query_string['elementorPageId']; + } + + if ( isset( $wp_http_referer_query_string['elementorWidgetId'] ) ) { + $widget_id = $wp_http_referer_query_string['elementorWidgetId']; + } + } + } + } + + if ( ! $page_id ) { + $page_id = url_to_postid( wp_get_referer() ); + } + + // Bail if no `$page_id`. + if ( ! $page_id ) { + return; + } + + // Get Elementor document from `$page_id`. + $document = Plugin::elementor()->documents->get_doc_for_frontend( $page_id ); + + // Bail if not Elementor page. + if ( ! $document ) { + return; + } + + // Setup $page_id as the WP global $post, so is available to our widgets. + $post = get_post( $page_id, OBJECT ); + setup_postdata( $post ); + + $widget_data = false; + if ( $widget_id ) { + // If we did manage to pass `$widget_id` to this ajax call we get the widget data by its ID. + $widget_data = Utils::find_element_recursive( $document->get_elements_data(), $widget_id ); + } else { + // If we didn't manage to pass `$widget_id` to this ajax call we use this alternate method and get the first + // of the type of widget used on the WC endpoint pages responsible for these ajax calls - cart or checkout widget. + $woocommerce_widgets = [ 'woocommerce-cart', 'woocommerce-checkout-page' ]; + + $document_data = $document->get_elements_data(); + Plugin::elementor()->db->iterate_data( $document_data, function( $element ) use ( $woocommerce_widgets, &$widget_data ) { + if ( $widget_data && ( ! isset( $element['widgetType'] ) || ! in_array( $element['widgetType'], $woocommerce_widgets, true ) ) ) { + return; + } + $widget_data = $element; + } ); + } + + // If we found a widget then run `add_render_hooks()` widget method. + if ( $widget_data ) { + $widget_instance = Plugin::elementor()->elements_manager->create_element_instance( $widget_data ); + if ( method_exists( $widget_instance, 'add_render_hooks' ) ) { + $widget_instance->add_render_hooks(); + } + } + } + + /** + * Elementor Woocommerce Checkout Login User + * + * Handle the Ajax call for the custom login form on the Checkout Widget + * + * @since 3.5.0 + */ + public function elementor_woocommerce_checkout_login_user() { + if ( is_user_logged_in() ) { + wp_logout(); + } + + $error = false; + $error_message = ''; + + if ( ! wp_verify_nonce( ProUtils::_unstable_get_super_global_value( $_POST, 'nonce' ), 'woocommerce-login' ) ) { + $error = true; + $error_message = sprintf( + /* translators: 1: Bold text opening tag, 2: Bold text closing tag. */ + esc_html__( '%1$sError:%2$s The nonce security check didn’t pass. Please reload the page and try again. You may want to try clearing your browser cache as a last attempt.', 'elementor-pro' ), + '', + '' + ); + } else { + $info = [ + 'user_login' => trim( ProUtils::_unstable_get_super_global_value( $_POST, 'username' ) ), + 'user_password' => $_POST['password'] ?? '', // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, A password should not be sanitized. + 'remember' => ProUtils::_unstable_get_super_global_value( $_POST, 'remember' ), + ]; + + $user_signon = wp_signon( $info, false ); + + if ( is_wp_error( $user_signon ) ) { + $error = true; + $error_message = $user_signon->get_error_message(); + } + } + + if ( $error ) { + wc_add_notice( + $error_message, + 'error' + ); + $response = [ + 'logged_in' => false, + 'message' => wc_print_notices( true ), + ]; + } else { + $response = [ 'logged_in' => true ]; + } + + echo wp_json_encode( $response ); + wp_die(); + } + + /** + * Register Ajax Actions. + * + * Registers ajax action used by the Editor js. + * + * @since 3.5.0 + * + * @param Ajax $ajax + */ + public function register_ajax_actions( Ajax $ajax ) { + // `woocommerce_update_page_option` is called in the editor save-show-modal.js. + $ajax->register_ajax_action( 'pro_woocommerce_update_page_option', [ $this, 'update_page_option' ] ); + $ajax->register_ajax_action( 'pro_woocommerce_mock_notices', [ $this, 'woocommerce_mock_notices' ] ); + } + + /** + * @throws \Exception + */ + public function woocommerce_mock_notices( $data ) { + $document = ProUtils::_unstable_get_document_for_edit( $data['editor_post_id'] ); + + if ( in_array( 'wc_error', $data['notice_elements'], true ) ) { + $notice_message = sprintf( + '%1$s %2$s', + esc_html__( 'This is how an error notice would look.', 'elementor-pro' ), + esc_html__( 'Here\'s a link', 'elementor-pro' ) + ); + wc_add_notice( $notice_message, 'error' ); + } + + if ( in_array( 'wc_message', $data['notice_elements'], true ) ) { + $notice_message = sprintf( + '%1$s %2$s %3$s', + esc_html__( 'Button', 'elementor-pro' ), + esc_html__( 'This is what a WooCommerce message notice looks like.', 'elementor-pro' ), + esc_html__( 'Here\'s a link', 'elementor-pro' ) + ); + wc_add_notice( $notice_message, 'success' ); + } + + if ( in_array( 'wc_info', $data['notice_elements'], true ) ) { + $notice_message = sprintf( + '%1$s %2$s', + esc_html__( 'Button', 'elementor-pro' ), + esc_html__( 'This is how WooCommerce provides an info notice.', 'elementor-pro' ) + ); + wc_add_notice( $notice_message, 'notice' ); + } + + return '
      ' . wc_print_notices( true ) . '
      '; + } + + /** + * Update Page Option. + * + * Ajax action can be used to update any WooCommerce option. + * + * @since 3.5.0 + * + * @param array $data + */ + public function update_page_option( $data ) { + $is_admin = current_user_can( 'manage_options' ); + $is_shop_manager = current_user_can( 'manage_woocommerce' ); + $is_allowed = $is_admin || $is_shop_manager; + + if ( ! $is_allowed ) { + return new \WP_Error( 401 ); + } + + $allowed_options = [ + 'woocommerce_checkout_page_id', + 'woocommerce_cart_page_id', + 'woocommerce_myaccount_page_id', + 'elementor_woocommerce_purchase_summary_page_id', + ]; + + $option_name = $data['option_name']; + $post_id = absint( $data['editor_post_id'] ); + + if ( ! in_array( $option_name, $allowed_options, true ) ) { + return new \WP_Error( 400 ); + } + + update_option( $option_name, $post_id ); + } + + public function init_site_settings( \Elementor\Core\Kits\Documents\Kit $kit ) { + $kit->register_tab( 'settings-woocommerce', \ElementorPro\Modules\Woocommerce\Settings\Settings_Woocommerce::class ); + } + + public function add_products_type_to_template_popup( $form ) { + $this->add_products_to_options( $form, '_elementor_source' ); + } + + public function add_products_type_to_loop_settings_query( $form ) { + $this->add_products_to_options( $form, 'source' ); + } + + public function add_products_taxonomy_type_to_template_popup( $form ) { + $this->add_taxonomies_to_options( $form, '_elementor_source' ); + } + + public function add_products_taxonomy_type_to_loop_settings_query( $form ) { + $this->add_taxonomies_to_options( $form, 'source' ); + } + + public function e_cart_count_fragments( $fragments ) { + $product_count = WC()->cart->get_cart_contents_count(); + + $fragments['.elementor-menu-cart__toggle_button span.elementor-button-text'] = '' . WC()->cart->get_cart_subtotal() . ''; + $fragments['.elementor-menu-cart__toggle_button span.elementor-button-icon-qty'] = '' . $product_count . ''; + + return $fragments; + } + + /** + * @param $form + * @param $control_name + * @return void + */ + protected function add_products_to_options( $form, $control_name ) { + if ( empty( $form ) ) { + return; + } + + $controls = $form->get_controls( $control_name ); + if ( ! $controls || ! isset( $controls['options'] ) ) { + return; + } + + $options = $controls['options']; + $options[ self::LOOP_PRODUCT_SKIN_ID ] = esc_html__( 'Products', 'elementor-pro' ); + + $form->update_control( $control_name, [ + 'options' => $options, + ] ); + } + + protected function add_taxonomies_to_options( $form, $control_name ) { + $controls = $form->get_controls( $control_name ); + + if ( ! $controls || ! isset( $controls['options'] ) ) { + return; + } + + $options = $controls['options']; + $options[ self::LOOP_PRODUCT_TAXONOMY_SKIN_ID ] = esc_html__( 'Product Taxonomy', 'elementor-pro' ); + + $form->update_control($control_name, [ + 'options' => $options, + ]); + } + + /** + * Add Update Kit Settings Hooks + * + * Add hooks that update the corresponding kit setting when the WooCommerce option is updated. + */ + public function add_update_kit_settings_hooks() { + add_action( 'update_option_woocommerce_cart_page_id', function( $old_value, $value ) { + Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_cart_page_id', $value ); + }, 10, 2 ); + + add_action( 'update_option_woocommerce_checkout_page_id', function( $old_value, $value ) { + Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_checkout_page_id', $value ); + }, 10, 2 ); + + add_action( 'update_option_woocommerce_myaccount_page_id', function( $old_value, $value ) { + Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_myaccount_page_id', $value ); + }, 10, 2 ); + + add_action( 'update_option_woocommerce_terms_page_id', function( $old_value, $value ) { + Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_terms_page_id', $value ); + }, 10, 2 ); + } + + /** + * Elementor WC My Account Logout + * + * Programatically log out if $_REQUEST['elementor_wc_logout'] is set. + * The $_REQUEST variables we have generated a custom logout URL for in the My Account menu. + * + * @since 3.5.0 + */ + public function elementor_wc_my_account_logout() { + $elementor_wc_logout = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor_wc_logout' ); + $nonce = ProUtils::_unstable_get_super_global_value( $_REQUEST, '_wpnonce' ); + + if ( $elementor_wc_logout && $nonce && wp_verify_nonce( $nonce, 'customer-logout' ) ) { + wp_logout(); // Log the user out Programatically. + wp_safe_redirect( esc_url( ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor_my_account_redirect' ) ) ); // Redirect back to the widget page. + exit; + } + } + + /** + * Add Localize Data + * + * Makes `woocommercePages` available with the page name and the associated post ID for use with the various + * widgets site settings modal. + * + * @param $settings + * @return array + */ + public function add_localize_data( $settings ) { + $settings['woocommerce']['woocommercePages'] = [ + 'checkout' => wc_get_page_id( 'checkout' ), + 'cart' => wc_get_page_id( 'cart' ), + 'myaccount' => wc_get_page_id( 'myaccount' ), + 'purchase_summary' => get_option( 'elementor_woocommerce_purchase_summary_page_id' ), + ]; + + return $settings; + } + + /** + * Localize Added To Cart On Product Single + * + * WooCommerce doesn't trigger `added_to_cart` event on its products single page which is required for us to + * automatically open our Menu Cart if the settings is chosen. We make the `productAddedToCart` setting + * available that we can use in the Menu Cart js to check if a product has just been added. + * + * @since 3.5.0 + */ + public function localize_added_to_cart_on_product_single() { + add_filter( 'elementor_pro/frontend/localize_settings', function ( $settings ) { + $settings['woocommerce']['productAddedToCart'] = true; + return $settings; + } ); + } + + public function e_notices_body_classes( $classes ) { + if ( $this->should_load_wc_notices_styles() ) { + foreach ( $this->get_styled_notice_elements() as $notice_element ) { + $classes[] = 'e-' . str_replace( '_', '-', $notice_element ) . '-notice'; + } + } + + return $classes; + } + + public function get_styled_notice_elements() { + if ( empty( $this->woocommerce_notices_elements ) ) { + $kit = Plugin::elementor()->kits_manager->get_active_kit_for_frontend(); + $this->woocommerce_notices_elements = $kit->get_settings_for_display( 'woocommerce_notices_elements' ); + } + + return ! empty( $this->woocommerce_notices_elements ) ? $this->woocommerce_notices_elements : []; + } + + public function e_notices_css() { + if ( ! $this->should_load_wc_notices_styles() ) { + return false; + } + + wp_enqueue_style( + 'e-woocommerce-notices', + ELEMENTOR_PRO_URL . 'assets/css/woocommerce-notices.min.css', + [], + ELEMENTOR_PRO_VERSION + ); + } + + public function get_order_received_endpoint_url( $url, $endpoint, $value ) { + $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' ); + + if ( $order_received_endpoint === $endpoint ) { + $woocommerce_purchase_summary_page_id = get_option( 'elementor_woocommerce_purchase_summary_page_id' ); + $order = wc_get_order( $value ); + + if ( $woocommerce_purchase_summary_page_id && $order ) { + $url = trailingslashit( trailingslashit( trailingslashit( get_permalink( $woocommerce_purchase_summary_page_id ) ) . $order_received_endpoint ) . $order->get_id() ); + } + } + + return $url; + } + + public function maybe_define_woocommerce_checkout() { + $woocommerce_purchase_summary_page_id = get_option( 'elementor_woocommerce_purchase_summary_page_id' ); + + if ( $woocommerce_purchase_summary_page_id && intval( $woocommerce_purchase_summary_page_id ) === get_queried_object_id() ) { + if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) { + define( 'WOOCOMMERCE_CHECKOUT', true ); + } + } + } + + /** + * Products Query Sources Fragments. + * + * Since we introduced additional query sources to the Products Widget, + * some of these query sources can now be used outside of the Single Product template. + * + * For example the Related Products and Cross-Sells. + * + * But now we'll need to make those sections also update when the Cart is updated. So + * we'll do this by creating fragments for each of these. + * + * @since 3.7.0 + * + * @param array $fragments + * + * @return array + */ + public function products_query_sources_fragments( $fragments ) { + if ( WC()->cart->get_cart_contents_count() !== 0 ) { + $document = Plugin::elementor()->documents->get( url_to_postid( wp_get_referer() ) ); + + if ( is_object( $document ) ) { + $data = $document->get_elements_data(); + + Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$fragments ) { + if ( + isset( $element['widgetType'] ) + && 'woocommerce-products' === $element['widgetType'] + ) { + $settings = $element['settings']; + if ( isset( $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ] ) ) { + $query_type = $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ]; + $query_types_to_check = [ 'related_products', 'upsells', 'cross_sells' ]; + + if ( in_array( $query_type, $query_types_to_check, true ) ) { + switch ( $query_type ) { + case 'related_products': + $content = self::get_products_related_content( $settings ); + break; + case 'upsells': + $content = self::get_upsells_content( $settings ); + break; + case 'cross_sells': + $content = self::get_cross_sells_content( $settings ); + break; + default: + $content = null; + } + + if ( $content ) { + $fragments[ 'div.elementor-element-' . $element['id'] . ' div.elementor-widget-container' ] = '
      ' . $content . '
      '; + } + } + } + } + } ); + } + } else { + $fragments['div.elementor-widget-container .woocommerce .cross-sells'] = '
      '; + + $fragments['div.elementor-widget-container .woocommerce section.up-sells'] = '
      '; + } + + return $fragments; + } + + /** + * Get Products Related Content. + * + * A function to return content for the 'related' products query type in the Products widget. + * This function is declared in the Module file so it can be accessed during a WC fragment refresh + * and also be used in the Product widget's render method. + * + * @since 3.7.0 + * @access public + * + * @param array $settings + * + * @return mixed The content or false + */ + public static function get_products_related_content( $settings ) { + global $product; + + $product = wc_get_product(); + + if ( ! $product ) { + return; + } + + return self::get_product_widget_content( + $settings, + 'related_products', + 'woocommerce_product_related_products_heading', + 'products_related_title_text' + ); + } + + /** + * Get Upsells Content. + * + * A function to return content for the 'upsell' query type in the Products widget. + * This function is declared in the Module file so it can be accessed during a WC fragment refresh + * and also be used in the Product widget's render method. + * + * @since 3.7.0 + * @access public + * + * @param array $settings + * + * @return mixed The content or false + */ + public static function get_upsells_content( $settings ) { + return self::get_product_widget_content( + $settings, + 'upsells', + 'woocommerce_product_upsells_products_heading', + 'products_upsells_title_text' + ); + } + + /** + * Get Cross Sells Content. + * + * A function to return content for the 'cross_sells' query type in the Products widget. + * This function is declared in the Module file so it can be accessed during a WC fragment refresh + * and also be used in the Product widget's render method. + * + * @since 3.7.0 + * @access public + * + * @param array $settings + * + * @return mixed The content or false + */ + public static function get_cross_sells_content( $settings ) { + return self::get_product_widget_content( + $settings, + 'cross_sells', + 'woocommerce_product_cross_sells_products_heading', + 'products_cross_sells_title_text' + ); + } + + /** + * Print Woocommerce Shipping Message + * + * Format the shipping messages that will be displayed on the Cart and Checkout Widgets. + * This will add extra classes to those messages so that we can target certain messages + * with certain style controls. + * + * @since 3.5.0 + * + * @param string $html the original HTML from WC + * @param string $classes the classes we will surround $html with + * @return string the final formatted HTML that will be rendered + */ + private function print_woocommerce_shipping_message( $html, $classes ) { + return '' . $html . ''; + } + + /** + * Should load WC Notices Styles + * + * Determine if we should load the WooCommerce notices CSS. + * It should only load: + * - When we are in the Editor, regardless if any notices have been activated. + * - If WooCoomerce is active. + * - When we are on the front end, if at least one notice is activated. + * + * It should not load in WP Admin. + * + * @return boolean + */ + private function should_load_wc_notices_styles() { + if ( ! API::is_licence_has_feature( static::SITE_SETTINGS_NOTICES_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + return false; + } + + $woocommerce_active = in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ); + $is_editor = ProUtils::_unstable_get_super_global_value( $_GET, 'elementor-preview' ); + + // Editor checks. + if ( $woocommerce_active && $is_editor ) { + return true; + } + + // Front end checks. + if ( + 0 < count( $this->get_styled_notice_elements() ) // At least one notice has been activated. + && $woocommerce_active // WooCommerce is active. + && ( ! is_admin() || $is_editor ) // We are not in WP Admin. + ) { + return true; + } + + return false; + } + + /** + * Get Product Widget Content. + * + * A general function to create markup for the new query types in the Products widget. + * + * @since 3.7.0 + * @access private + * + * @param array $settings The widget settings. + * @param string $type The query type to create content for. + * @param string $title_hook The hook name to filter in the widget title. + * @param string $title_key The control ID for the section title. + * + * @return mixed The content or false + */ + private static function get_product_widget_content( $settings, $type, $title_hook, $title_key = '' ) { + add_filter( $title_hook, function ( $heading ) use ( $settings, $title_key ) { + $title_text = isset( $settings[ $title_key ] ) ? $settings[ $title_key ] : ''; + + if ( ! empty( $title_text ) ) { + return $title_text; + } + + return $heading; + }, 10, 1 ); + + ob_start(); + + $args = self::parse_product_widget_args( $settings, $type ); + + if ( 'related_products' === $type ) { + woocommerce_related_products( $args ); + } elseif ( 'upsells' === $type ) { + woocommerce_upsell_display( $args['limit'], $args['columns'], $args['orderby'], $args['order'] ); + } else { + /** + * We need to wrap this content in the 'woocommerce' class for the layout to have the correct styling. + * Because this will only be used as a separate widget on the Cart page, + * the normal 'woocommerce' div from the cart widget will be closed before this content. + */ + echo '
      '; + woocommerce_cross_sell_display( $args['limit'], $args['columns'], $args['orderby'], $args['order'] ); + echo '
      '; + } + + $products_html = ob_get_clean(); + + remove_filter( $title_hook, function() {}, 10 ); + + if ( $products_html ) { + $products_html = str_replace( '
        '-1', + 'columns' => ! empty( $settings['columns'] ) ? $settings['columns'] : 4, + 'orderby' => ! empty( $settings[ "{$query_name}_orderby" ] ) ? $settings[ "{$query_name}_orderby" ] : 'rand', + 'order' => ! empty( $settings[ "{$query_name}_order" ] ) ? $settings[ "{$query_name}_order" ] : 'desc', + ]; + + if ( ! empty( $settings['rows'] ) ) { + $args[ $limit_key ] = $args['columns'] * $settings['rows']; + } + + return $args; + } + + /** + * Get Fragment Data. + * + * A function that will return the selector and HTML for WC fragments. + * + * @since 3.7.0 + * @access private + * + * @param array $element + * + * @return array $fragment_data + */ + private function get_fragment_data( $element ) { + $fragment_data = []; + + if ( 'woocommerce-menu-cart' === $element['widgetType'] ) { + ob_start(); + self::render_menu_cart_toggle_button( $element['settings'] ); + $fragment_data['html'][] = ob_get_clean(); + + $fragment_data['selector'][] = 'div.elementor-element-' . $element['id'] . ' div.elementor-menu-cart__toggle'; + } + + return $fragment_data; + } + + /** + * Is Preview + * + * Helper to check if we are doing either: + * - Viewing the WP Preview page - also used as the Elementor preview page when clicking "Preview Changes" in the editor + * - Viewing the page in the editor, but not the active page being edited e.g. if you click Edit Header while editing a page + * + * @since 3.7.0 + * + * @return bool + */ + public static function is_preview() { + return Plugin::elementor()->preview->is_preview_mode() || is_preview(); + } + + public function __construct() { + parent::__construct(); + + add_action( 'elementor/kit/register_tabs', [ $this, 'init_site_settings' ], 1, 40 ); + $this->add_update_kit_settings_hooks(); + + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'add_products_type_to_template_popup' ], 11 ); + add_action( 'elementor-pro/modules/loop-builder/documents/loop/query_settings', [ $this, 'add_products_type_to_loop_settings_query' ], 11 ); + + add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'add_products_taxonomy_type_to_template_popup' ], 13 ); + add_action( 'elementor-pro/modules/loop-builder/documents/loop/query_settings', [ $this, 'add_products_taxonomy_type_to_loop_settings_query' ], 13 ); + + $this->use_mini_cart_template = 'yes' === get_option( 'elementor_' . self::OPTION_NAME_USE_MINI_CART, 'no' ); + + if ( is_admin() ) { + add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 ); + } + + add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'maybe_init_cart' ] ); + add_action( 'elementor/dynamic_tags/register', [ $this, 'register_tags' ] ); + add_action( 'elementor/documents/register', [ $this, 'register_documents' ] ); + add_action( 'elementor/theme/register_conditions', [ $this, 'register_conditions' ] ); + + add_action( 'wp_ajax_elementor_woocommerce_checkout_login_user', [ $this, 'elementor_woocommerce_checkout_login_user' ] ); + add_action( 'wp_ajax_nopriv_elementor_woocommerce_checkout_login_user', [ $this, 'elementor_woocommerce_checkout_login_user' ] ); + + add_action( 'wp_ajax_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] ); + add_action( 'wp_ajax_nopriv_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] ); + + add_filter( 'woocommerce_add_to_cart_fragments', [ $this, 'e_cart_count_fragments' ] ); + + add_filter( 'elementor/theme/need_override_location', [ $this, 'theme_template_include' ], 10, 2 ); + + add_filter( 'elementor/document/config', [ $this, 'add_loop_recommended_widgets' ], 11, 2 ); + + add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'localized_settings_frontend' ] ); + + // Load our widget Before WooCommerce Ajax. See the variable's PHPDoc for details. + add_action( 'woocommerce_checkout_update_order_review', [ $this, 'load_widget_before_wc_ajax' ] ); + add_action( 'woocommerce_before_calculate_totals', [ $this, 'load_widget_before_wc_ajax' ] ); + + // On Editor - Register WooCommerce frontend hooks before the Editor init. + // Priority = 5, in order to allow plugins remove/add their wc hooks on init. + $action = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'action' ); + if ( 'elementor' === $action && is_admin() ) { + add_action( 'init', [ $this, 'register_wc_hooks' ], 5 ); + } + + // Allow viewing of Checkout page in the Editor with an empty cart. + if ( + ( 'elementor' === $action && is_admin() ) // Elementor Editor + || 'elementor_ajax' === $action // Elementor Editor Preview - Ajax Render Widget + || ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor-preview' ) // Elementor Editor Preview + ) { + add_filter( 'woocommerce_checkout_redirect_empty_cart', '__return_false', 5 ); + } + + if ( $this->use_mini_cart_template ) { + add_filter( 'woocommerce_locate_template', [ $this, 'woocommerce_locate_template' ], 10, 3 ); + } + + $wc_ajax = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'wc-ajax' ); + if ( 'get_refreshed_fragments' === $wc_ajax ) { + add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'products_query_sources_fragments' ] ); + // Render the Empty Cart Template on WC fragment refresh + add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'empty_cart_fragments' ] ); + } + + add_filter( 'elementor/widgets/wordpress/widget_args', [ $this, 'woocommerce_wordpress_widget_css_class' ], 10, 2 ); + + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); + + // Make the Logout redirect go to our my account widget page instead of the set My Account Page. + add_action( 'init', [ $this, 'elementor_wc_my_account_logout' ], 5 ); + + add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_localize_data' ] ); + + add_action( 'wp', [ $this, 'maybe_define_woocommerce_checkout' ] ); + + add_filter( 'woocommerce_get_endpoint_url', [ $this, 'get_order_received_endpoint_url' ], 10, 3 ); + + // Filters for messages on the Shipping calculator + add_filter( 'woocommerce_shipping_may_be_available_html', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-may-be-available-html e-checkout-message e-cart-content' ); + }, 10, 1 ); + + add_filter( 'woocommerce_shipping_not_enabled_on_cart_html', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-not_enabled-on-cart-html e-checkout-message e-cart-content' ); + }, 10, 1 ); + + add_filter( 'woocommerce_shipping_estimate_html', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-estimate-html e-checkout-message e-cart-content' ); + }, 10, 1 ); + + add_filter( 'woocommerce_cart_no_shipping_available_html', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-cart-no-shipping-available-html e-checkout-message e-cart-content' ); + }, 10, 1 ); + + add_filter( 'woocommerce_no_available_payment_methods_message', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-available-payment-methods-message e-description' ); + }, 10, 1 ); + + add_filter( 'woocommerce_no_shipping_available_html', function ( $html ) { + return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-shipping-available-html e-checkout-message' ); + }, 10, 1 ); + + add_action( 'woocommerce_add_to_cart', [ $this, 'localize_added_to_cart_on_product_single' ] ); + + foreach ( LoopBuilderModule::LOOP_WIDGETS as $widget_type ) { + add_action( 'elementor/widget/' . $widget_type . '/skins_init', function( Widget_Base $widget ) { + $widget->add_skin( new Skin_Loop_Product( $widget ) ); + } ); + add_action( 'elementor/widget/' . $widget_type . '/skins_init', function ( Widget_Base $widget ) { + $widget->add_skin( new Skin_Loop_Product_Taxonomy( $widget ) ); + }, 13 ); + } + + // WooCommerce Notice Site Settings + add_filter( 'body_class', [ $this, 'e_notices_body_classes' ] ); + add_filter( 'wp_enqueue_scripts', [ $this, 'e_notices_css' ] ); + + add_filter( 'elementor/query/query_args', function( $query_args, $widget ) { + return $this->loop_query( $query_args, $widget ); + }, 10, 2 ); + + add_filter( 'woocommerce_rest_prepare_system_status', function( $response, $system_status, $request ) { + return $this->add_system_status_data( $response, $system_status, $request ); + }, 10, 3 ); + + add_filter( 'elementor/editor/localize_settings', function ( $config ) { + return $this->populate_persistent_settings( $config ); + }); + + add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] ); + } + + public function add_system_status_data( $response, $system_status, $request ) { + foreach ( $response->data['pages'] as $index => $wc_page ) { + $this->modify_response_if_widget_exists_in_page( $wc_page, $response, $index ); + } + + return $response; + } + + private function modify_response_if_widget_exists_in_page( $wc_page, &$response, $index ) { + if ( empty( $wc_page['page_name'] ) || empty( $wc_page['page_id'] ) || ! array_key_exists( $wc_page['page_name'], static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS ) ) { + return; + } + + if ( isset( $wc_page['shortcode_present'] ) && false !== $wc_page['shortcode_present'] ) { + return; + } + + $document = Plugin::elementor()->documents->get( $wc_page['page_id'] ); + + if ( ! $document || ! $document->is_built_with_elementor() ) { + return; + } + + $elementor_data = get_post_meta( $wc_page['page_id'], '_elementor_data', true ); + $widget_name = static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS[ $wc_page['page_name'] ]; + $widget_exists_in_page = false !== strpos( $elementor_data, $widget_name ); + + if ( $widget_exists_in_page ) { + $response->data['pages'][ $index ]['shortcode_present'] = true; + } + } + + public function loop_query( $query_args, $widget ) { + if ( ! $this->is_product_query( $widget ) ) { + return $query_args; + } + + return $this->parse_loop_query_args( $widget, $query_args ); + } + + private function is_product_query( $widget ) { + $widget_config = $widget->get_config(); + + return ( ! empty( $widget_config['is_loop'] ) && 'product' === $widget->get_current_skin_id() ); + } + + private function parse_loop_query_args( $widget, $query_args ) { + global $wp_query; + + $settings = $this->adjust_setting_for_product_renderer( $widget ); + + // For Products_Renderer. + if ( ! isset( $GLOBALS['post'] ) ) { + $GLOBALS['post'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + } + + $shortcode = Products_Widget::get_shortcode_object( $settings ); + + $parsed_query_args = $shortcode->parse_query_args(); + + if ( empty( $wp_query->include_field_ids_arg ) ) { + unset( $parsed_query_args['fields'] ); + } + + $override_various_query_args = array_filter( $query_args, function( $key ) { + return in_array( $key, [ 'posts_per_page', 'offset', 'paged' ], true ); + }, ARRAY_FILTER_USE_KEY ); + + return wp_parse_args( $override_various_query_args, $parsed_query_args ); + } + + private function adjust_setting_for_product_renderer( $widget ) { + $settings = $widget->get_settings_for_display(); + + $query_name = $widget->get_query_name(); + + $unique_query_settings = array_filter( $settings, function( $key ) use ( $query_name ) { + return 0 === strpos( $key, $query_name ); + }, ARRAY_FILTER_USE_KEY ); + + $query_settings = []; + + foreach ( $unique_query_settings as $key => $value ) { + $query_settings[ 'query' . str_replace( $query_name, '', $key ) ] = $value; + } + + $settings = array_merge( $settings, $query_settings ); + + if ( isset( $settings['posts_per_page'] ) && isset( $settings['columns'] ) ) { + $settings['rows'] = ceil( $settings['posts_per_page'] / $settings['columns'] ); + } + + $settings['paginate'] = 'yes'; + $settings['allow_order'] = 'no'; + $settings['show_result_count'] = 'no'; + $settings['query_fields'] = false; + + return $settings; + } + + /** + * @param $post_id + * @return bool + */ + private function is_source_set_to_products( $post_id ) { + return 'product' === get_post_meta( $post_id, '_elementor_source', true ); + } + + /** + * @param array $config + * @return array + */ + private function add_woocommerce_widgets_to_recommended( array $config ) { + foreach ( static::RECOMMENDED_POSTS_WIDGET_NAMES as $recommended_posts_widget_name ) { + $config['panel']['widgets_settings'][ $recommended_posts_widget_name ] = [ + 'categories' => [ 'recommended' ], + 'show_in_panel' => true, + ]; + } + return $config; + } + + private function hide_woocommerce_widgets_in_loop_document( array $config ) { + $config['panel']['widgets_settings']['woocommerce-product-images'] = [ + 'show_in_panel' => false, + ]; + return $config; + } + + private function populate_persistent_settings( array $config ) { + $config['persistent_keys'] = array_key_exists( 'persistent_keys', $config ) ? + array_merge( $config['persistent_keys'], self::WC_PERSISTENT_SITE_SETTINGS ) : + self::WC_PERSISTENT_SITE_SETTINGS; + + return $config; + } + + /** + * Get the base URL for assets. + * + * @return string + */ + public function get_assets_base_url(): string { + return ELEMENTOR_PRO_URL; + } + + /** + * Register styles. + * + * At build time, Elementor compiles `/modules/woocommerce/assets/scss/widgets/*.scss` + * to `/assets/css/widget-*.min.css`. + * + * @return void + */ + public function register_styles(): void { + $direction_suffix = is_rtl() ? '-rtl' : ''; + $widget_styles = $this->get_widgets_style_list(); + $has_custom_breakpoints = Plugin::elementor()->breakpoints->has_custom_breakpoints(); + + foreach ( $widget_styles as $widget_style_name => $widget_has_responsive_style ) { + $should_load_responsive_css = $widget_has_responsive_style ? $has_custom_breakpoints : false; + + wp_register_style( + $widget_style_name, + Plugin::get_frontend_file_url( "{$widget_style_name}{$direction_suffix}.min.css", $should_load_responsive_css ), + [ 'elementor-frontend' ], + $should_load_responsive_css ? null : ELEMENTOR_PRO_VERSION + ); + } + } + + private function get_widgets_style_list(): array { + return [ + 'widget-woocommerce-cart' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-categories' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-checkout-page' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-menu-cart' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-my-account' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-notices' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-add-to-cart' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-additional-information' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-data-tabs' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-images' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-meta' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-price' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-product-rating' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-products' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-products-archive' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + 'widget-woocommerce-purchase-summary' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, + ]; + } +} diff --git a/modules/woocommerce/settings/settings-woocommerce.php b/modules/woocommerce/settings/settings-woocommerce.php new file mode 100644 index 00000000..1f9b90d0 --- /dev/null +++ b/modules/woocommerce/settings/settings-woocommerce.php @@ -0,0 +1,898 @@ +start_controls_section( + 'section_woocommerce_pages', + [ + 'label' => esc_html__( 'WooCommerce Pages', 'elementor-pro' ), + 'tab' => $this->get_id(), + ] + ); + + if ( API::is_licence_has_feature( Woocommerce::SITE_SETTINGS_PAGES_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->register_woocommerce_pages_controls(); + } else { + $this->register_woocommerce_pages_promotion(); + } + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_woocommerce_notices', + [ + 'label' => esc_html__( 'Notices', 'elementor-pro' ), + 'tab' => $this->get_id(), + ] + ); + + if ( API::is_licence_has_feature( Woocommerce::SITE_SETTINGS_NOTICES_LICENSE_FEATURE_NAME, API::BC_VALIDATION_CALLBACK ) ) { + $this->register_woocommerce_notices_controls(); + } else { + $this->register_woocommerce_notices_promotion(); + } + + $this->end_controls_section(); + + $this->start_controls_section( + 'woocommerce_error_notices', + [ + 'label' => esc_html__( 'Error Notices', 'elementor-pro' ), + 'tab' => $this->get_id(), + 'condition' => [ + 'woocommerce_notices_elements' => 'wc_error', + ], + ] + ); + + $this->add_notice_text_controls( 'error', $this->get_notice_text_selectors( 'error' ) ); + + $this->add_control( + 'error_message_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Link Text', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'error_message_link_typography', + 'selector' => $this->get_main_selector( 'error', 'body', ' a.wc-backward' ), + ] + ); + + $this->start_controls_tabs( 'error_message_links' ); + + $this->start_controls_tab( 'error_message_normal_links', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'error_message_normal_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + $this->get_main_selector( 'error' ) => '--error-message-normal-links-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'error_message_hover_links', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'error_message_hover_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + $this->get_main_selector( 'error' ) => '--error-message-hover-links-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_notice_box_controls( 'error', $this->get_notice_box_selectors( 'error' ) ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'woocommerce_message_notices', + [ + 'label' => esc_html__( 'Message Notices', 'elementor-pro' ), + 'tab' => $this->get_id(), + 'condition' => [ + 'woocommerce_notices_elements' => 'wc_message', + ], + ] + ); + + $this->add_notice_text_controls( 'message', $this->get_notice_text_selectors( 'message' ) ); + + $this->add_control( + 'notice_message_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Link Text', 'elementor-pro' ), + ] + ); + + $message_link_typography_selector = $this->get_main_selector( 'message', 'body', ' .restore-item' ); + $message_link_typography_selector .= ', '; + $message_link_typography_selector .= $this->get_main_selector( 'message', 'body', ' a:not([class])' ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'notice_message_link_typography', + 'selector' => $message_link_typography_selector, + ] + ); + + $this->start_controls_tabs( 'notice_message_links' ); + + $this->start_controls_tab( 'notice_message_normal_links', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $message_normal_link_color_selector = $this->get_main_selector( 'message', '', ' .restore-item' ); + $message_normal_link_color_selector .= ', '; + $message_normal_link_color_selector .= $this->get_main_selector( 'message', '', ' a:not([class])' ); + + $this->add_control( + 'notice_message_normal_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + $message_normal_link_color_selector => '--notice-message-normal-links-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'notice_message_hover_links', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $message_hover_link_color_selector = $this->get_main_selector( 'message', '', ' .restore-item:hover' ); + $message_hover_link_color_selector .= ', '; + $message_hover_link_color_selector .= $this->get_main_selector( 'message', '', ' a:not([class]):hover' ); + + $this->add_control( + 'notice_message_hover_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + $message_hover_link_color_selector => '--notice-message-hover-links-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_notice_box_controls( 'message', $this->get_notice_box_selectors( 'message' ) ); + + $this->add_notice_button_controls( 'message', $this->get_notice_button_selectors( 'message' ) ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'woocommerce_info_notices', + [ + 'label' => esc_html__( 'Info Notices', 'elementor-pro' ), + 'tab' => $this->get_id(), + 'condition' => [ + 'woocommerce_notices_elements' => 'wc_info', + ], + ] + ); + + $this->add_notice_text_controls( 'info', $this->get_notice_text_selectors( 'info' ) ); + + $this->add_notice_box_controls( 'info', $this->get_notice_box_selectors( 'info' ) ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_notice_button_controls( 'info', $this->get_notice_button_selectors( 'info' ) ); + + $this->end_controls_section(); + } + + private function get_main_selector( $notice_type, $selector_prefix = '', $selector_suffix = '' ) { + $notice_name = 'message' === $notice_type ? 'success' : $notice_type; + $old_notice_selector = $selector_prefix . '.e-wc-' . $notice_type . '-notice .woocommerce-' . $notice_type . $selector_suffix; + $block_notice_selector = $selector_prefix . '.e-wc-' . $notice_type . '-notice .wc-block-components-notice-banner.is-' . $notice_name . $selector_suffix; + + return $old_notice_selector . ', ' . $block_notice_selector; + } + + private function get_notice_text_selectors( $notice_type ) { + return [ + $notice_type . '_message_text_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-message-text-color: {{VALUE}};', + ], + $notice_type . '_message_text_typography' => $this->get_main_selector( $notice_type ), + $notice_type . '_message_text_shadow' => $this->get_main_selector( $notice_type ), + $notice_type . '_message_icon_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-message-icon-color: {{VALUE}};', + ], + $notice_type . '_message_icon_size' => [ + $this->get_main_selector( $notice_type, '', ':before' ) => 'font-size: {{SIZE}}{{UNIT}};', + ], + $notice_type . '_message_icon_spacing' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-message-icon-spacing: {{SIZE}}{{UNIT}};', + ], + ]; + } + + private function get_notice_box_selectors( $notice_type ) { + return [ + $notice_type . '_notice_box_background' => $this->get_main_selector( $notice_type, 'body' ), + $notice_type . '_notice_box_box_shadow' => $this->get_main_selector( $notice_type ), + $notice_type . '_notice_box_border' => $this->get_main_selector( $notice_type, 'body' ), + $notice_type . '_notice_box_border_radius' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-box-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + $notice_type . '_notice_box_padding' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-box-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ]; + } + + private function get_notice_button_selectors( $notice_type ) { + $button_hover_background_selector = $this->get_main_selector( $notice_type, 'body', ' .button:hover' ); + + if ( 'info' === $notice_type ) { + // Override styling from the My Account widget. + $button_hover_background_selector .= ', body.e-wc-info-notice .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-info .woocommerce-Button:hover'; + $button_hover_background_selector .= ', body.e-wc-info-notice .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .wc-block-components-notice-banner.is-info .woocommerce-Button:hover'; + } + + return [ + $notice_type . '_button_typography' => $this->get_main_selector( $notice_type, 'body', ' .button' ), + $notice_type . '_button_text_shadow' => $this->get_main_selector( $notice_type, 'body', ' .button' ), + $notice_type . '_buttons_normal_text_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-normal-text-color: {{VALUE}};', + ], + $notice_type . '_buttons_normal_background' => $this->get_main_selector( $notice_type, 'body', ' .button' ), + $notice_type . '_buttons_normal_box_shadow' => $this->get_main_selector( $notice_type, '', ' .button' ), + $notice_type . '_buttons_hover_text_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-hover-text-color: {{VALUE}};', + ], + $notice_type . '_buttons_hover_background' => $button_hover_background_selector, + $notice_type . '_buttons_focus_box_shadow' => $this->get_main_selector( $notice_type, '', ' .button:hover' ), + $notice_type . '_buttons_hover_border_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-hover-border-color: {{VALUE}};', + ], + $notice_type . '_buttons_hover_transition_duration' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-hover-transition-duration: {{SIZE}}ms;', + ], + $notice_type . '_buttons_border_type' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-border-type: {{VALUE}};', + ], + $notice_type . '_buttons_border_width' => [ + $this->get_main_selector( $notice_type, 'body', ' .button' ) => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + $notice_type . '_buttons_border_color' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-border-color: {{VALUE}};', + ], + $notice_type . '_buttons_border_radius' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + $notice_type . '_buttons_padding' => [ + $this->get_main_selector( $notice_type ) => '--' . $notice_type . '-buttons-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ]; + } + + private function add_notice_text_controls( $notice_type, $selectors ) { + $this->add_control( + $notice_type . '_message_text_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Notice Text', 'elementor-pro' ), + ] + ); + + $this->add_control( + $notice_type . '_message_text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_message_text_color' ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => $notice_type . '_message_text_typography', + 'selector' => $selectors[ $notice_type . '_message_text_typography' ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => $notice_type . '_message_text_shadow', + 'selector' => $selectors[ $notice_type . '_message_text_shadow' ], + ] + ); + + $this->add_control( + $notice_type . '_message_icon_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + ] + ); + + $this->add_control( + $notice_type . '_message_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_message_icon_color' ], + ] + ); + } + + private function add_notice_box_controls( $notice_type, $selectors ) { + $this->add_control( + $notice_type . '_notice_box_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Notice Box', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => $notice_type . '_notice_box_background', + 'selector' => $selectors[ $notice_type . '_notice_box_background' ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => $notice_type . '_notice_box_box_shadow', + 'selector' => $selectors[ $notice_type . '_notice_box_box_shadow' ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => $notice_type . '_notice_box_border', + 'selector' => $selectors[ $notice_type . '_notice_box_border' ], + ] + ); + + $this->add_responsive_control( + $notice_type . '_notice_box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => $selectors[ $notice_type . '_notice_box_border_radius' ], + ] + ); + } + + private function add_notice_button_controls( $notice_type, $selectors ) { + $this->add_control( + $notice_type . '_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Button', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => $notice_type . '_button_typography', + 'selector' => $selectors[ $notice_type . '_button_typography' ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => $notice_type . '_button_text_shadow', + 'selector' => $selectors[ $notice_type . '_button_text_shadow' ], + ] + ); + + $this->start_controls_tabs( $notice_type . '_buttons_styles' ); + + $this->start_controls_tab( $notice_type . '_buttons_normal_styles', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + $notice_type . '_buttons_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_buttons_normal_text_color' ], + ] + ); + + $button_background_selectors = [ + 'image' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-image: url("{{URL}}") !important;', + ], + ], + 'color' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-color: {{VALUE}} !important; background-image: none !important', + ], + ], + 'gradient_angle' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-color: transparent !important; background-image: linear-gradient({{SIZE}}{{UNIT}}, {{color.VALUE}} {{color_stop.SIZE}}{{color_stop.UNIT}}, {{color_b.VALUE}} {{color_b_stop.SIZE}}{{color_b_stop.UNIT}}) !important', + ], + ], + 'gradient_position' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-color: transparent !important; background-image: radial-gradient(at {{VALUE}}, {{color.VALUE}} {{color_stop.SIZE}}{{color_stop.UNIT}}, {{color_b.VALUE}} {{color_b_stop.SIZE}}{{color_b_stop.UNIT}}) !important', + ], + ], + 'position' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-position: {{VALUE}} !important;', + ], + ], + 'xpos' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-position: {{SIZE}}{{UNIT}} {{ypos.SIZE}}{{ypos.UNIT}} !important', + ], + ], + 'ypos' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-position: {{xpos.SIZE}}{{xpos.UNIT}} {{SIZE}}{{UNIT}} !important', + ], + ], + 'repeat' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-repeat: {{VALUE}} !important;', + ], + ], + 'size' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-size: {{VALUE}} !important;', + ], + ], + 'bg_width' => [ + 'selectors' => [ + '{{SELECTOR}}' => 'background-size: {{SIZE}}{{UNIT}} auto !important', + ], + ], + ]; + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => $notice_type . '_buttons_normal_background', + 'selector' => $selectors[ $notice_type . '_buttons_normal_background' ], + 'fields_options' => $button_background_selectors, + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => $notice_type . '_buttons_normal_box_shadow', + 'selector' => $selectors[ $notice_type . '_buttons_normal_box_shadow' ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( $notice_type . '_buttons_hover_styles', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + $notice_type . '_buttons_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_buttons_hover_text_color' ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => $notice_type . '_buttons_hover_background', + 'selector' => $selectors[ $notice_type . '_buttons_hover_background' ], + 'fields_options' => $button_background_selectors, + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => $notice_type . '_buttons_focus_box_shadow', + 'selector' => $selectors[ $notice_type . '_buttons_focus_box_shadow' ], + ] + ); + + $this->add_control( + $notice_type . '_buttons_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_buttons_hover_border_color' ], + 'condition' => [ + $notice_type . '_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + $notice_type . '_buttons_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => $selectors[ $notice_type . '_buttons_hover_transition_duration' ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + $notice_type . '_buttons_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => $selectors[ $notice_type . '_buttons_border_type' ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + $notice_type . '_buttons_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => $selectors[ $notice_type . '_buttons_border_width' ], + 'condition' => [ + $notice_type . '_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + $notice_type . '_buttons_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => $selectors[ $notice_type . '_buttons_border_color' ], + 'condition' => [ + $notice_type . '_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + $notice_type . '_buttons_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => $selectors[ $notice_type . '_buttons_border_radius' ], + ] + ); + + $this->add_responsive_control( + $notice_type . '_buttons_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => $selectors[ $notice_type . '_buttons_padding' ], + ] + ); + } + + public function on_save( $data ) { + if ( + ! isset( $data['settings']['post_status'] ) || + Document::STATUS_PUBLISH !== $data['settings']['post_status'] || + // Should check for the current action to avoid infinite loop + // when updating options like: "blogname" and "blogdescription". + strpos( current_action(), 'update_option_' ) === 0 + ) { + return; + } + + $ec_wc_key_mapping = [ + 'woocommerce_cart_page_id' => 'woocommerce_cart_page_id', + 'woocommerce_checkout_page_id' => 'woocommerce_checkout_page_id', + 'woocommerce_myaccount_page_id' => 'woocommerce_myaccount_page_id', + 'woocommerce_terms_page_id' => 'woocommerce_terms_page_id', + 'woocommerce_purchase_summary_page_id' => 'elementor_woocommerce_purchase_summary_page_id', + 'woocommerce_shop_page_id' => 'woocommerce_shop_page_id', + ]; + foreach ( $ec_wc_key_mapping as $ec_key => $wc_key ) { + if ( array_key_exists( $ec_key, $data['settings'] ) ) { + $value = $data['settings'][ $ec_key ] ? $data['settings'][ $ec_key ] : ''; + update_option( $wc_key, $value ); + } + } + } + + private function register_woocommerce_pages_controls() { + $this->add_control( + 'woocommerce_pages_intro', + [ + 'raw' => esc_html__( 'Select the pages you want to use as your default WooCommerce shop pages', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $autocomplete = [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => [ 'page' ], + ], + ]; + + $this->add_control( + 'woocommerce_cart_page_id', + [ + 'label' => esc_html__( 'Cart', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'woocommerce_cart_page_id' ), + ] + ); + + $this->add_control( + 'woocommerce_checkout_page_id', + [ + 'label' => esc_html__( 'Checkout', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'woocommerce_checkout_page_id' ), + ] + ); + + $this->add_control( + 'woocommerce_myaccount_page_id', + [ + 'label' => esc_html__( 'My Account', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'woocommerce_myaccount_page_id' ), + ] + ); + + $this->add_control( + 'woocommerce_terms_page_id', + [ + 'label' => esc_html__( 'Terms & Conditions', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'woocommerce_terms_page_id' ), + ] + ); + + $this->add_control( + 'woocommerce_purchase_summary_page_id', + [ + 'label' => esc_html__( 'Purchase Summary', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'elementor_woocommerce_purchase_summary_page_id' ), // This is not in WC core. This is a custom page added by Elementor. + ] + ); + + $this->add_control( + 'woocommerce_shop_page_id', + [ + 'label' => esc_html__( 'Shop', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'select2options' => [ + 'placeholder' => esc_html__( 'Select a page', 'elementor-pro' ), + ], + 'autocomplete' => $autocomplete, + 'default' => get_option( 'woocommerce_shop_page_id' ), + ] + ); + + $this->add_control( + 'woocommerce_pages_notice', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Note: Changes you make here will also be reflected in the WooCommerce settings on your WP dashboard', 'elementor-pro' ), + ] + ); + } + + private function register_woocommerce_notices_controls() { + $this->add_control( + 'woocommerce_notices_intro', + [ + 'raw' => esc_html__( 'Here\'s where you can customize how notices form WooCommerce will appear for your customers', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->add_control( + 'woocommerce_notices_elements', + [ + 'label' => esc_html__( 'Notice Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'wc_error' => esc_html__( 'Error Notices', 'elementor-pro' ), + 'wc_message' => esc_html__( 'Message Notices', 'elementor-pro' ), + 'wc_info' => esc_html__( 'Info Notices', 'elementor-pro' ), + ], + 'render_type' => 'ui', + 'label_block' => true, + 'frontend_available' => true, + 'default' => [], + ] + ); + } + + /** + * @return array + */ + public function get_notices_promotion_data() { + return [ + 'title' => sprintf( + esc_html__( 'Say hello to %s WooCommerce notices!', 'elementor-pro' ), + '
        ' + ), + 'messages' => [ + esc_html__( 'Upgrade your subscription to customize these and much more.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-site-settings-woocommerce-notices/', + ]; + } + + /** + * @return array + */ + private function get_pages_promotion_data(): array { + return [ + 'title' => sprintf( + esc_html__( 'Say hello to %s WooCommerce pages!', 'elementor-pro' ), + '
        ' + ), + 'messages' => [ + esc_html__( 'Upgrade your subscription to customize these and much more.', 'elementor-pro' ), + ], + 'link' => 'https://go.elementor.com/go-pro-advanced-site-settings-woocommerce-pages/', + ]; + } + + /** + * @return void + */ + private function register_woocommerce_pages_promotion(): void { + $this->add_control( + 'woocommerce_pages_promotion', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Tiers::get_promotion_template( $this->get_pages_promotion_data() ), + ] + ); + } + + /** + * @return void + */ + private function register_woocommerce_notices_promotion(): void { + $this->add_control( + 'woocommerce_notices_promotion', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Tiers::get_promotion_template( $this->get_notices_promotion_data() ), + ] + ); + } +} diff --git a/modules/woocommerce/skins/skin-classic.php b/modules/woocommerce/skins/skin-classic.php new file mode 100644 index 00000000..a537d22b --- /dev/null +++ b/modules/woocommerce/skins/skin-classic.php @@ -0,0 +1,89 @@ +parent = $widget; + + $this->add_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '1' => esc_html__( '1', 'elementor-pro' ), + '2' => esc_html__( '2', 'elementor-pro' ), + '3' => esc_html__( '3', 'elementor-pro' ), + '4' => esc_html__( '4', 'elementor-pro' ), + '5' => esc_html__( '5', 'elementor-pro' ), + '6' => esc_html__( '6', 'elementor-pro' ), + ], + 'default' => '4', + ] + ); + } + + public function render() { + $this->parent->query_posts(); + + /** @var \WP_Query $query */ + $query = $this->parent->get_query(); + + if ( ! $query->have_posts() ) { + return; + } + + global $woocommerce_loop; + + $woocommerce_loop['columns'] = (int) $this->get_instance_value( 'columns' ); + + Module::instance()->add_products_post_class_filter(); + + echo '
        '; + + woocommerce_product_loop_start(); + + while ( $query->have_posts() ) { + $query->the_post(); + + wc_get_template_part( 'content', 'product' ); + } + + woocommerce_product_loop_end(); + + woocommerce_reset_loop(); + + wp_reset_postdata(); + + echo '
        '; + + Module::instance()->remove_products_post_class_filter(); + } +} diff --git a/modules/woocommerce/skins/skin-loop-product-taxonomy.php b/modules/woocommerce/skins/skin-loop-product-taxonomy.php new file mode 100644 index 00000000..041d009f --- /dev/null +++ b/modules/woocommerce/skins/skin-loop-product-taxonomy.php @@ -0,0 +1,31 @@ +parent->add_render_attribute( '_wrapper', 'class', 'woocommerce' ); + parent::render(); + } + + protected function get_default_source_option() { + return Taxonomy_Loop_Provider::PRODUCT_CATEGORY_TAXONOMY; + } +} diff --git a/modules/woocommerce/skins/skin-loop-product.php b/modules/woocommerce/skins/skin-loop-product.php new file mode 100644 index 00000000..c0d00662 --- /dev/null +++ b/modules/woocommerce/skins/skin-loop-product.php @@ -0,0 +1,66 @@ +parent->add_render_attribute( '_wrapper', 'class', 'woocommerce' ); + + global $wp_query; + $wp_query->is_loop_product = true; + + parent::render(); + + $wp_query->is_loop_product = null; + } + + /** + * Register Query Controls + * + * Registers the controls for the query used by the Loop. + * + * @since 3.8.0 + */ + public function register_query_controls( Loop_Widget_Base $widget ) { + $this->parent = $widget; + + $this->add_query_controls( Loop_Module::QUERY_ID ); + } + + protected function render_post() { + global $product; + + if ( ! $product instanceof \WC_Product ) { + $product = wc_get_product( get_the_ID() ); + } + + parent::render_post(); + } +} diff --git a/modules/woocommerce/tags/base-data-tag.php b/modules/woocommerce/tags/base-data-tag.php new file mode 100644 index 00000000..69c02c70 --- /dev/null +++ b/modules/woocommerce/tags/base-data-tag.php @@ -0,0 +1,29 @@ +get_category_ids(); + if ( ! empty( $category_ids ) ) { + $category_id = $category_ids[0]; + } + } + } elseif ( Taxonomy_Loop_Provider::is_loop_taxonomy() ) { + $category_id = $this->get_data_id_from_taxonomy_loop_query(); + } + + if ( $category_id ) { + $image_id = get_term_meta( $category_id, 'thumbnail_id', true ); + } + + if ( empty( $image_id ) ) { + return []; + } + + $src = wp_get_attachment_image_src( $image_id, 'full' ); + + return [ + 'id' => $image_id, + 'url' => $src[0], + ]; + } +} diff --git a/modules/woocommerce/tags/product-content.php b/modules/woocommerce/tags/product-content.php new file mode 100644 index 00000000..f913daaf --- /dev/null +++ b/modules/woocommerce/tags/product-content.php @@ -0,0 +1,30 @@ +add_product_id_control(); + } + + public function render() { + $product = $this->get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return; + } + + echo wp_kses_post( $product->get_description() ); + } +} diff --git a/modules/woocommerce/tags/product-gallery.php b/modules/woocommerce/tags/product-gallery.php new file mode 100644 index 00000000..e3dfdda1 --- /dev/null +++ b/modules/woocommerce/tags/product-gallery.php @@ -0,0 +1,46 @@ +get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return []; + } + + $value = []; + + $attachment_ids = $product->get_gallery_image_ids(); + + foreach ( $attachment_ids as $attachment_id ) { + $value[] = [ + 'id' => $attachment_id, + ]; + } + + return $value; + } +} diff --git a/modules/woocommerce/tags/product-image.php b/modules/woocommerce/tags/product-image.php new file mode 100644 index 00000000..27a1d697 --- /dev/null +++ b/modules/woocommerce/tags/product-image.php @@ -0,0 +1,57 @@ +add_product_id_control(); + } + + public function get_group() { + return Module::WOOCOMMERCE_GROUP; + } + + public function get_categories() { + return [ \Elementor\Modules\DynamicTags\Module::IMAGE_CATEGORY ]; + } + + public function get_value( array $options = [] ) { + $product = $this->get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return []; + } + + $image_id = $product->get_image_id(); + + if ( ! $image_id ) { + return []; + } + + $src = wp_get_attachment_image_src( $image_id, 'full' ); + + return [ + 'id' => $image_id, + 'url' => $src[0], + ]; + } +} diff --git a/modules/woocommerce/tags/product-price.php b/modules/woocommerce/tags/product-price.php new file mode 100644 index 00000000..95e6208b --- /dev/null +++ b/modules/woocommerce/tags/product-price.php @@ -0,0 +1,60 @@ +add_control( 'format', [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'both' => esc_html__( 'Both', 'elementor-pro' ), + 'original' => esc_html__( 'Original', 'elementor-pro' ), + 'sale' => esc_html__( 'Sale', 'elementor-pro' ), + ], + 'default' => 'both', + ] ); + + $this->add_product_id_control(); + } + + public function render() { + $settings = $this->get_settings(); + + $product = $this->get_product( $settings['product_id'] ); + + if ( ! $product ) { + return ''; + } + + $format = $settings['format']; + $value = ''; + switch ( $format ) { + case 'both': + $value = $product->get_price_html(); + break; + case 'original': + $value = wc_price( $product->get_regular_price() ) . $product->get_price_suffix(); + break; + case 'sale' && $product->is_on_sale(): + $value = wc_price( $product->get_sale_price() ) . $product->get_price_suffix(); + break; + } + + // PHPCS - Just passing WC price as is + echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/woocommerce/tags/product-rating.php b/modules/woocommerce/tags/product-rating.php new file mode 100644 index 00000000..53f0c3e8 --- /dev/null +++ b/modules/woocommerce/tags/product-rating.php @@ -0,0 +1,60 @@ +add_control( 'field', [ + 'label' => esc_html__( 'Format', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'average_rating' => esc_html__( 'Average Rating', 'elementor-pro' ), + 'rating_count' => esc_html__( 'Rating Count', 'elementor-pro' ), + 'review_count' => esc_html__( 'Review Count', 'elementor-pro' ), + ], + 'default' => 'average_rating', + ] ); + + $this->add_product_id_control(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + $product = $this->get_product( $settings['product_id'] ); + + if ( ! $product ) { + return ''; + } + + $field = $settings['field']; + $value = ''; + switch ( $field ) { + case 'average_rating': + $value = $product->get_average_rating(); + break; + case 'rating_count': + $value = $product->get_rating_count(); + break; + case 'review_count': + $value = $product->get_review_count(); + break; + } + + // PHPCS - Safe WC data + echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} diff --git a/modules/woocommerce/tags/product-sale.php b/modules/woocommerce/tags/product-sale.php new file mode 100644 index 00000000..4dc4214b --- /dev/null +++ b/modules/woocommerce/tags/product-sale.php @@ -0,0 +1,46 @@ +add_control( 'text', [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Sale!', 'elementor-pro' ), + ] ); + + $this->add_product_id_control(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + $product = $this->get_product( $settings['product_id'] ); + + if ( ! $product ) { + return; + } + + $value = ''; + + if ( $product->is_on_sale() ) { + $value = $settings['text']; + } + + echo wp_kses_post( $value ); + } +} diff --git a/modules/woocommerce/tags/product-short-description.php b/modules/woocommerce/tags/product-short-description.php new file mode 100644 index 00000000..69192105 --- /dev/null +++ b/modules/woocommerce/tags/product-short-description.php @@ -0,0 +1,30 @@ +add_product_id_control(); + } + + public function render() { + $product = $this->get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return; + } + + echo wp_kses_post( $product->get_short_description() ); + } +} diff --git a/modules/woocommerce/tags/product-sku.php b/modules/woocommerce/tags/product-sku.php new file mode 100644 index 00000000..7ce50c0a --- /dev/null +++ b/modules/woocommerce/tags/product-sku.php @@ -0,0 +1,36 @@ +add_product_id_control(); + } + + public function render() { + $product = $this->get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return; + } + + $value = ''; + + if ( $product->get_sku() ) { + $value = $product->get_sku(); + } + + echo esc_html( $value ); + } +} diff --git a/modules/woocommerce/tags/product-stock.php b/modules/woocommerce/tags/product-stock.php new file mode 100644 index 00000000..b8fc4cd0 --- /dev/null +++ b/modules/woocommerce/tags/product-stock.php @@ -0,0 +1,52 @@ +get_settings_for_display(); + + $product = $this->get_product( $settings['product_id'] ); + + if ( ! $product ) { + return; + } + + if ( 'yes' === $settings['show_text'] ) { + $value = wc_get_stock_html( $product ); + } else { + $value = (int) $product->get_stock_quantity(); + } + + // PHPCS - `wc_get_stock_html` is safe, and `get_stock_quantity` protected with (int). + echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + protected function register_controls() { + $this->add_control( + 'show_text', + [ + 'label' => esc_html__( 'Show Text', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + ] + ); + + $this->add_product_id_control(); + } +} diff --git a/modules/woocommerce/tags/product-terms.php b/modules/woocommerce/tags/product-terms.php new file mode 100644 index 00000000..b546b82c --- /dev/null +++ b/modules/woocommerce/tags/product-terms.php @@ -0,0 +1,79 @@ +update_control( + 'before', + [ + 'default' => esc_html__( 'Categories', 'elementor-pro' ) . ': ', + ] + ); + } + + protected function register_controls() { + $taxonomy_filter_args = [ + 'show_in_nav_menus' => true, + 'object_type' => [ 'product' ], + ]; + + $taxonomies = get_taxonomies( $taxonomy_filter_args, 'objects' ); + + $options = []; + + foreach ( $taxonomies as $taxonomy => $object ) { + $options[ $taxonomy ] = $object->label; + } + + $this->add_control( + 'taxonomy', + [ + 'label' => esc_html__( 'Taxonomy', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $options, + 'default' => 'product_cat', + ] + ); + + $this->add_control( + 'separator', + [ + 'label' => esc_html__( 'Separator', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => ', ', + ] + ); + + $this->add_product_id_control(); + } + + public function render() { + $settings = $this->get_settings_for_display(); + + $product = $this->get_product( $settings['product_id'] ); + + if ( ! $product ) { + return; + } + + $value = get_the_term_list( $product->get_id(), $settings['taxonomy'], '', $settings['separator'] ); + + echo wp_kses_post( $value ); + } +} diff --git a/modules/woocommerce/tags/product-title.php b/modules/woocommerce/tags/product-title.php new file mode 100644 index 00000000..cf39ed42 --- /dev/null +++ b/modules/woocommerce/tags/product-title.php @@ -0,0 +1,36 @@ +add_product_id_control(); + } + + public function render() { + $product = $this->get_product( $this->get_settings( 'product_id' ) ); + + if ( ! $product ) { + return; + } + + if ( 'variation' === $product->get_type() ) { + $title = $product->get_name(); + } else { + $title = get_the_title( $product->get_id() ); + } + + echo wp_kses_post( $title ); + } +} diff --git a/modules/woocommerce/tags/traits/tag-product-id.php b/modules/woocommerce/tags/traits/tag-product-id.php new file mode 100644 index 00000000..d1fc38a9 --- /dev/null +++ b/modules/woocommerce/tags/traits/tag-product-id.php @@ -0,0 +1,28 @@ +add_control( + 'product_id', + [ + 'label' => esc_html__( 'Product', 'elementor-pro' ), + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => [ 'product' ], + ], + ], + // Since we're using the `wc_get_product` method to retrieve products, when no product selected manually + // by the dynamic tag - the default should be `false` so the method will use the product id given in the + // http request instead. + 'default' => false, + ] + ); + } +} diff --git a/modules/woocommerce/tags/woocommerce-add-to-cart.php b/modules/woocommerce/tags/woocommerce-add-to-cart.php new file mode 100644 index 00000000..d78cac98 --- /dev/null +++ b/modules/woocommerce/tags/woocommerce-add-to-cart.php @@ -0,0 +1,93 @@ +add_control( + 'product_id', + [ + 'label' => esc_html__( 'Product', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => [ 'product' ], + 'tax_query' => [ + [ + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => 'simple', + ], + ], + ], + ], + ] + ); + + $this->add_control( + 'quantity', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'ai' => [ + 'active' => false, + ], + 'default' => 1, + ] + ); + } + + public function get_value( array $options = [] ) { + $settings = $this->get_settings_for_display(); + + if ( ! $settings['product_id'] ) { + global $product; + + $product = wc_get_product(); + + if ( empty( $product ) ) { + return; + } + + $product_id = $product->get_id(); + } else { + $product_id = absint( $settings['product_id'] ); + } + + $quantity = absint( $settings['quantity'] ); + + $url = 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) + ? wc_get_cart_url() + : get_permalink( $product_id ); + + return home_url() . '?add-to-cart=' . $product_id . '&quantity=' . $quantity . '&e-redirect=' . $url; + } +} diff --git a/modules/woocommerce/traits/product-id-trait.php b/modules/woocommerce/traits/product-id-trait.php new file mode 100644 index 00000000..a27e8591 --- /dev/null +++ b/modules/woocommerce/traits/product-id-trait.php @@ -0,0 +1,43 @@ +product_already_queried( $product ) ) { + return $product; + } + + if ( 'product_variation' === get_post_type() ) { + return $this->get_product_variation(); + } + + $product_data = wc_get_product( $product_id ); + + if ( ! $product_data ) { + $product_data = wc_get_product(); + } + + return $product_data; + } + + private function product_already_queried( $product ): bool { + global $wp_query; + + if ( empty( $wp_query->is_loop_product ) ) { + return false; + } + + return $product instanceof \WC_Product; + } + + public function get_product_variation() { + return wc_get_product( get_the_ID() ); + } +} diff --git a/modules/woocommerce/traits/products-trait.php b/modules/woocommerce/traits/products-trait.php new file mode 100644 index 00000000..42852511 --- /dev/null +++ b/modules/woocommerce/traits/products-trait.php @@ -0,0 +1,202 @@ + [ + 'default' => 'product', + 'options' => [ + 'current_query' => esc_html__( 'Current Query', 'elementor-pro' ), + 'product' => esc_html__( 'Latest Products', 'elementor-pro' ), + 'sale' => esc_html__( 'Sale', 'elementor-pro' ), + 'featured' => esc_html__( 'Featured', 'elementor-pro' ), + 'by_id' => _x( 'Manual Selection', 'Posts Query Control', 'elementor-pro' ), + 'related_products' => esc_html__( 'Related Products', 'elementor-pro' ), + 'upsells' => esc_html__( 'Upsells', 'elementor-pro' ), + 'cross_sells' => esc_html__( 'Cross-Sells', 'elementor-pro' ), + ], + ], + 'orderby' => [ + 'default' => 'date', + 'options' => [ + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'price' => esc_html__( 'Price', 'elementor-pro' ), + 'popularity' => esc_html__( 'Popularity', 'elementor-pro' ), + 'rating' => esc_html__( 'Rating', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + ], + ], + 'exclude' => [ + 'options' => [ + 'current_post' => esc_html__( 'Current Post', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + 'terms' => esc_html__( 'Term', 'elementor-pro' ), + ], + ], + 'include' => [ + 'options' => [ + 'terms' => esc_html__( 'Term', 'elementor-pro' ), + ], + ], + ]; + } + + private function init_query_settings( $name ) { + $this->product_query_group_control_name = $name; + $this->product_query_control_args = $this->get_query_control_args(); + $this->product_query_post_type_control_id = $this->get_query_post_type_control_id(); + } + + /** + * @return array + */ + private function get_query_control_args() { + $args = [ + 'name' => $this->product_query_group_control_name, + 'post_type' => 'product', + 'presets' => [ 'include', 'exclude', 'order' ], + 'fields_options' => $this->get_query_fields_options(), + 'exclude' => [ + 'posts_per_page', + 'exclude_authors', + 'authors', + 'offset', + 'related_fallback', + 'related_ids', + 'query_id', + 'avoid_duplicates', + 'ignore_sticky_posts', + ], + ]; + + $args['fields_options'] = array_merge( $args['fields_options'], $this->get_query_exclude_conditions() ); + + return $args; + } + + private function get_query_exclude_conditions() { + $fields = []; + foreach ( $this->product_query_controls_to_hide as $control_name ) { + $fields = $this->add_query_not_supported_types( $control_name, $fields ); + } + + return $fields; + } + + private function add_query_not_supported_types( $control_name, $fields ) { + foreach ( $this->product_query_types as $query_type ) { + $fields[ $control_name ]['condition']['post_type!'][] = $query_type; + } + + return $fields; + } + + /** + * @return string + */ + private function get_query_post_type_control_id() { + $control_id = $this->product_query_control_args['name'] . '_post_type'; + + // Check if the trait is currently being used by a widget or skin. Group controls add + // the post_type as a prefix when added by a skin. + if ( method_exists( $this, 'get_control_id' ) ) { + $control_id = $this->product_query_control_args['post_type'] . '_' . $control_id; + } + + return $control_id; + } + + private function add_query_controls( $name ) { + $this->init_query_settings( $name ); + + $this->add_group_control( + Group_Control_Query::get_type(), + $this->product_query_control_args + ); + + $this->add_control( + 'related_products_note', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Note: The Related Products Query is available when creating a Single Product template', 'elementor-pro' ), + 'condition' => [ + $this->product_query_post_type_control_id => 'related_products', + ], + ] + ); + + $this->add_control( + 'upsells_products_note', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Note: The Upsells Query is available when creating a Single Product template', 'elementor-pro' ), + 'condition' => [ + $this->product_query_post_type_control_id => 'upsells', + ], + ] + ); + + $this->add_control( + 'cross_sells_products_note', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Note: The Cross-Sells Query is available when creating a Cart page', 'elementor-pro' ), + 'condition' => [ + $this->product_query_post_type_control_id => 'cross_sells', + ], + ] + ); + } +} diff --git a/modules/woocommerce/traits/send-app-plg-trait.php b/modules/woocommerce/traits/send-app-plg-trait.php new file mode 100644 index 00000000..5674698b --- /dev/null +++ b/modules/woocommerce/traits/send-app-plg-trait.php @@ -0,0 +1,43 @@ +add_control( + 'send_app_promo', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => Hints::get_notice_template( [ + 'display' => ! Hints::is_dismissed( $notice_id ), + 'type' => 'info', + 'content' => $notice_content, + 'icon' => true, + 'dismissible' => $notice_id, + 'button_text' => __( 'Install Plugin', 'elementor-pro' ), + 'button_event' => $notice_id, + 'button_data' => [ + 'action_url' => Hints::get_plugin_action_url( 'send-app' ), + ], + ], true ), + ] + ); + } +} diff --git a/modules/woocommerce/wc-templates/cart/mini-cart.php b/modules/woocommerce/wc-templates/cart/mini-cart.php new file mode 100644 index 00000000..652c6559 --- /dev/null +++ b/modules/woocommerce/wc-templates/cart/mini-cart.php @@ -0,0 +1,101 @@ +exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ); + + if ( ! $is_product_visible ) { + return; + } + + $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key ); + $product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); + $product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key ); + ?> +
        + +
        + get_image(), $cart_item, $cart_item_key ); + + if ( ! $product_permalink ) : + echo wp_kses_post( $thumbnail ); + else : + printf( '%s', esc_url( $product_permalink ), wp_kses_post( $thumbnail ) ); + endif; + ?> +
        + +
        + get_name(), $cart_item, $cart_item_key ) . ' ' ); + else : + echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key ) ); + endif; + + do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key ); + + // Meta data. + echo wc_get_formatted_cart_item_data( $cart_item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ?> +
        + +
        + ' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '', $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
        + +
        + ', + esc_url( wc_get_cart_remove_url( $cart_item_key ) ), + $class, + __( 'Remove this item', 'elementor-pro' ), + esc_attr( $product_id ), + esc_attr( $cart_item_key ), + esc_attr( $_product->get_sku() ) + ), $cart_item_key ); + } ?> +
        +
        + cart->get_cart(); + +if ( empty( $cart_items ) ) { ?> +
        + +
        + $cart_item ) { + elementor_pro_render_mini_cart_item( $cart_item_key, $cart_item ); + } + + do_action( 'woocommerce_mini_cart_contents' ); + ?> +
        + +
        + : + cart->get_cart_subtotal(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
        + + diff --git a/modules/woocommerce/widgets/add-to-cart.php b/modules/woocommerce/widgets/add-to-cart.php new file mode 100644 index 00000000..6e15c172 --- /dev/null +++ b/modules/woocommerce/widgets/add-to-cart.php @@ -0,0 +1,335 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-add-to-cart' ]; + } + + public function on_export( $element ) { + unset( $element['settings']['product_id'] ); + + return $element; + } + + public function unescape_html( $safe_text, $text ) { + return $text; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_product', + [ + 'label' => esc_html__( 'Product', 'elementor-pro' ), + ] + ); + + $this->maybe_add_send_app_promotion_control( $this ); + + $this->add_control( + 'product_id', + [ + 'label' => esc_html__( 'Product', 'elementor-pro' ), + 'type' => Module::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => Module::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => [ 'product' ], + ], + ], + ] + ); + + $this->add_control( + 'show_quantity', + [ + 'label' => esc_html__( 'Show Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'description' => esc_html__( 'Please note that switching on this option will disable some of the design controls.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'quantity', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 1, + 'condition' => [ + 'show_quantity' => '', + ], + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Inline', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + 'auto' => esc_html__( 'Auto', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-add-to-cart--layout-', + 'render_type' => 'template', + ] + ); + + $this->end_controls_section(); + + $this->update_control( + 'link', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => [ + 'url' => '', + ], + ] + ); + + $this->update_control( + 'text', + [ + 'default' => esc_html__( 'Add to Cart', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Add to Cart', 'elementor-pro' ), + ] + ); + + $this->update_responsive_control( + 'align', + [ + 'prefix_class' => 'elementor-add-to-cart%s--align-', + ] + ); + + $this->update_control( + 'selected_icon', + [ + 'default' => [ + 'value' => 'fas fa-shopping-cart', + 'library' => 'fa-solid', + ], + ] + ); + + $this->update_control( + 'size', + [ + 'condition' => [ + 'show_quantity' => '', + ], + ] + ); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + if ( ! empty( $settings['product_id'] ) ) { + $product_id = $settings['product_id']; + } elseif ( wp_doing_ajax() && ! empty( $settings['product_id'] ) ) { + // PHPCS - No nonce is required. + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $product_id = (int) Utils::_unstable_get_super_global_value( $_POST, 'post_id' ); + } else { + $product_id = get_queried_object_id(); + } + + global $product; + $product = $this->get_product( $product_id ); + + $settings = $this->get_settings_for_display(); + + if ( in_array( $settings['layout'], [ 'auto', 'stacked' ], true ) ) { + add_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 ); + add_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 ); + } + + if ( 'yes' === $settings['show_quantity'] ) { + $this->render_form_button( $product ); + } else { + $this->render_ajax_button( $product ); + } + + if ( in_array( $settings['layout'], [ 'auto', 'stacked' ], true ) ) { + remove_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 ); + remove_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 ); + } + } + + /** + * Before Add to Cart Quantity + * + * Added wrapper tag around the quantity input and "Add to Cart" button + * used to more solidly accommodate the layout when additional elements + * are added by 3rd party plugins. + * + * @since 3.6.0 + */ + public function before_add_to_cart_quantity() { + ?> +
        + +
        + get_settings_for_display(); + + if ( $product ) { + if ( version_compare( WC()->version, '3.0.0', '>=' ) ) { + $product_type = $product->get_type(); + } else { + $product_type = $product->product_type; + } + + $class = implode( ' ', array_filter( [ + 'product_type_' . $product_type, + $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '', + $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '', + ] ) ); + + $this->add_render_attribute( 'button', + [ + 'rel' => 'nofollow', + 'href' => $product->add_to_cart_url(), + 'data-quantity' => ( isset( $settings['quantity'] ) ? $settings['quantity'] : 1 ), + 'data-product_id' => $product->get_id(), + 'class' => $class, + ] + ); + + } elseif ( current_user_can( 'manage_options' ) ) { + $settings['text'] = esc_html__( 'Please set a valid product', 'elementor-pro' ); + $this->set_settings( $settings ); + } + + parent::render(); + } + + private function render_form_button( $product ) { + if ( ! $product && current_user_can( 'manage_options' ) ) { + echo esc_html__( 'Please set a valid product', 'elementor-pro' ); + + return; + } + + $text_callback = function() { + ob_start(); + $this->render_text(); + + return ob_get_clean(); + }; + + add_filter( 'woocommerce_get_stock_html', '__return_empty_string' ); + add_filter( 'woocommerce_product_single_add_to_cart_text', $text_callback ); + add_filter( 'esc_html', [ $this, 'unescape_html' ], 10, 2 ); + + ob_start(); + woocommerce_template_single_add_to_cart(); + $form = ob_get_clean(); + $form = str_replace( 'single_add_to_cart_button', 'single_add_to_cart_button elementor-button', $form ); + + // PHPCS - The HTML from 'woocommerce_template_single_add_to_cart' is safe. + echo $form; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + remove_filter( 'woocommerce_product_single_add_to_cart_text', $text_callback ); + remove_filter( 'woocommerce_get_stock_html', '__return_empty_string' ); + remove_filter( 'esc_html', [ $this, 'unescape_html' ] ); + } + + /** + * Written as a Backbone JavaScript template and used to generate the live preview. + * + * @since 2.9.0 + * @access protected + */ + // Force remote render + protected function content_template() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/archive-description.php b/modules/woocommerce/widgets/archive-description.php new file mode 100644 index 00000000..22ea7cef --- /dev/null +++ b/modules/woocommerce/widgets/archive-description.php @@ -0,0 +1,119 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_description_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'text_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .term-description' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '.woocommerce {{WRAPPER}} .term-description', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + do_action( 'woocommerce_archive_description' ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/archive-products-deprecated.php b/modules/woocommerce/widgets/archive-products-deprecated.php new file mode 100644 index 00000000..6763011c --- /dev/null +++ b/modules/woocommerce/widgets/archive-products-deprecated.php @@ -0,0 +1,166 @@ +deprecated_notice( Plugin::get_title(), '2.5.0', '', esc_html__( 'Archive Products', 'elementor-pro' ) ); + + parent::register_controls(); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'columns', + ] ); + + $this->add_control( + 'wc_notice_do_not_use_customizer', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Note that these layout settings will override settings made in Appearance > Customize', 'elementor-pro' ), + ] + ); + + $this->end_injection(); + + $this->update_control( + 'rows', + [ + 'default' => 4, + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'paginate', + [ + 'default' => 'yes', + ] + ); + + $this->update_control( + 'section_query', + [ + 'type' => 'hidden', + ] + ); + + $this->update_control( + 'query_post_type', + [ + 'default' => 'current_query', + ] + ); + + $this->start_controls_section( + 'section_advanced', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'It seems we can’t find what you’re looking for.', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_nothing_found_style', + [ + 'tab' => Controls_Manager::TAB_STYLE, + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'condition' => [ + 'nothing_found_message!' => '', + ], + ] + ); + + $this->add_control( + 'nothing_found_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-products-nothing-found' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'nothing_found_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-products-nothing-found', + ] + ); + + $this->end_controls_section(); + } + + public function render_no_results() { + echo '
        ' . esc_html( $this->get_settings( 'nothing_found_message' ) ) . '
        '; + } + + protected function render() { + add_action( 'woocommerce_shortcode_products_loop_no_results', [ $this, 'render_no_results' ] ); + + parent::render(); + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/archive-products.php b/modules/woocommerce/widgets/archive-products.php new file mode 100644 index 00000000..512e9a77 --- /dev/null +++ b/modules/woocommerce/widgets/archive-products.php @@ -0,0 +1,204 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-products', 'widget-woocommerce-products-archive' ]; + } + + protected function register_controls() { + parent::register_controls(); + + $this->remove_responsive_control( 'columns' ); + $this->remove_responsive_control( 'rows' ); + $this->remove_control( 'orderby' ); + $this->remove_control( 'order' ); + + $this->update_control( + 'products_class', + [ + 'prefix_class' => 'elementor-products-grid elementor-', + ] + ); + + // Should be kept as hidden since required for "allow_order" + $this->update_control( + 'paginate', + [ + 'type' => 'hidden', + 'default' => 'yes', + ] + ); + + $this->update_control( + 'allow_order', + [ + 'default' => 'yes', + ] + ); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'allow_order', + ] ); + + if ( ! get_theme_support( 'woocommerce' ) ) { + $this->add_control( + 'wc_notice_wc_not_supported', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'warning', + 'content' => esc_html__( 'Looks like you are using WooCommerce, while your theme does not support it. Please consider switching themes.', 'elementor-pro' ), + ] + ); + } + + $this->add_control( + 'wc_notice_use_customizer', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'To change the Products Archive’s layout, go to Appearance > Customize.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'wc_notice_wrong_data', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The editor preview might look different from the live site. Please make sure to check the frontend.', 'elementor-pro' ), + ] + ); + + $this->end_injection(); + + $this->update_control( + 'show_result_count', + [ + 'default' => 'yes', + ] + ); + + $this->update_control( + 'section_query', + [ + 'type' => 'hidden', + ] + ); + + $this->update_control( + Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + [ + 'default' => 'current_query', + ] + ); + + $this->start_controls_section( + 'section_advanced', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'nothing_found_message', + [ + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXTAREA, + 'default' => esc_html__( 'It seems we can’t find what you’re looking for.', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_nothing_found_style', + [ + 'tab' => Controls_Manager::TAB_STYLE, + 'label' => esc_html__( 'Nothing Found Message', 'elementor-pro' ), + 'condition' => [ + 'nothing_found_message!' => '', + ], + ] + ); + + $this->add_control( + 'nothing_found_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-products-nothing-found' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'nothing_found_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .elementor-products-nothing-found', + ] + ); + + $this->end_controls_section(); + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/base-widget.php b/modules/woocommerce/widgets/base-widget.php new file mode 100644 index 00000000..10be6b85 --- /dev/null +++ b/modules/woocommerce/widgets/base-widget.php @@ -0,0 +1,153 @@ + $breakpoint_config ) { + $devices_required[ $breakpoint_name ] = [ + 'required' => false, + ]; + } + + return $devices_required; + } + + protected function add_columns_responsive_control() { + $this->add_responsive_control( + 'columns', + [ + 'label' => esc_html__( 'Columns', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'prefix_class' => 'elementor-grid%s-', + 'min' => 1, + 'max' => 12, + 'default' => Products_Renderer::DEFAULT_COLUMNS_AND_ROWS, + 'tablet_default' => '3', + 'mobile_default' => '2', + 'required' => true, + 'device_args' => $this->get_devices_default_args(), + 'min_affected_device' => [ + Controls_Stack::RESPONSIVE_DESKTOP => Controls_Stack::RESPONSIVE_TABLET, + Controls_Stack::RESPONSIVE_TABLET => Controls_Stack::RESPONSIVE_TABLET, + ], + ] + ); + } + + /** + * Is WooCommerce Feature Active. + * + * Checks whether a specific WooCommerce feature is active. These checks can sometimes look at multiple WooCommerce + * settings at once so this simplifies and centralizes the checking. + * + * @since 3.5.0 + * + * @param string $feature + * @return bool + */ + protected function is_wc_feature_active( $feature ) { + switch ( $feature ) { + case 'checkout_login_reminder': + return 'yes' === get_option( 'woocommerce_enable_checkout_login_reminder' ); + case 'shipping': + if ( class_exists( 'WC_Shipping_Zones' ) ) { + $all_zones = \WC_Shipping_Zones::get_zones(); + if ( count( $all_zones ) > 0 ) { + return true; + } + } + break; + case 'coupons': + return function_exists( 'wc_coupons_enabled' ) && wc_coupons_enabled(); + case 'signup_and_login_from_checkout': + return 'yes' === get_option( 'woocommerce_enable_signup_and_login_from_checkout' ); + case 'ship_to_billing_address_only': + return wc_ship_to_billing_address_only(); + } + + return false; + } + + /** + * Get Custom Border Type Options + * + * Return a set of border options to be used in different WooCommerce widgets. + * + * This will be used in cases where the Group Border Control could not be used. + * + * @since 3.5.0 + * + * @return array + */ + public static function get_custom_border_type_options() { + return [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ]; + } + + /** + * Init Gettext Modifications + * + * Should be overridden by a method in the Widget class. + * + * @since 3.5.0 + */ + protected function init_gettext_modifications() { + $this->gettext_modifications = []; + } + + /** + * Filter Gettext. + * + * Filter runs when text is output to the page using the translation functions (`_e()`, `__()`, etc.) + * used to apply text changes from the widget settings. + * + * This allows us to make text changes without having to ovveride WooCommerce templates, which would + * lead to dev tax to keep all the templates up to date with each future WC release. + * + * @since 3.5.0 + * + * @param string $translation + * @param string $text + * @param string $domain + * @return string + */ + public function filter_gettext( $translation, $text, $domain ) { + if ( 'woocommerce' !== $domain && 'pro-elements' !== $domain ) { + return $translation; + } + + if ( ! isset( $this->gettext_modifications ) ) { + $this->init_gettext_modifications(); + } + + return array_key_exists( $text, $this->gettext_modifications ) ? $this->gettext_modifications[ $text ] : $translation; + } +} diff --git a/modules/woocommerce/widgets/breadcrumb.php b/modules/woocommerce/widgets/breadcrumb.php new file mode 100644 index 00000000..4d3427f4 --- /dev/null +++ b/modules/woocommerce/widgets/breadcrumb.php @@ -0,0 +1,124 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_rating_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-breadcrumb' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'link_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-breadcrumb > a' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '{{WRAPPER}} .woocommerce-breadcrumb', + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-breadcrumb' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + woocommerce_breadcrumb(); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/cart.php b/modules/woocommerce/widgets/cart.php new file mode 100644 index 00000000..ffa0a4ab --- /dev/null +++ b/modules/woocommerce/widgets/cart.php @@ -0,0 +1,2665 @@ +start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'General', 'elementor-pro' ), + ] + ); + + $this->maybe_add_send_app_promotion_control( $this ); + + $this->add_control( + 'cart_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'two-column' => esc_html__( 'Two columns', 'elementor-pro' ), + 'one-column' => esc_html__( 'One column', 'elementor-pro' ), + ], + 'default' => 'two-column', + 'prefix_class' => 'e-cart-layout-', + ] + ); + + $this->add_control( + 'sticky_right_column', + [ + 'label' => esc_html__( 'Sticky Right Column', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'description' => esc_html__( 'This option will allow the right column (e.g, Cart Totals) to be sticky while scrolling.', 'elementor-pro' ), + 'frontend_available' => true, + 'render_type' => 'none', + 'condition' => [ + 'cart_layout!' => 'one-column', + ], + ] + ); + + $this->add_control( + 'sticky_right_column_offset', + [ + 'label' => esc_html__( 'Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'frontend_available' => true, + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'sticky_right_column', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'cart_layout', + 'operator' => '!==', + 'value' => 'one-column', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_order_summary', + [ + 'label' => esc_html__( 'Order Summary', 'elementor-pro' ), + 'condition' => [ + 'update_cart_automatically' => '', + ], + ] + ); + + $this->add_control( + 'update_cart_button_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Update Cart Button', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'update_cart_button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Update Cart', 'elementor-pro' ), + 'default' => esc_html__( 'Update Cart', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'update_cart_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-cart-form' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--update-cart-button-alignment: start; --update-cart-button-width: auto;', + 'center' => '--update-cart-button-alignment: center; --update-cart-button-width: auto;', + 'end' => '--update-cart-button-alignment: end; --update-cart-button-width: auto;', + 'justify' => '--update-cart-button-alignment: justify; --update-cart-button-width: 100%;', + ], + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'coupons' ) ) { + + $this->start_controls_section( + 'section_coupon', + [ + 'label' => esc_html__( 'Coupon', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'section_coupon_display', + [ + 'label' => esc_html__( 'Coupon', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'apply_coupon_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Apply Coupon Button', 'elementor-pro' ), + 'condition' => [ + 'section_coupon_display' => 'yes', + ], + ] + ); + + $this->add_control( + 'apply_coupon_button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Apply coupon', 'elementor-pro' ), + 'default' => esc_html__( 'Apply coupon', 'elementor-pro' ), + 'condition' => [ + 'section_coupon_display' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'apply_coupon_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .coupon' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--apply-coupon-button-alignment: start; --apply-coupon-button-width: auto;', + 'center' => '--apply-coupon-button-alignment: center; --apply-coupon-button-width: auto;', + 'end' => '--apply-coupon-button-alignment: end; --apply-coupon-button-width: auto;', + 'justify' => '--apply-coupon-button-alignment: center; --apply-coupon-button-width: 100%;', + ], + 'condition' => [ + 'section_coupon_display' => 'yes', + ], + ] + ); + + $this->add_control( + 'coupon_button_alignment_note', + [ + 'raw' => esc_html__( 'Note: This control will only affect screen sizes Tablet and below', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'section_coupon_display' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + $this->start_controls_section( + 'section_totals', + [ + 'label' => esc_html__( 'Totals', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'totals_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Cart Totals', 'elementor-pro' ), + 'default' => esc_html__( 'Cart Totals', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'totals_section_title_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--totals-title-alignment: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'update_shipping_button_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Update Shipping Button', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'update_shipping_button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Update', 'elementor-pro' ), + 'default' => esc_html__( 'Update', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'update_shipping_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .shipping-calculator-form' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--update-shipping-button-alignment: start; --update-shipping-button-width: auto;', + 'center' => '--update-shipping-button-alignment: center; --update-shipping-button-width: auto;', + 'end' => '--update-shipping-button-alignment: end; --update-shipping-button-width: auto;', + 'justify' => '--update-shipping-button-alignment: center; --update-shipping-button-width: 100%;', + ], + ] + ); + + $this->add_control( + 'checkout_button_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkout Button', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'checkout_button_text', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'placeholder' => esc_html__( 'Proceed to Checkout', 'elementor-pro' ), + 'default' => esc_html__( 'Proceed to Checkout', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'checkout_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .wc-proceed-to-checkout' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'start' => '--place-order-title-alignment: flex-start; --checkout-button-width: fit-content;', + 'center' => '--place-order-title-alignment: center; --checkout-button-width: fit-content;', + 'end' => '--place-order-title-alignment: flex-end; --checkout-button-width: fit-content;', + 'justify' => '--place-order-title-alignment: stretch; --checkout-button-width: 100%;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'update_cart_automatically', + [ + 'label' => esc_html__( 'Update Cart Automatically', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}};', + ], + 'selectors_dictionary' => [ + 'yes' => '--update-cart-automatically-display: none;', + ], + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'update_cart_automatically_description', + [ + 'raw' => esc_html__( 'Changes to the cart will update automatically.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->add_control( + 'additional_template_switch', + [ + 'label' => esc_html__( 'Customize empty cart', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'active', + 'default' => '', + 'render_type' => 'template', + 'prefix_class' => 'e-cart-empty-template-', + ] + ); + + $this->add_control( + 'additional_template_description', + [ + 'raw' => sprintf( + /* translators: 1: Saved templates link opening tag, 2: Link closing tag. */ + esc_html__( 'Replaces the default WooCommerce Empty Cart screen with a custom template. (Don’t have one? Head over to %1$sSaved Templates%2$s)', 'elementor-pro' ), + sprintf( '', admin_url( 'edit.php?post_type=elementor_library&tabs_group=library#add_new' ) ), + '' + ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor elementor-descriptor-subtle', + 'condition' => [ + 'additional_template_switch' => 'active', + ], + ] + ); + + $this->add_control( + 'additional_template_select_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Choose template', 'elementor-pro' ), + 'condition' => [ + 'additional_template_switch' => 'active', + ], + ] + ); + + $document_types = Plugin::elementor()->documents->get_document_types( [ + 'show_in_library' => true, + ] ); + + $this->add_control( + 'additional_template_select', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'show_label' => false, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => array_keys( $document_types ), + 'compare' => 'IN', + ], + ], + ], + ], + 'frontend_available' => true, + 'condition' => [ + 'additional_template_switch' => 'active', + ], + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'edit_button', + [ + 'raw' => sprintf( ' %s', esc_html__( 'Edit Template', 'elementor-pro' ) ), + 'type' => \Elementor\Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-edit-template-wrapper', + 'condition' => [ + 'additional_template_switch' => 'active', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_style', + [ + 'label' => esc_html__( 'Sections', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'sections_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-cart-section', + ] + ); + + $this->add_control( + 'sections_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'sections_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-cart-section' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'sections_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-margin: {{BOTTOM}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_typography', + [ + 'label' => esc_html__( 'Typography', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'sections_typography', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'sections_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_titles_typography', + 'selector' => '{{WRAPPER}} .cart_totals h2', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'sections_titles_text_shadow', + 'selector' => '{{WRAPPER}} .cart_totals h2', + ] + ); + + $this->add_responsive_control( + 'sections_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sections_descriptions_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Descriptions', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'sections_descriptions_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--sections-descriptions-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_descriptions_typography', + 'selector' => '{{WRAPPER}} .e-cart-content, {{WRAPPER}} .woocommerce-shipping-destination, {{WRAPPER}} .shipping-calculator-button', + ] + ); + + $this->add_responsive_control( + 'sections_descriptions_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-descriptions-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sections_links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Links', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'links_colors' ); + + $this->start_controls_tab( 'links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'links_normal_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'links_hover_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'sections_radio_buttons_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Radio Buttons', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_radio_buttons_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-radio-buttons-color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_radio_buttons_typography', + 'selector' => '{{WRAPPER}} #shipping_method li label', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_forms', + [ + 'label' => esc_html__( 'Forms', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'forms_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-rows-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'forms_field_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Field', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_field_typography', + 'selector' => '{{WRAPPER}} .coupon .input-text, {{WRAPPER}} .cart-collaterals .input-text, {{WRAPPER}} select, {{WRAPPER}} .select2-selection--single', + ] + ); + + $this->start_controls_tabs( 'forms_fields_styles' ); + + $this->start_controls_tab( 'forms_fields_normal_styles', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_fields_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-normal-color: {{VALUE}};', + '.e-woo-select2-wrapper .select2-results__option' => 'color: {{VALUE}};', + // style select2 arrow + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow b' => 'border-color: {{VALUE}} transparent transparent transparent;', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_normal_background', + 'selector' => '{{WRAPPER}} .coupon .input-text, {{WRAPPER}} .e-cart-totals .input-text, {{WRAPPER}} select, {{WRAPPER}} .select2-selection--single', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_normal_box_shadow', + 'selector' => '{{WRAPPER}} .coupon .input-text, {{WRAPPER}} .e-cart-totals .input-text, {{WRAPPER}} select, {{WRAPPER}} .select2-selection--single', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_fields_focus_styles', [ 'label' => esc_html__( 'Focus', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_fields_focus_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-color: {{VALUE}}', + '.e-woo-select2-wrapper .select2-results__option:focus' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_focus_background', + 'selector' => '{{WRAPPER}} .coupon .input-text:focus, {{WRAPPER}} .e-cart-totals .input-text:focus, {{WRAPPER}} select:focus, {{WRAPPER}} .select2-selection--single:focus', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_focus_box_shadow', + 'selector' => '{{WRAPPER}} .coupon .input-text:focus, {{WRAPPER}} .e-cart-totals .input-text:focus, {{WRAPPER}} select:focus, {{WRAPPER}} .select2-selection--single:focus', + ] + ); + + $this->add_control( + 'forms_fields_focus_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_fields_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'forms_fields_focus_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'forms_fields_border', + 'selector' => '{{WRAPPER}} .coupon .input-text, {{WRAPPER}} .cart-collaterals .input-text, {{WRAPPER}} select, {{WRAPPER}} .select2-selection--single', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_fields_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_fields_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} ' => '--forms-fields-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + // style select2 + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__rendered' => 'line-height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow' => 'height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .select2-container--default .select2-selection--single' => 'height: auto;', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'forms_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_button_typography', + 'selector' => '{{WRAPPER}} .shop_table .button', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'forms_button_text_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button', + ] + ); + + $this->start_controls_tabs( 'forms_buttons_styles' ); + + $this->start_controls_tab( 'forms_buttons_normal_styles', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_buttons_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_normal_background', + 'selector' => '{{WRAPPER}} .shop_table .button', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_normal_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_buttons_hover_styles', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_buttons_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_hover_background', + 'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .shop_table .button:disabled[disabled]:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_focus_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button:hover', + ] + ); + + $this->add_control( + 'forms_buttons_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'forms_buttons_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_buttons_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .shop_table .button' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'forms_buttons_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-color: {{VALUE}};', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'forms_buttons_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_buttons_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --forms-buttons-width: auto;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'tabs_order_summary', + [ + 'label' => esc_html__( 'Order Summary', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'order_summary_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-rows-gap-top: calc( {{SIZE}}{{UNIT}}/2 ); --order-summary-rows-gap-bottom: calc( {{SIZE}}{{UNIT}}/2 );', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'order_summary_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-cart-form' => '--order-summary-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_title_typography', + 'selector' => '{{WRAPPER}} .e-shop-table .cart th, {{WRAPPER}} .e-shop-table .cart td:before', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'order_summary_title_text_shadow', + 'selector' => '{{WRAPPER}} .e-shop-table .cart th, {{WRAPPER}} .e-shop-table .cart td:before', + ] + ); + + $this->add_responsive_control( + 'order_summary_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'order_summary_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_items_typography', + 'selector' => '{{WRAPPER}} .cart td span, {{WRAPPER}} .cart td, {{WRAPPER}} .input-text.qty', + ] + ); + + $this->add_control( + 'order_summary_variations_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_variations_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-variations-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_variations_typography', + 'selector' => '{{WRAPPER}} .product-name .variation', + ] + ); + + $this->add_control( + 'order_summary_product_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Product Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'order_summary' ); + + $this->start_controls_tab( 'order_summary_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'product_link_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--product-link-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'order_summary_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'product_link_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--product-link-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'order_summary_divider_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'order_summary_items_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-items-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_items_divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-items-divider-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'order_summary_quantity_border_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Quantity Borders', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'order_summary_quantity_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-quantity-border-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_quantity_border_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-quantity-border-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'order_summary_remove_icon_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Remove icon', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'order_summary_remove_icon' ); + + $this->start_controls_tab( 'order_summary_remove_icon_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_summary_remove_icon_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-remove-icon-normal-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'order_summary_remove_icon_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_summary_remove_icon_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-remove-icon-hover-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_totals', + [ + 'label' => esc_html__( 'Totals', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'totals_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--totals-rows-gap-top: calc( {{SIZE}}{{UNIT}}/2 ); --totals-rows-gap-bottom: calc( {{SIZE}}{{UNIT}}/2 );', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'totals_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'totals_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--totals-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'totals_typography', + 'selector' => '{{WRAPPER}} .cart_totals .shop_table td:before, {{WRAPPER}} .cart_totals .shop_table td .woocommerce-Price-amount', + ] + ); + + $this->add_control( + 'totals_divider_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Divider Total', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'totals_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--totals-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'totals_divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--totals-divider-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_checkout_button', + [ + 'label' => esc_html__( 'Checkout Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'checkout_button_typography', + 'selector' => '{{WRAPPER}} .checkout-button', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'checkout_button_text_shadow', + 'selector' => '{{WRAPPER}} .checkout-button', + ] + ); + + $this->start_controls_tabs( 'checkout_button_styles' ); + + $this->start_controls_tab( 'checkout_button_normal_styles', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'checkout_button_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'checkout_button_normal_background', + 'selector' => '{{WRAPPER}} .woocommerce .wc-proceed-to-checkout .checkout-button', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'checkout_button_normal_box_shadow', + 'selector' => '{{WRAPPER}} .checkout-button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'checkout_button_hover_styles', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'checkout_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'checkout_button_hover_background', + 'selector' => '{{WRAPPER}} .woocommerce .wc-proceed-to-checkout .checkout-button:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'checkout_button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .checkout-button:hover', + ] + ); + + $this->add_control( + 'checkout_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-hover-border-color: {{VALUE}}', + ], + 'condition' => [ + 'checkout_button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'checkout_button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'checkout_button_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'checkout_button_border', + 'selector' => '{{WRAPPER}} .checkout-button', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'checkout_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'checkout_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --checkout-button-width: fit-content;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_customize', + [ + 'label' => esc_html__( 'Customize', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $customize_options = []; + + $customize_options += [ + 'customize_order_summary' => esc_html__( 'Order Summary', 'elementor-pro' ), + ]; + + if ( $this->is_wc_feature_active( 'coupons' ) ) { + $customize_options += [ + 'customize_coupon' => esc_html__( 'Coupon', 'elementor-pro' ), + ]; + } + + $customize_options += [ + 'customize_totals' => esc_html__( 'Totals', 'elementor-pro' ), + ]; + + $this->add_control( + 'section_cart_show_customize_elements', + [ + 'label' => esc_html__( 'Select sections of the cart to customize:', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => $customize_options, + 'render_type' => 'ui', + 'label_block' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_customize_order_summary', + [ + 'label' => esc_html__( 'Customize: Order Summary', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_cart_show_customize_elements' => 'customize_order_summary', + ], + ] + ); + + $this->add_control( + 'order_summary_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_section_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'order_summary_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-shop-table', + 'separator' => 'after', + ] + ); + + $this->add_control( + 'order_summary_section_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'order_summary_section_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'order_summary_section_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_summary_section_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'order_summary_section_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_section_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_section_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_section_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-shop-table' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_customize_totals', + [ + 'label' => esc_html__( 'Customize: Totals', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_cart_show_customize_elements' => 'customize_totals', + ], + ] + ); + + $this->add_control( + 'customize_totals_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'sections_totals_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'totals_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-cart-totals', + ] + ); + + $this->add_control( + 'totals_section_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'totals_section_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'totals_section_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'totals_section_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'totals_section_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'totals_section_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'checkout_sections_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'totals_section_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'totals_section_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'totals_section_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart_totals' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'totals_section_titles_typography', + 'selector' => '{{WRAPPER}} .cart_totals h2', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'totals_section_titles_text_shadow', + 'selector' => '{{WRAPPER}} .cart_totals h2', + 'separator' => 'after', + ] + ); + + $this->add_control( + 'totals_section_content_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'totals_section_content_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--sections-descriptions-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'totals_section_content_typography', + 'selector' => '{{WRAPPER}} .e-cart-totals .e-cart-content, {{WRAPPER}} .e-cart-totals .woocommerce-shipping-destination, {{WRAPPER}} .e-cart-totals .shipping-calculator-button', + ] + ); + + $this->add_control( + 'totals_section_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'totals_section_links_colors' ); + + $this->start_controls_tab( 'totals_section_links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'totals_section_links_normal_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--links-normal-color: {{VALUE}} !important;', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'totals_section_links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'totals_section_links_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-cart-totals' => '--links-hover-color: {{VALUE}} !important;', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_tabs_customize_coupon', + [ + 'label' => esc_html__( 'Customize: Coupon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_cart_show_customize_elements' => 'customize_coupon', + ], + ] + ); + + $this->add_control( + 'coupon_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_coupon_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'customize_coupon_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .coupon', + ] + ); + + $this->add_control( + 'customize_coupon_section_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'customize_coupon_section_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .coupon' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'customize_coupon_section_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'customize_coupon_section_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'customize_coupon_section_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'customize_coupon_section_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'customize_coupon_section_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'customize_coupon_section_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .coupon' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .e-cart__container' => 'grid-row-gap: {{BOTTOM}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->end_controls_section(); + } + + /** + * Init Gettext Modifications + * + * Sets the `$gettext_modifications` property used with the `filter_gettext()` in the extended Base_Widget. + * + * @since 3.5.0 + */ + protected function init_gettext_modifications() { + $instance = $this->get_settings_for_display(); + + $this->gettext_modifications = [ + 'Update cart' => isset( $instance['update_cart_button_text'] ) ? $instance['update_cart_button_text'] : '', + 'Cart totals' => isset( $instance['totals_section_title'] ) ? $instance['totals_section_title'] : '', + 'Proceed to checkout' => isset( $instance['checkout_button_text'] ) ? $instance['checkout_button_text'] : '', + 'Update' => isset( $instance['update_shipping_button_text'] ) ? $instance['update_shipping_button_text'] : '', + 'Apply coupon' => isset( $instance['apply_coupon_button_text'] ) ? $instance['apply_coupon_button_text'] : '', + ]; + } + + /** + * Check if an Elementor template has been selected to display the empty cart notification + * + * @since 3.7.0 + * @return boolean + */ + protected function has_empty_cart_template() { + $additional_template_select = $this->get_settings_for_display( 'additional_template_select' ); + return ! empty( $additional_template_select ) && 0 < $additional_template_select; + } + + /** + * Render Woocommerce Cart Coupon Form + * + * A custom function to render a coupon form on the Cart widget. The default WC coupon form + * was removed in this file's render() method. + * + * We are doing this in order to match the placement of the coupon form to the provided design. + * + * @since 3.5.0 + */ + private function render_woocommerce_cart_coupon_form() { + $settings = $this->get_settings_for_display(); + $button_classes = [ 'button', 'e-apply-coupon' ]; + if ( $settings['forms_buttons_hover_animation'] ) { + $button_classes[] = 'elementor-animation-' . $settings['forms_buttons_hover_animation']; + } + $this->add_render_attribute( + 'button_coupon', [ + 'class' => $button_classes, + 'name' => 'apply_coupon', + 'type' => 'submit', + ] + ); + ?> +
        +
        +
        + +
        +
        + +
        + +
        +
        + +
        + +
        + + get_settings_for_display(); + $coupon_display_control = true; + + if ( '' === $settings['section_coupon_display'] ) { + $coupon_display_control = false; + } + + return wc_coupons_enabled() && $coupon_display_control; + } + + /** + * Woocommerce Before Cart Table + * + * Output containing elements. Callback function for the woocommerce_before_cart_table hook + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function woocommerce_before_cart_table() { + $section_classes = [ 'e-shop-table', 'e-cart-section' ]; + + if ( ! $this->should_render_coupon() ) { + $section_classes[] = 'e-cart-section--no-coupon'; + } + + $this->add_render_attribute( + 'before_cart_table', [ + 'class' => $section_classes, + ] + ); + ?> +
        print_render_attribute_string( 'before_cart_table' ); ?>> + + +
        + +
        + should_render_coupon() ) { + $this->render_woocommerce_cart_coupon_form(); + } + } + + /** + * Woocommerce Before Cart Collaterals + * + * Output containing elements. * Callback function for the woocommerce_before_cart_collaterals hook + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function woocommerce_before_cart_collaterals() { + ?> + +
        +
        + +
        + +
        + + + +
        + +
        + +
        + +
        + modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.7.0' ); + + $url_components = wp_parse_url( $url ); + + if ( ! isset( $url_components['query'] ) ) { + return $url; + } + + $params = []; + parse_str( html_entity_decode( $url_components['query'] ), $params ); + + $params['_wp_http_referer'] = rawurlencode( Plugin::elementor()->documents->get_current()->get_wp_preview_url() ); + + return add_query_arg( $params, get_site_url() ); + } + + /** + * WooCommerce Get Cart Url + * + * Used with the `woocommerce_get_cart_url`. This sets the url to the current page, so links like the `remove_url` + * are set to the current page, and not the existing WooCommerce cart endpoint. + * + * @since 3.7.0 + * + * @param $url + * @return string + */ + public function woocommerce_get_cart_url( $url ) { + global $post; + + if ( ! $post ) { + return $url; + } + + if ( Module::is_preview() || Plugin::elementor()->editor->is_edit_mode() ) { + return Plugin::elementor()->documents->get_current()->get_wp_preview_url(); + } + + return get_permalink( $post->ID ); + } + + /** + * The following disabling of cart coupon needs to be done this way so that + * we only disable the display of coupon interface in our cart widget and + * `wc_coupons_enabled()` can still be reliably used elsewhere. + */ + public function disable_cart_coupon() { + add_filter( 'woocommerce_coupons_enabled', [ $this, 'cart_coupon_return_false' ], 90 ); + } + public function enable_cart_coupon() { + remove_filter( 'woocommerce_coupons_enabled', [ $this, 'cart_coupon_return_false' ], 90 ); + } + public function cart_coupon_return_false() { + return false; + } + + /** + * Add Render Hooks + * + * Add actions & filters before displaying our widget. + * + * @since 3.7.0 + */ + public function add_render_hooks() { + $is_editor = Plugin::elementor()->editor->is_edit_mode(); + $is_preview = Module::is_preview(); + + /** + * Add actions & filters before displaying our Widget. + */ + add_filter( 'gettext', [ $this, 'filter_gettext' ], 20, 3 ); + + add_action( 'woocommerce_before_cart', [ $this, 'woocommerce_before_cart' ] ); + add_action( 'woocommerce_after_cart_table', [ $this, 'woocommerce_after_cart_table' ] ); + add_action( 'woocommerce_before_cart_table', [ $this, 'woocommerce_before_cart_table' ] ); + add_action( 'woocommerce_before_cart_collaterals', [ $this, 'woocommerce_before_cart_collaterals' ] ); + add_action( 'woocommerce_after_cart', [ $this, 'woocommerce_after_cart' ] ); + // The following disabling of cart coupon needs to be done this way so that + // we only disable the display of coupon interface in our cart widget and + // `wc_coupons_enabled()` can still be reliably used elsewhere. + add_action( 'woocommerce_cart_contents', [ $this, 'disable_cart_coupon' ] ); + add_action( 'woocommerce_after_cart_contents', [ $this, 'enable_cart_coupon' ] ); + add_filter( 'woocommerce_get_cart_url', [ $this, 'woocommerce_get_cart_url' ] ); + + if ( $this->has_empty_cart_template() ) { + remove_action( 'woocommerce_cart_is_empty', 'wc_empty_cart_message', 10 ); + } + + // Remove cross-sells in cart. + remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' ); + } + + /** + * Remove Render Hooks + * + * Remove actions & filters after displaying our widget. + * + * @since 3.7.0 + */ + public function remove_render_hooks() { + remove_filter( 'gettext', [ $this, 'filter_gettext' ], 20 ); + + remove_action( 'woocommerce_before_cart', [ $this, 'woocommerce_before_cart' ] ); + remove_action( 'woocommerce_after_cart_table', [ $this, 'woocommerce_after_cart_table' ] ); + remove_action( 'woocommerce_before_cart_table', [ $this, 'woocommerce_before_cart_table' ] ); + remove_action( 'woocommerce_before_cart_collaterals', [ $this, 'woocommerce_before_cart_collaterals' ] ); + remove_action( 'woocommerce_after_cart', [ $this, 'woocommerce_after_cart' ] ); + remove_filter( 'woocommerce_coupons_enabled', [ $this, 'hide_coupon_field_on_cart' ] ); + remove_filter( 'woocommerce_get_remove_url', [ $this, 'woocommerce_get_remove_url' ] ); + remove_action( 'woocommerce_cart_contents', [ $this, 'disable_cart_coupon' ] ); + remove_action( 'woocommerce_after_cart_contents', [ $this, 'enable_cart_coupon' ] ); + remove_action( 'woocommerce_get_cart_url', [ $this, 'woocommerce_get_cart_url' ] ); + add_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' ); + + if ( $this->has_empty_cart_template() ) { + add_action( 'woocommerce_cart_is_empty', 'wc_empty_cart_message', 10 ); + } + } + + public function render() { + // Add actions & filters before displaying our Widget. + $this->add_render_hooks(); + + // Display our Widget. + if ( $this->has_empty_cart_template() && WC()->cart->get_cart_contents_count() === 0 ) { + $template_id = intval( $this->get_settings_for_display( 'additional_template_select' ) ); + echo do_shortcode( '[elementor-template id="' . $template_id . '"]' ); + } else { + echo do_shortcode( '[woocommerce_cart]' ); + } + + // Remove actions & filters after displaying our Widget. + $this->remove_render_hooks(); + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/categories.php b/modules/woocommerce/widgets/categories.php new file mode 100644 index 00000000..cebd9f46 --- /dev/null +++ b/modules/woocommerce/widgets/categories.php @@ -0,0 +1,426 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_categories() { + return [ + 'woocommerce-elements', + ]; + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-products', 'widget-woocommerce-categories' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_columns_responsive_control(); + + $this->add_control( + 'number', + [ + 'label' => esc_html__( 'Categories Count', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '4', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_filter', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'source', + [ + 'label' => esc_html__( 'Source', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Show All', 'elementor-pro' ), + 'by_id' => esc_html__( 'Manual Selection', 'elementor-pro' ), + 'by_parent' => esc_html__( 'By Parent', 'elementor-pro' ), + 'current_subcategories' => esc_html__( 'Current Subcategories', 'elementor-pro' ), + ], + 'label_block' => true, + ] + ); + + $categories = get_terms( 'product_cat' ); + + $options = []; + foreach ( $categories as $category ) { + $options[ $category->term_id ] = $category->name; + } + + $this->add_control( + 'categories', + [ + 'label' => esc_html__( 'Categories', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $options, + 'default' => [], + 'label_block' => true, + 'multiple' => true, + 'condition' => [ + 'source' => 'by_id', + ], + ] + ); + + $parent_options = [ '0' => esc_html__( 'Only Top Level', 'elementor-pro' ) ] + $options; + $this->add_control( + 'parent', + [ + 'label' => esc_html__( 'Parent', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '0', + 'options' => $parent_options, + 'condition' => [ + 'source' => 'by_parent', + ], + ] + ); + + $this->add_control( + 'hide_empty', + [ + 'label' => esc_html__( 'Hide Empty', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'label_on' => 'Hide', + 'label_off' => 'Show', + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'name', + 'options' => [ + 'name' => esc_html__( 'Name', 'elementor-pro' ), + 'slug' => esc_html__( 'Slug', 'elementor-pro' ), + 'description' => esc_html__( 'Description', 'elementor-pro' ), + 'count' => esc_html__( 'Count', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_products_style', + [ + 'label' => esc_html__( 'Products', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'products_class', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => 'wc-products', + 'prefix_class' => 'elementor-products-grid elementor-', + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 40, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products' => 'grid-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-product-loop-item--align-', + 'selectors' => [ + '{{WRAPPER}} .product' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'image_border', + 'selector' => '{{WRAPPER}} a > img', + ] + ); + + $this->add_responsive_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} a > img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'image_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} a > img' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce .woocommerce-loop-category__title' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .woocommerce .woocommerce-loop-category__title', + ] + ); + + $this->add_control( + 'heading_count_style', + [ + 'label' => esc_html__( 'Count', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'count_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-loop-category__title .count' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'count_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .woocommerce-loop-category__title .count', + ] + ); + + $this->end_controls_section(); + } + + private function get_shortcode() { + $settings = $this->get_settings(); + + $attributes = [ + 'number' => $settings['number'], + 'columns' => $settings['columns'], + 'hide_empty' => ( 'yes' === $settings['hide_empty'] ) ? 1 : 0, + 'orderby' => $settings['orderby'], + 'order' => $settings['order'], + ]; + + if ( 'by_id' === $settings['source'] ) { + $attributes['ids'] = implode( ',', $settings['categories'] ); + } elseif ( 'by_parent' === $settings['source'] ) { + $attributes['parent'] = $settings['parent']; + } elseif ( 'current_subcategories' === $settings['source'] ) { + $attributes['parent'] = get_queried_object_id(); + } + + $this->add_render_attribute( 'shortcode', $attributes ); + + $shortcode = sprintf( '[product_categories %s]', $this->get_render_attribute_string( 'shortcode' ) ); + + return $shortcode; + } + + public function render() { + $product_categories_html = do_shortcode( $this->get_shortcode() ); + + if ( $product_categories_html ) { + $product_categories_html = str_replace( '
          get_shortcode() ); + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/category-image.php b/modules/woocommerce/widgets/category-image.php new file mode 100644 index 00000000..0fb55272 --- /dev/null +++ b/modules/woocommerce/widgets/category-image.php @@ -0,0 +1,63 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'image', + [ + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'woocommerce-category-image-tag' ), + ], + ], + [ + 'recursive' => true, + ] + ); + } + + protected function get_html_wrapper_class() { + return parent::get_html_wrapper_class() . ' elementor-widget-' . parent::get_name(); + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/checkout.php b/modules/woocommerce/widgets/checkout.php new file mode 100644 index 00000000..cdc42b19 --- /dev/null +++ b/modules/woocommerce/widgets/checkout.php @@ -0,0 +1,4340 @@ +start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'General', 'elementor-pro' ), + ] + ); + + $this->maybe_add_send_app_promotion_control( $this ); + + $this->add_control( + 'checkout_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'two-column' => esc_html__( 'Two columns', 'elementor-pro' ), + 'one-column' => esc_html__( 'One column', 'elementor-pro' ), + ], + 'default' => 'two-column', + 'prefix_class' => 'e-checkout-layout-', + ] + ); + + $this->add_control( + 'sticky_right_column', + [ + 'label' => esc_html__( 'Sticky Right Column', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'description' => esc_html__( 'The Order Summary and Payment sections will remain in place while scrolling.', 'elementor-pro' ), + 'frontend_available' => true, + 'render_type' => 'none', + 'condition' => [ + 'checkout_layout' => 'two-column', + ], + ] + ); + + $this->add_control( + 'sticky_right_column_offset', + [ + 'label' => esc_html__( 'Offset', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'frontend_available' => true, + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'sticky_right_column', + 'operator' => '!==', + 'value' => '', + ], + [ + 'name' => 'checkout_layout', + 'operator' => '=', + 'value' => 'two-column', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'checkout_login_reminder' ) ) { + $this->add_checkout_login_reminder_controls(); + } + + $this->start_controls_section( + 'billing_details_section', + [ + 'label' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'billing_details_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ), + 'default' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_responsive_control( + 'billing_details_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--billing-details-title-alignment: {{VALUE}};', + ], + ] + ); + + $repeater = new Repeater(); + + $repeater->start_controls_tabs( 'tabs', [ + 'condition' => [ + 'repeater_state' => '', + ], + ] ); + + $repeater->start_controls_tab( 'content_tab', [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + ] + ); + + $repeater->add_control( + 'placeholder', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( 'advanced_tab', [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'default', + [ + 'label' => esc_html__( 'Default Value', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $repeater->add_control( + 'repeater_state', + [ + 'label' => esc_html__( 'Repeater State - hidden', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + ] + ); + + $repeater->add_control( + 'locale_notice', + [ + 'raw' => __( 'Note: This content cannot be changed due to local regulations.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'repeater_state' => 'locale', + ], + ] + ); + + $repeater->add_control( + 'from_billing_notice', + [ + 'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'repeater_state' => 'from_billing', + ], + ] + ); + + $this->add_control( + 'billing_details_form_fields', + [ + 'label' => esc_html__( 'Form Items', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'item_actions' => [ + 'add' => false, + 'duplicate' => false, + 'remove' => false, + 'sort' => false, + ], + 'default' => $this->get_billing_field_defaults(), + 'title_field' => '{{{ label }}}', + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'shipping' ) && ! $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ) { + $this->add_shipping_controls(); + } + + $this->start_controls_section( + 'additional_information_section', + [ + 'label' => esc_html__( 'Additional Information', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'additional_information_active', + [ + 'label' => esc_html__( 'Additional Information', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '--additional-information-display: block;', + ], + ] + ); + + if ( $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ) { + $this->add_control( + 'additional_information_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'Additional Information', 'elementor-pro' ), + 'default' => esc_html__( 'Additional Information', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'additional_information_active!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'additional_information_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--additional-fields-title-alignment: {{VALUE}};', + ], + 'condition' => [ + 'additional_information_active!' => '', + ], + ] + ); + } + + $repeater = new Repeater(); + + $repeater->start_controls_tabs( 'additional_information_form_fields_tabs' ); + + $repeater->start_controls_tab( 'additional_information_form_fields_content_tab', [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'placeholder', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( 'additional_information_form_fields_advanced_tab', [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'default', + [ + 'label' => esc_html__( 'Default Value', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $this->add_control( + 'additional_information_form_fields', + [ + 'label' => esc_html__( 'Items', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'item_actions' => [ + 'add' => false, + 'duplicate' => false, + 'remove' => false, + 'sort' => false, + ], + 'default' => [ + [ + 'field_key' => 'order_comments', + 'field_label' => esc_html__( 'Order Notes', 'elementor-pro' ), + 'label' => esc_html__( 'Order Notes', 'elementor-pro' ), + 'placeholder' => esc_html__( 'Notes about your order, e.g. special notes for delivery.', 'elementor-pro' ), + ], + ], + 'title_field' => '{{{ label }}}', + 'condition' => [ + 'additional_information_active!' => '', + ], + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'signup_and_login_from_checkout' ) ) { + $this->add_signup_and_login_from_checkout_controls(); + } + + $this->start_controls_section( + 'order_summary_section', + [ + 'label' => esc_html__( 'Your Order', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Your Order', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-review-title-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'coupons' ) ) { + $this->add_coupon_controls(); + } + + $this->start_controls_section( + 'payment_section', + [ + 'label' => esc_html__( 'Payment', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'terms_conditions_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Terms & Conditions', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'terms_conditions_message_text', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'default' => esc_html__( 'I have read and agree to the website', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'terms_conditions_link_text', + [ + 'label' => esc_html__( 'Link Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'default' => esc_html__( 'terms and conditions', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'purchase_buttom_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Purchase Button', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'purchase_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--place-order-title-alignment: flex-start; --purchase-button-width: fit-content;', + 'center' => '--place-order-title-alignment: center; --purchase-button-width: fit-content;', + 'end' => '--place-order-title-alignment: flex-end; --purchase-button-width: fit-content;', + 'justify' => '--place-order-title-alignment: stretch; --purchase-button-width: 100%;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_style', + [ + 'label' => esc_html__( 'Sections', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'sections_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'section_normal_box_shadow', + 'selector' => $this->get_main_woocommerce_sections_selectors(), + ] + ); + + $this->add_control( + 'sections_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'sections_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + $this->get_main_woocommerce_sections_selectors() => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'sections_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + // move the 'Ship to a different address?' checkbox + '{{WRAPPER}} .woocommerce-shipping-fields' => '--shipping-heading-padding-start: {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_typography', + [ + 'label' => esc_html__( 'Typography', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'sections_typography', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'sections_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_titles_typography', + 'selector' => $this->get_main_woocommerce_sections_title_selectors(), + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'sections_titles_text_shadow', + 'selector' => $this->get_main_woocommerce_sections_title_selectors(), + ] + ); + + $this->add_responsive_control( + 'sections_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sections_secondary_typography', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Secondary Titles', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_secondary_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-secondary-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_secondary_titles_typography', + 'selector' => '{{WRAPPER}} .e-checkout-secondary-title', + ] + ); + + $this->add_responsive_control( + 'sections_secondary_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-secondary-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sections_descriptions_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Descriptions', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_descriptions_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-descriptions-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_descriptions_typography', + 'selector' => '{{WRAPPER}} .e-description', + ] + ); + + $this->add_responsive_control( + 'sections_descriptions_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-descriptions-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'sections_messages_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Messages', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_messages_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-messages-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_messages_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_box, {{WRAPPER}} .woocommerce-privacy-policy-text p, {{WRAPPER}} .e-checkout-message', + ] + ); + + $this->add_control( + 'sections_checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkboxes', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_checkboxes_typography', + 'selector' => '{{WRAPPER}} .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->add_control( + 'sections_radio_buttons_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Radio Buttons', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sections_radio_buttons_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-radio-buttons-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sections_radio_buttons_typography', + 'selector' => '{{WRAPPER}} .wc_payment_method label, {{WRAPPER}} #shipping_method li label', + ] + ); + + // Links + $this->add_control( + 'sections_links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Links', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'links_colors' ); + + $this->start_controls_tab( 'links_normal_colors', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'links_normal_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'links_hover_colors', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'links_hover_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_forms', + [ + 'label' => esc_html__( 'Forms', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'forms_columns_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-columns-gap-padding: calc( {{SIZE}}{{UNIT}}/2 ); --forms-columns-gap-margin: calc( -{{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_responsive_control( + 'forms_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-rows-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'forms_label_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Labels', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'forms_label_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-labels-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_label_typography', + 'selector' => '{{WRAPPER}} .woocommerce-billing-fields .form-row label, {{WRAPPER}} .woocommerce-shipping-fields .form-row label, {{WRAPPER}} .woocommerce-additional-fields .form-row label, {{WRAPPER}} .e-woocommerce-login-anchor .form-row label, {{WRAPPER}} .e-coupon-anchor-description', + ] + ); + + $this->add_responsive_control( + 'forms_label_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-label-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'forms_field_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Fields', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_field_typography', + 'selector' => '{{WRAPPER}} #customer_details .input-text, {{WRAPPER}} #customer_details .form-row textarea, {{WRAPPER}} #customer_details .form-row select, {{WRAPPER}} .e-woocommerce-login-anchor .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} ::placeholder, {{WRAPPER}} .select2-container--default .select2-selection--single, .select2-results__option', + ] + ); + + $this->start_controls_tabs( 'forms_fields_styles' ); + + $this->start_controls_tab( 'forms_fields_normal_styles', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'forms_fields_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-normal-color: {{VALUE}};', + '.e-woo-select2-wrapper .select2-results__option' => 'color: {{VALUE}};', + // style select2 arrow + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow b' => 'border-color: {{VALUE}} transparent transparent transparent;', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_normal_background', + 'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text, {{WRAPPER}} .woocommerce #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single, {{WRAPPER}} .woocommerce-checkout #payment .payment_methods .payment_box', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_normal_box_shadow', + 'selector' => '{{WRAPPER}} #customer_details .input-text, {{WRAPPER}} #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .e-woocommerce-login-anchor .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_fields_focus_styles', [ + 'label' => esc_html__( 'Focus', 'elementor-pro' ), + ] ); + + $this->add_control( + 'forms_fields_focus_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-color: {{VALUE}}', + '.e-woo-select2-wrapper .select2-results__option:focus' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_focus_background', + 'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text:focus, {{WRAPPER}} .woocommerce #customer_details .form-row textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_focus_box_shadow', + 'selector' => '{{WRAPPER}} #customer_details .input-text:focus, {{WRAPPER}} #customer_details textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .e-woocommerce-login-anchor .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus', + ] + ); + + $this->add_control( + 'forms_fields_focus_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text:focus, {{WRAPPER}} .woocommerce #customer_details .form-row textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_fields_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'forms_fields_focus_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'forms_fields_border', + 'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text, {{WRAPPER}} .woocommerce #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_fields_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_fields_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + // style select2 + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__rendered' => 'line-height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow' => 'height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .select2-container--default .select2-selection--single' => 'height: auto;', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'forms_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Button', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_button_typography', + 'selector' => '{{WRAPPER}} .woocommerce-button', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'forms_button_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-button', + ] + ); + + $this->start_controls_tabs( 'forms_buttons_styles' ); + + $this->start_controls_tab( 'forms_buttons_normal_styles', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'forms_buttons_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_normal_background', + 'selector' => '{{WRAPPER}} .woocommerce-button', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_normal_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_buttons_hover_styles', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'forms_buttons_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_hover_background', + 'selector' => '{{WRAPPER}} .woocommerce-button:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_focus_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-button:hover', + ] + ); + + $this->add_control( + 'forms_buttons_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-apply-coupon:hover, {{WRAPPER}} .woocommerce-form-login__submit:hover' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'forms_buttons_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_buttons_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-apply-coupon, {{WRAPPER}} .woocommerce-form-login__submit' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'forms_buttons_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--forms-buttons-border-color: {{VALUE}};', + ], + 'condition' => [ + 'forms_buttons_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'forms_buttons_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_buttons_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; width: auto;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_order_summary', + [ + 'label' => esc_html__( 'Order Summary', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'order_summary_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-rows-gap-top: calc( {{SIZE}}{{UNIT}}/2 ); --order-summary-rows-gap-bottom: calc( {{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_control( + 'order_summary_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_items_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-items-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_items_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout-review-order-table .cart_item td', + ] + ); + + $this->add_control( + 'order_summary_variations_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_variations_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-variations-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_variations_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_TEXT, + ], + 'selector' => '{{WRAPPER}} .product-name .variation', + ] + ); + + $this->add_control( + 'order_summary_items_divider_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_items_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-items-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_items_divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-items-divider-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'order_summary_totals_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_totals_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-totals-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_totals_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout-review-order-table thead tr th, {{WRAPPER}} .woocommerce-checkout-review-order-table tfoot tr th, {{WRAPPER}} .woocommerce-checkout-review-order-table tfoot tr td', + ] + ); + + $this->add_control( + 'order_summary_dividers_total_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Divider Total', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_totals_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-totals-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_totals_divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-totals-divider-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_purchase_button', + [ + 'label' => esc_html__( 'Purchase Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'purchase_button_typography', + 'selector' => '{{WRAPPER}} .woocommerce #payment #place_order', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'purchase_button_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce #payment #place_order', + ] + ); + + $this->start_controls_tabs( 'purchase_button_styles' ); + + $this->start_controls_tab( 'purchase_button_normal_styles', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'purchase_button_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'purchase_button_normal_background', + 'selector' => '{{WRAPPER}} #payment #place_order', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'purchase_button_normal_box_shadow', + 'selector' => '{{WRAPPER}} #place_order', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'purchase_button_hover_styles', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'purchase_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'purchase_button_hover_background', + 'selector' => '{{WRAPPER}} #payment #place_order:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'purchase_button_hover_box_shadow', + 'selector' => '{{WRAPPER}} #place_order:hover', + ] + ); + + $this->add_control( + 'purchase_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-hover-border-color: {{VALUE}}', + ], + 'condition' => [ + 'purchase_button_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'purchase_button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'purchase_button_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'purchase_button_border', + 'selector' => '{{WRAPPER}} #place_order', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'purchase_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'purchase_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--purchase-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --purchase-button-width: fit-content;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_customize', + [ + 'label' => esc_html__( 'Customize', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $customize_options = []; + + if ( $this->is_wc_feature_active( 'checkout_login_reminder' ) ) { + $customize_options += [ + 'customize_returning_customer' => esc_html__( 'Returning Customer', 'elementor-pro' ), + ]; + } + + $customize_options += [ + 'customize_billing_details' => esc_html__( 'Billing Details', 'elementor-pro' ), + 'customize_additional_info' => esc_html__( 'Additional Information', 'elementor-pro' ), + ]; + + if ( $this->is_wc_feature_active( 'shipping' ) ) { + $customize_options += [ + 'customize_shipping_address' => esc_html__( 'Shipping Address', 'elementor-pro' ), + ]; + } + + $customize_options += [ + 'customize_order_summary' => esc_html__( 'Order Summary', 'elementor-pro' ), + ]; + + if ( $this->is_wc_feature_active( 'coupons' ) ) { + $customize_options += [ + 'customize_coupon' => esc_html__( 'Coupon', 'elementor-pro' ), + ]; + } + + $customize_options += [ + 'customize_payment' => esc_html__( 'Payment', 'elementor-pro' ), + ]; + + $this->add_control( + 'section_checkout_show_customize_elements', + [ + 'label' => esc_html__( 'Select sections of the checkout to customize:', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => $customize_options, + 'render_type' => 'ui', + 'label_block' => true, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_customize_returning_customer', + [ + 'label' => esc_html__( 'Customize: Returning Customer', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_returning_customer', + ], + ] + ); + + $this->add_control( + 'returning_customers_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_returning_customer_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'returning_customers_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-woocommerce-login-section', + ] + ); + + $this->add_control( + 'returning_customers_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'returning_customers_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'returning_customers_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'returning_customers_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'returning_customers_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'returning_customers_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'returning_customers_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'returning_customers_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'returning_customers_secondary_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Secondary Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'returning_customers_secondary_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-form-login-toggle' => '--sections-secondary-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'returning_customers_content_typography', + 'selector' => '{{WRAPPER}} .woocommerce-form-login-toggle', + ] + ); + + $this->add_control( + 'returning_customers_description_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'returning_customers_description_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-nudge' => '--sections-descriptions-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'returning_customers_description_typography', + 'selector' => '{{WRAPPER}} .e-woocommerce-login-nudge.e-description', + ] + ); + + $this->add_control( + 'returning_customers_checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkbox', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'returning_customers_checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--sections-checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'returning_customers_checkboxes_typography', + 'selector' => '{{WRAPPER}} .e-woocommerce-login-section .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->add_control( + 'returning_customers_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'returning_customers_links' ); + + $this->start_controls_tab( 'returning_customers_normal_links', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'returning_customers_normal_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'returning_customers_hover_links', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'returning_customers_hover_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-login-section' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_customize_billing_details', + [ + 'label' => esc_html__( 'Customize: Billing Details', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_billing_details', + ], + ] + ); + + $this->add_control( + 'customize_billing_details_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_billing_details_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'billing_details_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-checkout__column-start .col2-set .col-1', + ] + ); + + $this->add_control( + 'billing_details_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'billing_details_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-checkout__column-start #customer_details .col-1' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'billing_details_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'billing_details_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-border-color: {{VALUE}}', + ], + 'condition' => [ + 'billing_details_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'billing_details_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'billing_details_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'billing_details_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'billing_details_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'billing_details_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'billing_details_titles_typography', + 'selector' => '{{WRAPPER}} .woocommerce-billing-fields h3', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'billing_details_titles_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-billing-fields h3', + ] + ); + + $this->add_control( + 'billing_details_checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkbox', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'billing_details_checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .col2-set .col-1' => '--sections-checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'billing_details_checkboxes_typography', + 'selector' => '{{WRAPPER}} .col2-set .col-1 .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_customize_additional_info', + [ + 'label' => esc_html__( 'Customize: Additional Information', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_additional_info', + ], + ] + ); + + $this->add_control( + 'customize_additional_information_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_additional_information_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'additional_information_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-additional-fields', + ] + ); + + $this->add_control( + 'additional_information_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'additional_information_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'additional_information_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'additional_information_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'additional_information_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'additional_information_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'additional_information_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'additional_information_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + '{{WRAPPER}}.e-checkout-layout-one-column .e-checkout__container' => 'grid-row-gap: {{BOTTOM}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'additional_information_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'additional_information_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-additional-fields' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'additional_information_titles_typography', + 'selector' => '{{WRAPPER}} .woocommerce-additional-fields h3', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'additional_information_titles_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-additional-fields h3', + ] + ); + + $this->end_controls_section(); + + if ( $this->is_wc_feature_active( 'shipping' ) ) { + $this->add_shipping_style_controls(); + } + + if ( $this->is_wc_feature_active( 'coupons' ) ) { + $this->add_coupons_style_controls(); + } + + $this->start_controls_section( + 'section_checkout_tabs_customize_order_summary', + [ + 'label' => esc_html__( 'Customize: Order Summary', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_order_summary', + ], + ] + ); + + $this->add_control( + 'customize_order_summary_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_order_summary_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'order_summary_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-checkout__order_review', + ] + ); + + $this->add_control( + 'order_summary_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'order_summary_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'order_summary_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_summary_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-border-color: {{VALUE}}', + ], + 'condition' => [ + 'order_summary_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_summary_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'order_summary_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_titles_typography', + 'selector' => '{{WRAPPER}} h3#order_review_heading', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'order_summary_titles_text_shadow', + 'selector' => '{{WRAPPER}} h3#order_review_heading', + ] + ); + + $this->add_control( + 'order_summary_descriptions_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Message', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_descriptions_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-descriptions-color: {{VALUE}}; --sections-messages-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_descriptions_typography', + 'selector' => '{{WRAPPER}} .woocommerce-no-shipping-available-html.e-description, {{WRAPPER}} .woocommerce-no-shipping-available-html.e-checkout-message', + ] + ); + + $this->add_control( + 'order_summary_radios_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Radio Button', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_radios_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-checkout__order_review' => '--sections-radio-buttons-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_summary_radio_typography', + 'selector' => '{{WRAPPER}} .woocommerce .e-checkout__order_review ul#shipping_method li label', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_checkout_tabs_customize_payment', + [ + 'label' => esc_html__( 'Customize: Payment', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_payment', + ], + ] + ); + + $this->add_control( + 'customize_payment_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_payment_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'payment_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-checkout #payment', + ] + ); + + $this->add_control( + 'payment_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'payment_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'payment_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'payment_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'payment_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'payment_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'payment_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'payment_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'payment_info_box_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Info Box', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'payment_info_box_title_background', + 'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_methods .payment_box', + ] + ); + + $this->add_control( + 'payment_description_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Description', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_description_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-descriptions-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_description_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout-payment .e-description', + ] + ); + + $this->add_control( + 'payment_messages_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Message', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_messages_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-messages-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_messages_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_box, {{WRAPPER}} .woocommerce-privacy-policy-text p', + ] + ); + + $this->add_control( + 'payment_checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkbox', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-terms-and-conditions-wrapper' => '--sections-checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_checkboxes_typography', + 'selector' => '{{WRAPPER}} .woocommerce-terms-and-conditions-wrapper .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->add_control( + 'payment_radio_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Radio Button', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_radio_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-radio-buttons-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_radio_typography', + 'selector' => '{{WRAPPER}} .woocommerce-checkout-payment .wc_payment_method label', + ] + ); + + $this->add_control( + 'payment_links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Links', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'payment_colors' ); + + $this->start_controls_tab( 'payment_normal_colors', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'payment_normal_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout-payment' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'payment_hover_colors', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'payment_hover_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-checkout-payment' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + private function add_checkout_login_reminder_controls() { + $this->start_controls_section( + 'returning_customer_heading', + [ + 'label' => esc_html__( 'Returning Customer', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'returning_customer_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Returning customer?', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'returning_customer_link_text', + [ + 'label' => esc_html__( 'Link Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Click here to login', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_responsive_control( + 'returning_customer_title_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--login-title-alignment: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'login_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Login Button', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'login_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .e-login-wrap' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--login-button-alignment: start; --login-button-width: 35%;', + 'center' => '--login-button-alignment: center; --login-button-width: 35%;', + 'end' => '--login-button-alignment: end; --login-button-width: 35%;', + 'justify' => '--login-button-alignment: center; --login-button-width: 100%;', + ], + ] + ); + + $this->add_control( + 'login_button_alignment_note', + [ + 'raw' => esc_html__( 'Note: This control will only affect screen sizes Tablet and below', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->end_controls_section(); + } + + private function add_shipping_controls() { + $this->start_controls_section( + 'shipping_details_section', + [ + 'label' => esc_html__( 'Shipping Details', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'shipping_details_section_title', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Ship to a different address?', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'repeater_state', + [ + 'label' => esc_html__( 'Repeater State - hidden', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + ] + ); + + $repeater->add_control( + 'label_placeholder_notification', + [ + 'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'repeater_state' => 'from_billing', + ], + ] + ); + + $repeater->start_controls_tabs( 'tabs', [ + 'condition' => [ + 'repeater_state' => '', + ], + ] ); + + $repeater->start_controls_tab( 'content_tab', [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'label', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + ] + ); + + $repeater->add_control( + 'placeholder', + [ + 'label' => esc_html__( 'Placeholder', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + ] + ); + + $repeater->end_controls_tab(); + + $repeater->start_controls_tab( 'advanced_tab', [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + ] ); + + $repeater->add_control( + 'default', + [ + 'label' => esc_html__( 'Default Value', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->end_controls_tab(); + + $repeater->end_controls_tabs(); + + $repeater->add_control( + 'locale_notice', + [ + 'raw' => __( 'Note: This content cannot be changed due to local regulations.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'repeater_state' => 'locale', + ], + ] + ); + + $repeater->add_control( + 'from_billing_notice', + [ + 'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'repeater_state' => 'from_billing', + ], + ] + ); + + $this->add_control( + 'shipping_details_form_fields', + [ + 'label' => esc_html__( 'Form Items', 'elementor-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'item_actions' => [ + 'add' => false, + 'duplicate' => false, + 'remove' => false, + 'sort' => false, + ], + 'default' => $this->get_shipping_field_defaults(), + 'title_field' => '{{{ label }}}', + ] + ); + + $this->end_controls_section(); + } + + private function add_signup_and_login_from_checkout_controls() { + $this->start_controls_section( + 'create_account_section', + [ + 'label' => esc_html__( 'Create an Account', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'create_account_text', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Create an account?', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->end_controls_section(); + } + + private function add_coupon_controls() { + $this->start_controls_section( + 'coupon_section', + [ + 'label' => esc_html__( 'Coupon', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'coupon_section_display', + [ + 'label' => esc_html__( 'Coupon', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + ] + ); + + $this->add_control( + 'coupon_section_title_text', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Have a coupon?', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->add_control( + 'coupon_section_title_link_text', + [ + 'label' => esc_html__( 'Link Text', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Click here to enter your coupon code', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--coupon-title-alignment: {{VALUE}};', + ], + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Apply Button', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .coupon-container-grid' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--coupon-button-alignment: start;', + 'center' => '--coupon-button-alignment: center;', + 'end' => '--coupon-button-alignment: end;', + 'justify' => '--coupon-button-alignment: justify; --coupon-button-width: 100%;', + ], + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->add_control( + 'coupon_button_alignment_note', + [ + 'raw' => esc_html__( 'Note: This control will only affect screen sizes Tablet and below', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'coupon_section_display' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + private function add_shipping_style_controls() { + $this->start_controls_section( + 'section_checkout_tabs_customize_shipping_address', + [ + 'label' => esc_html__( 'Customize: Shipping Address', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_shipping_address', + ], + ] + ); + + $this->add_control( + 'shipping_address_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_shipping_address_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'shipping_address_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address', + ] + ); + + $this->add_control( + 'shipping_address_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'shipping_address_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'shipping_address_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'shipping_address_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-color: {{VALUE}}', + ], + 'condition' => [ + 'shipping_address_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'shipping_address_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'shipping_address_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'shipping_address_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'shipping_address_checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkboxes', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'shipping_address_checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .woocommerce-shipping-fields' => '--sections-checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'shipping_address_checkboxes_typography', + 'selector' => '{{WRAPPER}} .woocommerce-shipping-fields .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->end_controls_section(); + } + + private function add_coupons_style_controls() { + $this->start_controls_section( + 'section_checkout_tabs_customize_coupon', + [ + 'label' => esc_html__( 'Customize: Coupon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'section_checkout_show_customize_elements' => 'customize_coupon', + ], + ] + ); + + $this->add_control( + 'customize_coupon_section_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_coupon_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'coupon_section_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-coupon-box', + ] + ); + + $this->add_control( + 'coupon_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'coupon_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'coupon_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'coupon_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'coupon_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'coupon_margin', + [ + 'label' => esc_html__( 'Margin', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'coupon_secondary_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Secondary Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'coupon_secondary_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-woocommerce-coupon-nudge' => '--sections-secondary-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'coupon_content_typography', + 'selector' => '{{WRAPPER}} .e-woocommerce-coupon-nudge.e-checkout-secondary-title', + ] + ); + + $this->add_control( + 'coupon_link_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'coupon_links' ); + + $this->start_controls_tab( 'coupon_normal_links', [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] ); + + $this->add_control( + 'coupon_normal_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'coupon_hover_links', [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] ); + + $this->add_control( + 'coupon_hover_links_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-coupon-box' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + /** + * Get Billing Field Defaults + * + * Get defaults used for the billing details repeater control. + * + * @since 3.5.0 + * + * @return array + */ + private function get_billing_field_defaults() { + $fields = [ + 'billing_first_name' => [ + 'label' => esc_html__( 'First Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'billing_last_name' => [ + 'label' => esc_html__( 'Last Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'billing_company' => [ + 'label' => esc_html__( 'Company Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'billing_country' => [ + 'label' => esc_html__( 'Country / Region', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'billing_address_1' => [ + 'label' => esc_html__( 'Street Address', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'billing_postcode' => [ + 'label' => esc_html__( 'Post Code', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'billing_city' => [ + 'label' => esc_html__( 'Town / City', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'billing_state' => [ + 'label' => esc_html__( 'State', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'billing_phone' => [ + 'label' => esc_html__( 'Phone', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'billing_email' => [ + 'label' => esc_html__( 'Email Address', 'elementor-pro' ), + 'repeater_state' => '', + ], + ]; + + return $this->reformat_address_field_defaults( $fields ); + } + + /** + * Get Shipping Field Defaults + * + * Get defaults used for the shipping details repeater control. + * + * @since 3.5.0 + * + * @return array + */ + private function get_shipping_field_defaults() { + $fields = [ + 'shipping_first_name' => [ + 'label' => esc_html__( 'First Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'shipping_last_name' => [ + 'label' => esc_html__( 'Last Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'shipping_company' => [ + 'label' => esc_html__( 'Company Name', 'elementor-pro' ), + 'repeater_state' => '', + ], + 'shipping_country' => [ + 'label' => esc_html__( 'Country / Region', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'shipping_address_1' => [ + 'label' => esc_html__( 'Street Address', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'shipping_postcode' => [ + 'label' => esc_html__( 'Post Code', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'shipping_city' => [ + 'label' => esc_html__( 'Town / City', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + 'shipping_state' => [ + 'label' => esc_html__( 'State', 'elementor-pro' ), + 'repeater_state' => 'locale', + ], + ]; + + return $this->reformat_address_field_defaults( $fields ); + } + + /** + * Reformat Address Field Defaults + * + * Used with the `get_..._field_defaults()` methods. + * Takes the address array and converts it into the format expected by the repeater controls. + * + * @since 3.5.0 + * + * @param $address + * @return array + */ + private function reformat_address_field_defaults( $address ) { + $defaults = []; + foreach ( $address as $key => $value ) { + $defaults[] = [ + 'field_key' => $key, + 'field_label' => $value['label'], + 'label' => $value['label'], + 'placeholder' => $value['label'], + 'repeater_state' => $value['repeater_state'], + ]; + } + + return $defaults; + } + + /** + * Get Main Woocommerce Sections Selectors + * + * Get all the 'Sections' selectors. There are numerous controls that need these selectors so it was easier + * to consolidate them into one function. Especially when updates need to be made. + * + * @since 3.5.0 + * + * @return string + */ + private function get_main_woocommerce_sections_selectors() { + $selector = '{{WRAPPER}} .e-woocommerce-login-section, {{WRAPPER}} .woocommerce-checkout #customer_details .col-1, {{WRAPPER}} .woocommerce-additional-fields, {{WRAPPER}} .e-checkout__order_review, {{WRAPPER}} .e-coupon-box, {{WRAPPER}} .woocommerce-checkout #payment'; + if ( $this->is_wc_feature_active( 'shipping' ) ) { + $selector .= ', {{WRAPPER}} .woocommerce-shipping-fields .shipping_address'; + } + return $selector; + } + + /** + * Get Main Woocommerce Sections Title Selectors + * + * Get all the 'Title' selectors. There are numerous controls that need these selectors so it was easier to + * consolidate them into one function. Especially when updates need to be made. + * + * @since 3.5.0 + * + * @return string + */ + private function get_main_woocommerce_sections_title_selectors() { + return '{{WRAPPER}} h3#order_review_heading, {{WRAPPER}} .woocommerce-billing-fields h3, {{WRAPPER}} .woocommerce-additional-fields h3'; + } + + /** + * Init Gettext Modifications + * + * Sets the `$gettext_modifications` property used with the `filter_gettext()` in the extended Base_Widget. + * + * @since 3.5.0 + */ + protected function init_gettext_modifications() { + $instance = $this->get_settings_for_display(); + + $this->gettext_modifications = [ + 'Billing details' => isset( $instance['billing_details_section_title'] ) ? $instance['billing_details_section_title'] : '', + 'Billing & Shipping' => isset( $instance['billing_details_section_title'] ) ? $instance['billing_details_section_title'] : '', + 'Ship to a different address?' => isset( $instance['shipping_details_section_title'] ) ? $instance['shipping_details_section_title'] : '', + 'Additional information' => isset( $instance['additional_information_section_title'] ) ? $instance['additional_information_section_title'] : '', + 'Your order' => isset( $instance['order_summary_section_title'] ) ? $instance['order_summary_section_title'] : '', + 'Have a coupon?' => isset( $instance['coupon_section_title_text'] ) ? $instance['coupon_section_title_text'] : '', + 'Click here to enter your coupon code' => isset( $instance['coupon_section_title_link_text'] ) ? $instance['coupon_section_title_link_text'] : '', + 'Returning customer?' => isset( $instance['returning_customer_section_title'] ) ? $instance['returning_customer_section_title'] : '', + 'Click here to login' => isset( $instance['returning_customer_link_text'] ) ? $instance['returning_customer_link_text'] : '', + 'Create an account?' => isset( $instance['create_account_text'] ) ? $instance['create_account_text'] : '', + ]; + } + + /** + * WooCommerce Terms and Conditions Checkbox Text. + * + * WooCommerce filter is used to apply widget settings to Checkout Terms & Conditions text and link text. + * + * @since 3.5.0 + * + * @param string $text + * @return string + */ + public function woocommerce_terms_and_conditions_checkbox_text( $text ) { + $instance = $this->get_settings_for_display(); + + if ( ! isset( $instance['terms_conditions_message_text'] ) || ! isset( $instance['terms_conditions_link_text'] ) ) { + return $text; + } + + $message = $instance['terms_conditions_message_text']; + $link = $instance['terms_conditions_link_text']; + + $terms_page_id = wc_terms_and_conditions_page_id(); + if ( $terms_page_id ) { + $message .= ' ' . $link . ''; + } + + return $message; + } + + /** + * Modify Form Field. + * + * WooCommerce filter is used to apply widget settings to the Checkout forms address fields + * from the Billing and Shipping Details widget sections, e.g. label, placeholder, default. + * + * @since 3.5.0 + * + * @param array $args + * @param string $key + * @param string $value + * @return array + */ + public function modify_form_field( $args, $key, $value ) { + $reformatted_form_fields = $this->get_reformatted_form_fields(); + + // Check if we need to modify the args of this form field. + if ( isset( $reformatted_form_fields[ $key ] ) ) { + $apply_fields = [ + 'label', + 'placeholder', + 'default', + ]; + + foreach ( $apply_fields as $field ) { + if ( ! empty( $reformatted_form_fields[ $key ][ $field ] ) ) { + $args[ $field ] = $reformatted_form_fields[ $key ][ $field ]; + } + } + } + + return $args; + } + + /** + * Get Reformatted Form Fields. + * + * Combines the 3 relevant repeater settings arrays into a one level deep associative array + * with the keys that match those that WooCommerce uses for its form fields. + * + * The result is cached so the conversion only ever happens once. + * + * @since 3.5.0 + * + * @return array + */ + private function get_reformatted_form_fields() { + if ( ! isset( $this->reformatted_form_fields ) ) { + $instance = $this->get_settings_for_display(); + + // Reformat form repeater field into one usable array. + $repeater_fields = [ + 'billing_details_form_fields', + 'shipping_details_form_fields', + 'additional_information_form_fields', + ]; + + $this->reformatted_form_fields = []; + + // Apply other modifications to inputs. + foreach ( $repeater_fields as $repeater_field ) { + if ( isset( $instance[ $repeater_field ] ) ) { + foreach ( $instance[ $repeater_field ] as $item ) { + if ( ! isset( $item['field_key'] ) ) { + continue; + } + $this->reformatted_form_fields[ $item['field_key'] ] = $item; + } + } + } + } + + return $this->reformatted_form_fields; + } + + /** + * Render Woocommerce Checkout Login Form + * + * A custom function to render a login form on the Checkout widget. The default WC Login form + * was removed in this file's render() method with: + * remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_login_form' ); + * + * And then we are adding this form into the widget at the + * 'woocommerce_checkout_before_customer_details' hook. + * + * We are doing this in order to match the placement of the Login form to the provided design. + * WC places these forms ABOVE the checkout form section where as we needed to place them inside the + * checkout form section. So we removed the default login form and added our own form. + * + * @since 3.5.0 + */ + private function render_woocommerce_checkout_login_form() { + $settings = $this->get_settings_for_display(); + $button_classes = [ 'woocommerce-button', 'button', 'woocommerce-form-login__submit', 'e-woocommerce-form-login-submit' ]; + if ( $settings['forms_buttons_hover_animation'] ) { + $button_classes[] = 'elementor-animation-' . $settings['forms_buttons_hover_animation']; + } + $this->add_render_attribute( + 'button_login', [ + 'class' => $button_classes, + 'name' => 'login', + 'type' => 'submit', + ] + ); + ?> + + get_settings_for_display(); + $button_classes = [ 'woocommerce-button', 'button', 'e-apply-coupon' ]; + if ( $settings['forms_buttons_hover_animation'] ) { + $button_classes[] = 'elementor-animation-' . $settings['forms_buttons_hover_animation']; + } + $this->add_render_attribute( + 'button_coupon', [ + 'class' => $button_classes, + 'name' => 'apply_coupon', + 'type' => 'submit', + ] + ); + ?> +
          +

          + +
          + editor->is_edit_mode() ); + } + + /** + * Should Render Coupon + * + * Decide if the coupon form should be rendered. + * The coupon form should be rendered if: + * 1) The WooCommerce setting is enabled + * 2) And the Coupon Display toggle hasn't been set to 'no' + * 3) AND: a payment is needed, OR the Editor is open + * + * @since 3.5.0 + * + * @return boolean + */ + private function should_render_coupon() { + $settings = $this->get_settings_for_display(); + $coupon_display_control = true; + + if ( '' === $settings['coupon_section_display'] ) { + $coupon_display_control = false; + } + + return ( WC()->cart->needs_payment() || Plugin::elementor()->editor->is_edit_mode() ) && wc_coupons_enabled() && $coupon_display_control; + } + + /** + * WooCommerce Checkout Before Customer Details + * + * Callback function for the woocommerce_checkout_before_customer_details hook that outputs elements + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function woocommerce_checkout_before_customer_details() { + ?> +
          + +
          + + should_render_login() ) { + $this->render_woocommerce_checkout_login_form(); + } + } + + /** + * Woocommerce Checkout After Customer Details + * + * Output containing elements. Callback function for the woocommerce_checkout_after_customer_details hook. + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function woocommerce_checkout_after_customer_details() { + ?> + +
          + +
          + +
          + + +
          + + + +
          + +
          + should_render_coupon() ) { + $this->render_woocommerce_checkout_coupon_form(); + } + ?> +
          + + + + +
          + +
          + +
          + editor->is_edit_mode(); + + // Simulate a logged out user so that all WooCommerce sections will render in the Editor + if ( $is_editor ) { + $store_current_user = wp_get_current_user()->ID; + wp_set_current_user( 0 ); + } + + // Add actions & filters before displaying our Widget. + $this->add_render_hooks(); + + // Display our Widget. + echo do_shortcode( '[woocommerce_checkout]' ); + + // Remove actions & filters after displaying our Widget. + $this->remove_render_hooks(); + + // Return to existing logged-in user after widget is rendered. + if ( $is_editor ) { + wp_set_current_user( $store_current_user ); + } + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/elements.php b/modules/woocommerce/widgets/elements.php new file mode 100644 index 00000000..ddf62204 --- /dev/null +++ b/modules/woocommerce/widgets/elements.php @@ -0,0 +1,163 @@ +start_controls_section( + 'section_product', + [ + 'label' => esc_html__( 'Element', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'element', + [ + 'label' => esc_html__( 'Page', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => '— ' . esc_html__( 'Select', 'elementor-pro' ) . ' —', + 'woocommerce_cart' => esc_html__( 'Cart Page', 'elementor-pro' ), + 'product_page' => esc_html__( 'Single Product Page', 'elementor-pro' ), + 'woocommerce_checkout' => esc_html__( 'Checkout Page', 'elementor-pro' ), + 'woocommerce_order_tracking' => esc_html__( 'Order Tracking Form', 'elementor-pro' ), + 'woocommerce_my_account' => esc_html__( 'My Account', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'product_id', + [ + 'label' => esc_html__( 'Product', 'elementor-pro' ), + 'type' => QueryModule::QUERY_CONTROL_ID, + 'options' => [], + 'label_block' => true, + 'autocomplete' => [ + 'object' => QueryModule::QUERY_OBJECT_POST, + 'query' => [ + 'post_type' => [ 'product' ], + ], + ], + 'condition' => [ + 'element' => [ 'product_page' ], + ], + ] + ); + + $this->end_controls_section(); + } + + private function get_shortcode() { + $settings = $this->get_settings(); + + switch ( $settings['element'] ) { + case '': + return ''; + break; + + case 'product_page': + if ( ! empty( $settings['product_id'] ) ) { + $product_data = get_post( $settings['product_id'] ); + $product = ! empty( $product_data ) && in_array( $product_data->post_type, [ 'product', 'product_variation' ] ) ? wc_setup_product_data( $product_data ) : false; + } + + if ( empty( $product ) && current_user_can( 'manage_options' ) ) { + return esc_html__( 'Please set a valid product', 'elementor-pro' ); + } + + $this->add_render_attribute( 'shortcode', 'id', $settings['product_id'] ); + break; + + case 'woocommerce_cart': + case 'woocommerce_checkout': + case 'woocommerce_order_tracking': + break; + } + + $shortcode = sprintf( + '[%s %s]', + esc_html( $settings['element'] ), + $this->get_render_attribute_string( 'shortcode' ) + ); + + return $shortcode; + } + + protected function render() { + $shortcode = $this->get_shortcode(); + + if ( empty( $shortcode ) ) { + return; + } + + Module::instance()->add_products_post_class_filter(); + + $html = do_shortcode( $shortcode ); + + if ( 'woocommerce_checkout' === $this->get_settings( 'element' ) && '
          ' === $html ) { + $html = '
          ' . esc_html__( 'Your cart is currently empty.', 'elementor-pro' ) . '
          '; + } + + // PHPCS - Woocommerce output + echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + Module::instance()->remove_products_post_class_filter(); + } + + public function render_plain_content() { + // PHPCS - Already escaped in get_shortcode + echo $this->get_shortcode(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/menu-cart.php b/modules/woocommerce/widgets/menu-cart.php new file mode 100644 index 00000000..7ed77255 --- /dev/null +++ b/modules/woocommerce/widgets/menu-cart.php @@ -0,0 +1,2282 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-menu-cart' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_menu_icon_content', + [ + 'label' => esc_html__( 'Menu Icon', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'icon', + [ + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'cart-light' => esc_html__( 'Cart', 'elementor-pro' ) . ' ' . esc_html__( 'Light', 'elementor-pro' ), + 'cart-medium' => esc_html__( 'Cart', 'elementor-pro' ) . ' ' . esc_html__( 'Medium', 'elementor-pro' ), + 'cart-solid' => esc_html__( 'Cart', 'elementor-pro' ) . ' ' . esc_html__( 'Solid', 'elementor-pro' ), + 'basket-light' => esc_html__( 'Basket', 'elementor-pro' ) . ' ' . esc_html__( 'Light', 'elementor-pro' ), + 'basket-medium' => esc_html__( 'Basket', 'elementor-pro' ) . ' ' . esc_html__( 'Medium', 'elementor-pro' ), + 'basket-solid' => esc_html__( 'Basket', 'elementor-pro' ) . ' ' . esc_html__( 'Solid', 'elementor-pro' ), + 'bag-light' => esc_html__( 'Bag', 'elementor-pro' ) . ' ' . esc_html__( 'Light', 'elementor-pro' ), + 'bag-medium' => esc_html__( 'Bag', 'elementor-pro' ) . ' ' . esc_html__( 'Medium', 'elementor-pro' ), + 'bag-solid' => esc_html__( 'Bag', 'elementor-pro' ) . ' ' . esc_html__( 'Solid', 'elementor-pro' ), + 'custom' => esc_html__( 'Custom', 'elementor-pro' ), + ], + 'default' => 'cart-medium', + 'prefix_class' => 'toggle-icon--', // Prefix class not used anymore, but kept for BC reasons. + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'menu_icon_svg', + [ + 'label' => esc_html__( 'Custom Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon_active', + 'default' => [ + 'value' => 'fas fa-shopping-cart', + 'library' => 'fa-solid', + ], + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => 'None', + ], + ], + ], + 'recommended' => [ + 'fa-solid' => [ + 'shopping-bag', + 'shopping-basket', + 'shopping-cart', + 'cart-arrow-down', + 'cart-plus', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'icon' => 'custom', + ], + ] + ); + + $this->add_control( + 'items_indicator', + [ + 'label' => esc_html__( 'Items Indicator', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'bubble' => esc_html__( 'Bubble', 'elementor-pro' ), + 'plain' => esc_html__( 'Plain', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-menu-cart--items-indicator-', + 'default' => 'bubble', + ] + ); + + $this->add_control( + 'hide_empty_indicator', + [ + 'label' => esc_html__( 'Hide Empty', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'hide', + 'prefix_class' => 'elementor-menu-cart--empty-indicator-', + 'condition' => [ + 'items_indicator!' => 'none', + ], + ] + ); + + $this->add_control( + 'show_subtotal', + [ + 'label' => esc_html__( 'Subtotal', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'prefix_class' => 'elementor-menu-cart--show-subtotal-', + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--main-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart', + [ + 'label' => esc_html__( 'Cart', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'cart_type', + [ + 'label' => esc_html__( 'Cart Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'side-cart' => esc_html__( 'Side Cart', 'elementor-pro' ), + 'mini-cart' => esc_html__( 'Mini Cart', 'elementor-pro' ), + ], + 'default' => 'side-cart', + 'prefix_class' => 'elementor-menu-cart--cart-type-', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'open_cart', + [ + 'label' => esc_html__( 'Open Cart', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'click' => esc_html__( 'On Click', 'elementor-pro' ), + 'mouseover' => esc_html__( 'On Hover', 'elementor-pro' ), + ], + 'default' => 'click', + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->add_responsive_control( + 'side_cart_alignment', + [ + 'label' => esc_html__( 'Cart Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'cart_type' => 'side-cart', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--side-cart-alignment-transform: translateX(-100%); --side-cart-alignment-right: auto; --side-cart-alignment-left: 0;', + 'end' => '--side-cart-alignment-transform: translateX(100%); --side-cart-alignment-left: auto; --side-cart-alignment-right: 0;', + ], + ] + ); + + $this->add_responsive_control( + 'mini_cart_alignment', + [ + 'label' => esc_html__( 'Cart Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'cart_type' => 'mini-cart', + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-menu-cart--cart-type-mini-cart .elementor-menu-cart__container' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => 'left: 0; right: auto; transform: none;', + 'center' => 'left: 50%; right: auto; transform: translateX(-50%);', + 'end' => 'right: 0; left: auto; transform: none;', + ], + ] + ); + + $this->add_responsive_control( + 'mini_cart_spacing', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => -300, + 'max' => 300, + ], + 'em' => [ + 'min' => -30, + 'max' => 30, + ], + 'rem' => [ + 'min' => -30, + 'max' => 30, + ], + '%' => [ + 'min' => -100, + 'max' => 100, + ], + ], + 'condition' => [ + 'cart_type' => 'mini-cart', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--mini-cart-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'heading_close_cart_button', + [ + 'label' => esc_html__( 'Close Cart', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'close_cart_button_show', + [ + 'label' => esc_html__( 'Close Icon', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__close-button, {{WRAPPER}} .elementor-menu-cart__close-button-custom' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + '' => 'display: none;', + ], + 'control_type' => 'content', + ] + ); + + $this->add_control( + 'close_cart_icon_svg', + [ + 'label' => esc_html__( 'Custom Icon', 'elementor-pro' ), + 'type' => Controls_Manager::ICONS, + 'fa4compatibility' => 'icon_active', + 'skin_settings' => [ + 'inline' => [ + 'none' => [ + 'label' => 'Default', + 'icon' => 'fas fa-times', + ], + 'icon' => [ + 'icon' => 'eicon-star', + ], + ], + ], + 'recommended' => [ + 'fa-regular' => [ + 'times-circle', + ], + 'fa-solid' => [ + 'times', + 'times-circle', + ], + ], + 'skin' => 'inline', + 'label_block' => false, + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'close_cart_button_alignment', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'condition' => [ + 'close_cart_button_show!' => '', + ], + 'selectors_dictionary' => [ + 'start' => 'margin-right: auto', + 'end' => 'margin-left: auto', + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__close-button, {{WRAPPER}} .elementor-menu-cart__close-button-custom' => '{{VALUE}};', + ], + ] + ); + + $this->add_control( + 'heading_remove_item_button', + [ + 'label' => esc_html__( 'Remove Item', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'show_remove_icon', + [ + 'label' => esc_html__( 'Remove Item Icon', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'prefix_class' => 'elementor-menu-cart--show-remove-button-', + ] + ); + + $this->add_control( + 'remove_item_button_position', + [ + 'label' => esc_html__( 'Icon Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'middle' => [ + 'title' => esc_html__( 'Middle', 'elementor-pro' ), + 'icon' => 'eicon-v-align-middle', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'default' => '', + 'prefix_class' => 'remove-item-position--', + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->add_control( + 'heading_price_quantity', + [ + 'label' => esc_html__( 'Price and Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'price_quantity_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'top' => '--price-quantity-position--grid-template-rows: auto 75%; --price-quantity-position--align-self: start;', + 'bottom' => '', + ], + ] + ); + + $this->add_control( + 'show_divider', + [ + 'label' => esc_html__( 'Cart Dividers', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'separator' => 'before', + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '--divider-style: {{VALUE}}; --subtotal-divider-style: {{VALUE}};', + ], + 'selectors_dictionary' => [ + '' => 'none', + 'yes' => 'solid', + ], + ] + ); + + $this->add_control( + 'heading_buttons', + [ + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'view_cart_button_show', + [ + 'label' => esc_html__( 'View Cart', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + '' => '--view-cart-button-display: none; --cart-footer-layout: 1fr;', + ], + ] + ); + + $this->add_control( + 'view_cart_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'condition' => [ + 'view_cart_button_show!' => '', + 'checkout_button_show' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: left; --cart-footer-buttons-alignment-button-width: auto;', + 'center' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: center; --cart-footer-buttons-alignment-button-width: auto;', + 'end' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: right; --cart-footer-buttons-alignment-button-width: auto;', + 'justify' => '--cart-footer-layout: 1fr;', + ], + ] + ); + + $this->add_control( + 'checkout_button_show', + [ + 'label' => esc_html__( 'Checkout', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + '' => '--checkout-button-display: none; --cart-footer-layout: 1fr;', + ], + ] + ); + + $this->add_control( + 'checkout_button_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justify', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'condition' => [ + 'checkout_button_show!' => '', + 'view_cart_button_show' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: left; --cart-footer-buttons-alignment-button-width: auto;', + 'center' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: center; --cart-footer-buttons-alignment-button-width: auto;', + 'end' => '--cart-footer-buttons-alignment-display: block; --cart-footer-buttons-alignment-text-align: right; --cart-footer-buttons-alignment-button-width: auto;', + 'justify' => '--cart-footer-layout: 1fr;', + ], + ] + ); + + $this->add_control( + 'checkout_button_display', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'condition' => [ + 'checkout_button_show' => '', + 'view_cart_button_show' => '', + ], + 'default' => '--cart-footer-buttons-alignment-display: none;', + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + ] + ); + + $this->add_control( + 'buttons_position', + [ + 'label' => esc_html__( 'Vertical Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'top' => [ + 'title' => esc_html__( 'Top', 'elementor-pro' ), + 'icon' => 'eicon-v-align-top', + ], + 'bottom' => [ + 'title' => esc_html__( 'Bottom', 'elementor-pro' ), + 'icon' => 'eicon-v-align-bottom', + ], + ], + 'default' => '', + 'condition' => [ + 'cart_type' => 'side-cart', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'view_cart_button_show', + 'operator' => '!=', + 'value' => '', + ], + [ + 'name' => 'checkout_button_show', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'bottom' => '--cart-buttons-position-margin: auto;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'heading_additional_options', + [ + 'label' => esc_html__( 'Cart', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'automatically_open_cart', + [ + 'label' => esc_html__( 'Automatically Open Cart', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'description' => esc_html__( 'Open the cart every time an item is added.', 'elementor-pro' ), + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'no', + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'automatically_update_cart', + [ + 'label' => esc_html__( 'Automatically Update Cart', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'description' => esc_html__( 'Updates to the cart (e.g., a removed item) via Ajax. The cart will update without refreshing the whole page.', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'yes' => '--elementor-remove-from-cart-button: none; --remove-from-cart-button: block;', + '' => '--elementor-remove-from-cart-button: block; --remove-from-cart-button: none;', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_toggle_style', + [ + 'label' => esc_html__( 'Menu Icon', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'toggle_button_colors' ); + + $this->start_controls_tab( 'toggle_button_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'toggle_button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-text-color: {{VALUE}};', + ], + 'condition' => [ + 'show_subtotal!' => '', + ], + ] + ); + + $this->add_control( + 'toggle_button_icon_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-icon-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'toggle_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-border-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'toggle_button_normal_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__toggle .elementor-button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'toggle_button_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'toggle_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-hover-text-color: {{VALUE}};', + ], + 'condition' => [ + 'show_subtotal!' => '', + ], + ] + ); + + $this->add_control( + 'toggle_button_hover_icon_color', + [ + 'label' => esc_html__( 'Icon Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-icon-hover-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'toggle_button_hover_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-hover-background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'toggle_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-hover-border-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'toggle_button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__toggle .elementor-button:hover', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'toggle_button_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'separator' => 'before', + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-border-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'toggle_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-button-border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'toggle_button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__toggle .elementor-button', + 'separator' => 'before', + 'condition' => [ + 'show_subtotal!' => '', + ], + ] + ); + + $this->add_control( + 'heading_icon_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Icon', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'toggle_icon_size', + [ + 'label' => esc_html__( 'Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-icon-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'toggle_icon_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__toggle .elementor-button' => 'gap: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_subtotal!' => '', + ], + ] + ); + + $start = is_rtl() ? 'right' : 'left'; + $end = is_rtl() ? 'left' : 'right'; + + $this->add_control( + 'toggle_icon_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'row-reverse' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$start}", + ], + 'row' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-h-align-{$end}", + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__toggle .elementor-button' => 'flex-direction: {{VALUE}};', + ], + 'condition' => [ + 'show_subtotal!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'toggle_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--toggle-icon-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'items_indicator_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items Indicator', 'elementor-pro' ), + 'separator' => 'before', + 'condition' => [ + 'items_indicator!' => 'none', + ], + ] + ); + $this->add_control( + 'items_indicator_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--items-indicator-text-color: {{VALUE}};', + ], + 'condition' => [ + 'items_indicator!' => 'none', + ], + ] + ); + + $this->add_control( + 'items_indicator_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--items-indicator-background-color: {{VALUE}};', + ], + 'condition' => [ + 'items_indicator' => 'bubble', + ], + ] + ); + + $this->add_responsive_control( + 'items_indicator_distance', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'em' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}} .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]' => 'right: -{{SIZE}}{{UNIT}}; top: -{{SIZE}}{{UNIT}};', + 'body.rtl {{WRAPPER}} .elementor-menu-cart__toggle .elementor-button-icon .elementor-button-icon-qty[data-counter]' => 'right: {{SIZE}}{{UNIT}}; top: -{{SIZE}}{{UNIT}}; left: auto;', + ], + 'condition' => [ + 'items_indicator' => 'bubble', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_cart_style', + [ + 'label' => esc_html__( 'Cart', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--cart-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'none' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--cart-border-style: {{VALUE}};', + ], + 'default' => 'none', + ] + ); + + $this->add_responsive_control( + 'border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__main' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--cart-border-color: {{VALUE}};', + ], + 'condition' => [ + 'border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--cart-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'cart_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__main', + ] + ); + + $this->add_responsive_control( + 'cart_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--cart-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'heading_close', + [ + 'label' => esc_html__( 'Close Cart', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'condition' => [ + 'close_cart_button_show!' => '', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'close_cart_icon_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--cart-close-icon-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->start_controls_tabs( 'cart_icon_style' ); + + $this->start_controls_tab( + 'icon_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'close_cart_icon_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--cart-close-button-color: {{VALUE}};', + ], + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'icon_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'close_cart_icon_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--cart-close-button-hover-color: {{VALUE}};', + ], + 'condition' => [ + 'close_cart_button_show!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'heading_remove_item_button_style', + [ + 'label' => esc_html__( 'Remove Item', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'remove_item_button_size', + [ + 'label' => esc_html__( 'Icon Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--remove-item-button-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->start_controls_tabs( + 'cart_remove_item_button_style', + [ + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->start_controls_tab( + 'remove_item_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->add_control( + 'remove_item_button_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--remove-item-button-color: {{VALUE}}', + ], + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'remove_item_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->add_control( + 'remove_item_button_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--remove-item-button-hover-color: {{VALUE}};', + ], + 'condition' => [ + 'show_remove_icon!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'heading_subtotal_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Subtotal', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'subtotal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--menu-cart-subtotal-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'subtotal_typography', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__subtotal', + ] + ); + + $this->add_responsive_control( + 'subtotal_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--menu-cart-subtotal-text-align: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'subtotal_divider_style', + [ + 'label' => esc_html__( 'Divider Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}} .widget_shopping_cart_content' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + '' => '--subtotal-divider-left-width: 0; --subtotal-divider-right-width: 0;', + 'solid' => '--subtotal-divider-style: solid;', + 'double' => '--subtotal-divider-style: double;', + 'dotted' => '--subtotal-divider-style: dotted;', + 'dashed' => '--subtotal-divider-style: dashed;', + 'groove' => '--subtotal-divider-style: groove;', + ], + ] + ); + + $this->add_responsive_control( + 'subtotal_divider_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .widget_shopping_cart_content' => '--subtotal-divider-top-width: {{TOP}}{{UNIT}}; --subtotal-divider-right-width: {{RIGHT}}{{UNIT}}; --subtotal-divider-bottom-width: {{BOTTOM}}{{UNIT}}; --subtotal-divider-left-width: {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'subtotal_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .widget_shopping_cart_content' => '--subtotal-divider-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_product_tabs_style', + [ + 'label' => esc_html__( 'Products', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_product_title_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Product Title', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'product_title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__product-name a', + ] + ); + + $this->start_controls_tabs( 'product_title_colors' ); + + $this->start_controls_tab( 'product_title_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'product_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__product-name a' => 'color: {{VALUE}};', + + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'product_title_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'product_title_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__product-name a:hover' => 'color: {{VALUE}};', + + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'heading_product_variations_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'product_variations_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--product-variations-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'product_variations_typography', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__product .variation', + ] + ); + + $this->add_control( + 'heading_product_price_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Product Price', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'product_price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--product-price-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'product_price_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__product-price', + ] + ); + + $this->add_control( + 'heading_quantity_title_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'product_quantity_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__product-price .product-quantity' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'product_quantity_typography', + 'selector' => '{{WRAPPER}} .elementor-menu-cart__product-price .product-quantity', + ] + ); + + $this->add_control( + 'heading_product_divider_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + 'groove' => esc_html__( 'Groove', 'elementor-pro' ), + ], + 'selectors' => [ + '{{WRAPPER}}' => '--divider-style: {{VALUE}}; --subtotal-divider-style: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--divider-color: {{VALUE}}; --subtotal-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'divider_width', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 10, + ], + 'em' => [ + 'max' => 1, + ], + 'rem' => [ + 'max' => 1, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--divider-width: {{SIZE}}{{UNIT}}; --subtotal-divider-top-width: {{SIZE}}{{UNIT}}; --subtotal-divider-right-width: {{SIZE}}{{UNIT}}; --subtotal-divider-bottom-width: {{SIZE}}{{UNIT}}; --subtotal-divider-left-width: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'divider_gap', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--product-divider-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_buttons', + [ + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => 'view_cart_button_show', + 'operator' => '!=', + 'value' => '', + ], + [ + 'name' => 'checkout_button_show', + 'operator' => '!=', + 'value' => '', + ], + ], + ], + ] + ); + + $this->add_responsive_control( + 'buttons_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'inline' => esc_html__( 'Inline', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + ], + 'default' => 'inline', + 'devices' => [ 'desktop', 'tablet', 'mobile' ], + 'condition' => [ + 'view_cart_button_show!' => '', + 'checkout_button_show!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'inline' => '--cart-footer-layout: 1fr 1fr; --products-max-height-sidecart: calc(100vh - 240px); --products-max-height-minicart: calc(100vh - 385px)', + 'stacked' => '--cart-footer-layout: 1fr; --products-max-height-sidecart: calc(100vh - 300px); --products-max-height-minicart: calc(100vh - 450px)', + ], + ] + ); + + $this->add_responsive_control( + 'space_between_buttons', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--space-between-buttons: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'view_cart_button_show!' => '', + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'product_buttons_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__footer-buttons .elementor-button', + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--cart-footer-buttons-border-radius: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'heading_view_cart_button_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'View Cart', 'elementor-pro' ), + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'view_cart_buttons_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__footer-buttons a.elementor-button--view-cart', + 'separator' => 'before', + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->start_controls_tabs( + 'view_cart_button_text_colors', + [ + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->start_controls_tab( + 'heading_view_cart_button_normal_style', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'view_cart_button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-button-text-color: {{VALUE}};', + ], + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'view_cart_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-button-background-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'heading_view_cart_button_hover_style', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'view_cart_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-button-hover-text-color: {{VALUE}};', + ], + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'view_cart_button_hover_background', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-button-hover-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'view_cart_button_border_hover_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__footer-buttons .elementor-button--view-cart:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'view_cart_border_border!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'view_cart_border', + 'selector' => '{{WRAPPER}} .elementor-button--view-cart', + 'separator' => 'before', + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'view_cart_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__footer-buttons a.elementor-button--view-cart' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'view_cart_button_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-button--view-cart', + 'condition' => [ + 'view_cart_button_show!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'view_cart_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'view_cart_button_show!' => '', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'heading_checkout_button_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkout', 'elementor-pro' ), + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'cart_checkout_button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .elementor-menu-cart__footer-buttons a.elementor-button--checkout', + 'separator' => 'before', + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->start_controls_tabs( + 'cart_checkout_button_text_colors', + [ + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->start_controls_tab( + 'heading_cart_checkout_button_normal_style', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'checkout_button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-text-color: {{VALUE}};', + ], + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'checkout_button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-background-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'heading_cart_checkout_button_hover_style', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'checkout_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-hover-text-color: {{VALUE}};', + ], + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_control( + 'checkout_button_hover_background', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-hover-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'checkout_button_border_hover_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__footer-buttons .elementor-button--checkout:hover' => 'border-color: {{VALUE}};', + ], + 'condition' => [ + 'checkout_border_border!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'checkout_border', + 'selector' => '{{WRAPPER}} .elementor-button--checkout', + 'separator' => 'before', + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'view_checkout_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .elementor-menu-cart__footer-buttons a.elementor-button--checkout' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'view_checkout_button_box_shadow', + 'selector' => '{{WRAPPER}} .elementor-button--checkout', + 'condition' => [ + 'checkout_button_show!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'view_checkout_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--checkout-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'checkout_button_show!' => '', + ], + 'separator' => 'after', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_style_messages', + [ + 'label' => esc_html__( 'Messages', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'cart_empty_message_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}} .woocommerce-mini-cart__empty-message', + ] + ); + + $this->add_control( + 'empty_message_color', + [ + 'label' => esc_html__( 'Empty Cart Message Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--empty-message-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'empty_message_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--empty-message-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Check if user did not explicitly disabled the use of our mini-cart template and set the option accordingly. + * The option value is later used by Module::woocommerce_locate_template(). + */ + private function maybe_use_mini_cart_template() { + $option_value = get_option( 'elementor_' . Module::OPTION_NAME_USE_MINI_CART, '' ); + if ( empty( $option_value ) || 'initial' === $option_value ) { + update_option( 'elementor_' . Module::OPTION_NAME_USE_MINI_CART, 'yes' ); + } + } + + protected function render() { + $settings = $this->get_settings_for_display(); + if ( ! wp_script_is( 'wc-cart-fragments' ) ) { + wp_enqueue_script( 'wc-cart-fragments' ); + } + + $this->maybe_use_mini_cart_template(); + Module::render_menu_cart( $settings ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/my-account.php b/modules/woocommerce/widgets/my-account.php new file mode 100644 index 00000000..db5a0258 --- /dev/null +++ b/modules/woocommerce/widgets/my-account.php @@ -0,0 +1,2182 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-my-account' ]; + } + + protected function register_controls() { + $start = is_rtl() ? 'end' : 'start'; + $end = is_rtl() ? 'start' : 'end'; + + $this->start_controls_section( + 'section_menu_icon_content', + [ + 'label' => esc_html__( 'Tabs', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tabs_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'vertical' => esc_html__( 'Vertical', 'elementor-pro' ), + 'horizontal' => esc_html__( 'Horizontal', 'elementor-pro' ), + ], + 'default' => 'vertical', + 'render_type' => 'template', + 'prefix_class' => 'e-my-account-tabs-', + ] + ); + + $this->add_responsive_control( + 'tabs_content_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tab-content-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'tabs_position', + [ + 'label' => esc_html__( 'Tabs Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => "eicon-align-$start-h", + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-align-center-h', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => "eicon-align-$end-h", + ], + 'stretch' => [ + 'title' => esc_html__( 'Stretch', 'elementor-pro' ), + 'icon' => 'eicon-align-stretch-h', + ], + ], + 'condition' => [ + 'tabs_layout' => 'horizontal', + ], + 'selectors' => [ + '{{WRAPPER}}' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'start' => '--tabs-container-justify-content: flex-start; --tab-width: auto', + 'center' => '--tabs-container-justify-content: center; --tab-width: auto', + 'end' => '--tabs-container-justify-content: flex-end; --tab-width: auto', + 'stretch' => '--tabs-container-justify-content: space-between; --tab-width: 100%', + ], + ] + ); + + $repeater = new Repeater(); + + $repeater->add_control( + 'tab_name', + [ + 'label' => esc_html__( 'Tab Name', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $repeater->add_control( + 'order_display_description', + [ + 'raw' => esc_html__( 'Note: By default, only your last order is displayed while editing the orders section. You can see other orders on your live site or in the WooCommerce orders section', 'elementor-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + 'condition' => [ + 'field_key' => 'orders', + ], + ] + ); + + $this->add_control( + 'tabs', + [ + 'label' => '', + 'type' => Controls_Manager::REPEATER, + 'fields' => $repeater->get_controls(), + 'item_actions' => [ + 'add' => false, + 'duplicate' => false, + 'remove' => false, + 'sort' => false, + ], + 'default' => [ + [ + 'field_key' => 'dashboard', + 'field_label' => esc_html__( 'Dashboard', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Dashboard', 'elementor-pro' ), + ], + [ + 'field_key' => 'orders', + 'field_label' => esc_html__( 'Orders', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Orders', 'elementor-pro' ), + ], + [ + 'field_key' => 'downloads', + 'field_label' => esc_html__( 'Downloads', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Downloads', 'elementor-pro' ), + ], + [ + 'field_key' => 'edit-address', + 'field_label' => esc_html__( 'Addresses', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Addresses', 'elementor-pro' ), + ], + [ + 'field_key' => 'edit-account', + 'field_label' => esc_html__( 'Account Details', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Account Details', 'elementor-pro' ), + ], + [ + 'field_key' => 'customer-logout', + 'field_label' => esc_html__( 'Logout', 'elementor-pro' ), + 'tab_name' => esc_html__( 'Logout', 'elementor-pro' ), + ], + ], + 'title_field' => '{{{ tab_name }}}', + ] + ); + + $this->add_responsive_control( + 'tabs_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-alignment: {{VALUE}};', + ], + 'conditions' => [ + 'relation' => 'and', + 'terms' => [ + [ + 'name' => 'tabs_position', + 'operator' => '!==', + 'value' => 'start', + ], + [ + 'name' => 'tabs_position', + 'operator' => '!==', + 'value' => 'center', + ], + [ + 'name' => 'tabs_position', + 'operator' => '!==', + 'value' => 'end', + ], + ], + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Additional Options', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'customize_dashboard_check', + [ + 'label' => esc_html__( 'Customize Dashboard', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Yes', 'elementor-pro' ), + 'label_off' => esc_html__( 'No', 'elementor-pro' ), + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'customize_dashboard_description', + [ + 'raw' => sprintf( + /* translators: 1: Saved templates link opening tag. 2: Link closing tag. */ + esc_html__( 'Replaces the default WooCommerce customer dashboard screen with a custom template. (Don\'t have one? Head over to %1$sSaved Templates%2$s.)', 'elementor-pro' ), + sprintf( '', admin_url( 'edit.php?post_type=elementor_library&tabs_group=library#add_new' ) ), + '' + ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-control-field-description elementor-descriptor elementor-descriptor-subtle', + 'condition' => [ + 'customize_dashboard_check' => 'yes', + ], + ] + ); + + $this->add_control( + 'customize_dashboard_select_heading', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Choose template', 'elementor-pro' ), + 'condition' => [ + 'customize_dashboard_check' => 'yes', + ], + ] + ); + + $document_types = Plugin::elementor()->documents->get_document_types( [ + 'show_in_library' => true, + ] ); + + $this->add_control( + 'customize_dashboard_select', + [ + 'type' => QueryControlModule::QUERY_CONTROL_ID, + 'label_block' => true, + 'show_label' => false, + 'autocomplete' => [ + 'object' => QueryControlModule::QUERY_OBJECT_LIBRARY_TEMPLATE, + 'query' => [ + 'meta_query' => [ + [ + 'key' => Document::TYPE_META_KEY, + 'value' => array_keys( $document_types ), + 'compare' => 'IN', + ], + ], + ], + ], + 'condition' => [ + 'customize_dashboard_check' => 'yes', + ], + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'edit_button', + [ + 'raw' => sprintf( '%s', esc_html__( 'Edit Template', 'elementor-pro' ) ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-edit-template-wrapper', + 'condition' => [ + 'customize_dashboard_check' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'tabs_style', + [ + 'label' => esc_html__( 'Tabs', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'tabs_typography', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a', + ] + ); + + $this->start_controls_tabs( 'tabs_section' ); + + $this->start_controls_tab( 'tabs_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'tabs_normal_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:not(.is-active) a', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'tabs_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li:not(.is-active) a', + ] + ); + + $this->add_control( + 'tabs_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tabs_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'tabs_hover_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'tabs_hover_box_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a:hover', + ] + ); + + $this->add_control( + 'tabs_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-hover-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'tabs_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-hover-border-color: {{VALUE}}', + ], + 'condition' => [ + 'tabs_border_type!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tabs_active', [ 'label' => esc_html__( 'Active', 'elementor-pro' ) ] ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'tabs_active_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li.is-active a', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'tabs_active_box_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-MyAccount-navigation ul li.is-active a', + ] + ); + + $this->add_control( + 'tabs_active_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-active-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'tabs_active_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-active-border-color: {{VALUE}}', + ], + 'condition' => [ + 'tabs_border_type!' => '', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'tabs_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'tabs_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-my-account-tab .woocommerce .woocommerce-MyAccount-navigation ul li a' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'tabs_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'tabs_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-border-color: {{VALUE}};', + ], + 'condition' => [ + 'tabs_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'tabs_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'tabs_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'tabs_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'tabs_divider_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'tabs_divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-divider-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'tabs_divider_weight', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tabs-divider-weight: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'sections_title', + [ + 'label' => esc_html__( 'Sections', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'my_account_sections_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'my_account_sections_box_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab__dashboard:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper, {{WRAPPER}} .e-my-account-tab__orders .woocommerce-MyAccount-content-wrapper, {{WRAPPER}} .e-my-account-tab__downloads .woocommerce-MyAccount-content-wrapper, {{WRAPPER}} address, {{WRAPPER}} .e-my-account-tab__edit-account .woocommerce-MyAccount-content-wrapper, {{WRAPPER}} .e-my-account-tab__view-order .order_details, {{WRAPPER}} .woocommerce-form-login, {{WRAPPER}} .woocommerce-form-register, {{WRAPPER}} .woocommerce-ResetPassword, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper', + ] + ); + + $this->add_control( + 'sections_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-top-width: {{TOP}}{{UNIT}}; --sections-border-right-width: {{RIGHT}}{{UNIT}}; --sections-border-bottom-width: {{BOTTOM}}{{UNIT}}; --sections-border-left-width: {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'sections_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --edit-link-margin-top: {{TOP}}{{UNIT}}; --edit-link-margin-start: {{LEFT}}{{UNIT}};', + '{{WRAPPER}} .e-my-account-tab__edit-address .woocommerce-Address address' => 'padding-top: calc( {{TOP}}{{UNIT}} + 40px );', + '{{WRAPPER}} .woocommerce-pagination' => 'padding-bottom: {{BOTTOM}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'typography_title', + [ + 'label' => esc_html__( 'Typography', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'typography_titles', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Section Titles', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'typography_section_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--typography-section-titles-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'section_titles_typography', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) h2, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) h3', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'section_titles_typography_text_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) h2, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) h3', + ] + ); + + $this->add_responsive_control( + 'section_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--section-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'typography_secondary_titles', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'General Text', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'general_text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--general-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'general_text_typography', + 'selector' => '{{WRAPPER}} .woocommerce-MyAccount-content > div > p, {{WRAPPER}} address, {{WRAPPER}} .woocommerce-EditAccountForm fieldset legend, {{WRAPPER}} .woocommerce-ResetPassword p:nth-child(1), {{WRAPPER}} .woocommerce-OrderUpdate', + ] + ); + + $this->add_control( + 'typography_login_messages_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Login Messages', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'login_messages_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--login-messages-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'login_messages_typography', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register p:not([class]), {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce em', + ] + ); + + $this->add_control( + 'checkboxes_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Checkboxes', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'checkboxes_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--checkboxes-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'checkboxes_typography', + 'selector' => '{{WRAPPER}} .woocommerce-form__label-for-checkbox span', + ] + ); + + $this->add_control( + 'payment_methods_radio_buttons_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Radio Buttons', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'payment_methods_radio_buttons_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--payment-methods-radio-buttons-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_methods_radio_buttons_typography', + 'selector' => '{{WRAPPER}} .woocommerce-PaymentMethod .input-radio + label', + ] + ); + + $this->add_control( + 'links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Links', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'links_colors' ); + + $this->start_controls_tab( 'links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'links_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'links_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'forms_section', + [ + 'label' => esc_html__( 'Forms', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'forms_columns_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-columns-gap-padding-right: calc( {{SIZE}}{{UNIT}}/2 ); --forms-columns-gap-padding-left: calc( {{SIZE}}{{UNIT}}/2 ); --forms-columns-gap-margin-left: calc( -{{SIZE}}{{UNIT}}/2 ); --forms-columns-gap-margin-right: calc( -{{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_responsive_control( + 'forms_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-rows-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'forms_label_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Labels', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'forms_label_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-labels-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_label_typography', + 'selector' => '{{WRAPPER}} .woocommerce-form-row label, {{WRAPPER}} .woocommerce-address-fields label', + ] + ); + + $this->add_responsive_control( + 'forms_label_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-label-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'forms_field_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Fields', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_field_typography', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select, {{WRAPPER}} ::placeholder, {{WRAPPER}} .select2-container--default .select2-selection--single, .select2-results__option, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]', + + ] + ); + + $this->start_controls_tabs( 'forms_fields_styles' ); + + $this->start_controls_tab( 'forms_fields_normal_styles', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_fields_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-normal-color: {{VALUE}};', + '.e-woo-select2-wrapper .select2-results__option' => 'color: {{VALUE}};', + // style select2 arrow + '{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow b' => 'border-color: {{VALUE}} transparent transparent transparent;', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_normal_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default, .select2-results__option, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_normal_box_shadow', + 'selector' => '{{WRAPPER}} .input-text, {{WRAPPER}} select, {{WRAPPER}} .select2-container--default .select2-selection--single, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_fields_focus_styles', [ 'label' => esc_html__( 'Focus', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_fields_focus_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-color: {{VALUE}}', + '.e-woo-select2-wrapper .select2-results__option:focus' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_fields_focus_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default.select2-container--focus .select2-selection--single, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default.select2-container--focus, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]:focus', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_fields_focus_box_shadow', + 'selector' => '{{WRAPPER}} .input-text:focus, {{WRAPPER}} select:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]:focus', + ] + ); + + $this->add_control( + 'forms_fields_focus_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text:focus, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select:focus, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default.select2-container--focus, .select2-results__option:focus, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]:focus' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_fields_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'forms_fields_focus_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-focus-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'forms_fields_border', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row .input-text, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .form-row select, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default, {{WRAPPER}} .e-my-account-tab__payment-methods input[type=text]', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_fields_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_fields_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-fields-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + // style select2 + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__rendered' => 'line-height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single .select2-selection__arrow' => 'height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); right: {{RIGHT}}{{UNIT}};', + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .select2-container--default .select2-selection--single' => 'height: auto;', + ], + ] + ); + + $this->add_control( + 'forms_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'forms_button_typography', + 'selector' => '{{WRAPPER}} button.button, {{WRAPPER}} #add_payment_method #payment #place_order', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'forms_button_text_shadow', + 'selector' => '{{WRAPPER}} button.button, {{WRAPPER}} #add_payment_method #payment #place_order', + ] + ); + + $this->start_controls_tabs( 'forms_buttons_styles' ); + + $this->start_controls_tab( 'forms_buttons_normal_styles', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_buttons_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button, {{WRAPPER}} #add_payment_method #payment #place_order', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_normal_box_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button, {{WRAPPER}} button.button, {{WRAPPER}} #add_payment_method #payment #place_order', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'forms_buttons_hover_styles', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'forms_buttons_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'forms_buttons_hover_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover, {{WRAPPER}} #add_payment_method #payment #place_order:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'forms_buttons_focus_box_shadow', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover, {{WRAPPER}} button.button:hover, {{WRAPPER}} #add_payment_method #payment #place_order:hover', + ] + ); + + $this->add_control( + 'forms_buttons_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button:hover, {{WRAPPER}} #add_payment_method #payment #place_order:hover' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'forms_buttons_border_border!' => '', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'forms_buttons_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'forms_buttons_border', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-EditAccountForm .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-address-fields .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .login .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .register .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-ResetPassword .button, {{WRAPPER}} #add_payment_method #payment #place_order', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'forms_buttons_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'forms_buttons_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--forms-buttons-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'tables_section', + [ + 'label' => esc_html__( 'Order Details', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'tables_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-rows-gap-top: calc( {{SIZE}}{{UNIT}}/2 ); --order-summary-rows-gap-bottom: calc( {{SIZE}}{{UNIT}}/2 );', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'tables_titles', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tables_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'tables_titles_typography', + 'selector' => '{{WRAPPER}} .order_details thead th, {{WRAPPER}} .order_details tfoot td, {{WRAPPER}} .order_details tfoot th, {{WRAPPER}} .nobr', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'tables_titles_text_shadow', + 'selector' => '{{WRAPPER}} .order_details thead th, {{WRAPPER}} .order_details tfoot td, {{WRAPPER}} .order_details tfoot th, {{WRAPPER}} .nobr', + ] + ); + + $this->add_control( + 'tables_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tables_items_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-items-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'tables_items_typography', + 'selector' => '{{WRAPPER}} .e-my-account-tab__orders tbody td, {{WRAPPER}} .e-my-account-tab__downloads tbody td, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .product-quantity, {{WRAPPER}} .woocommerce-table--order-downloads tbody td, {{WRAPPER}} .woocommerce-table--order-details td a, {{WRAPPER}} td.product-total, {{WRAPPER}} td.payment-method-method, {{WRAPPER}} td.payment-method-expires', + ] + ); + + $this->add_control( + 'variations_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'variations_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--variations-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'variations_typography', + 'selector' => '{{WRAPPER}} .wc-item-meta', + ] + ); + + $this->add_control( + 'sections_links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Product Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'tables_links_colors' ); + + $this->start_controls_tab( 'tables_links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'tables_links_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tables_links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'tables_links_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'tables_divider_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'tables_divider_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'tables_divider_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'tables_divider_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'tables_divider_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-color: {{VALUE}};', + ], + 'condition' => [ + 'tables_divider_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'tables_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'tables_button_typography', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button, {{WRAPPER}} .woocommerce-pagination .button, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'tables_button_text_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button, {{WRAPPER}} .woocommerce-pagination .button, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button', + ] + ); + + $this->start_controls_tabs( 'tables_button_styles' ); + + $this->start_controls_tab( 'tables_button_styles_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'tables_button_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-button-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'tables_button_normal_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-pagination .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom).e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'tables_button_normal_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button, {{WRAPPER}} .woocommerce-pagination .button, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'tables_button_styles_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'tables_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .woocommerce-pagination .button:hover, {{WRAPPER}} .order-again .button:hover, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce .woocommerce-MyAccount-content-wrapper .button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'tables_button_hover_background', + 'selector' => '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-pagination .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom).e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'tables_button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover, {{WRAPPER}} .woocommerce-pagination .button:hover, {{WRAPPER}} .e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button:hover', + ] + ); + + $this->add_control( + 'tables_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button:hover, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce-pagination .button:hover, {{WRAPPER}} .e-my-account-tab__payment-methods:not(.e-my-account-tab__dashboard--custom) .woocommerce-MyAccount-content-wrapper .button:hover' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'tables_button_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'tables_button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tables-button-hover-transition-duration: {{SIZE}}ms', + ], + ] + ); + + $this->add_control( + 'tables_button_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'tables_button_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--tables-buttons-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'tables_button_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .shop_table .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .order-again .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom) .woocommerce .woocommerce-pagination .button, {{WRAPPER}} .e-my-account-tab:not(.e-my-account-tab__dashboard--custom).e-my-account-tab__payment-methods .woocommerce-MyAccount-content-wrapper .button' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'tables_button_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'tables_button_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--tables-buttons-border-color: {{VALUE}};', + ], + 'condition' => [ + 'tables_button_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'tables_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tables-button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'tables_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--tables-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + public function modify_menu_items( $items, $endpoints ) { + $settings = $this->get_settings_for_display(); + + if ( ! empty( $settings['tabs'] ) ) { + foreach ( $settings['tabs'] as $tab ) { + if ( isset( $tab['tab_name'] ) && isset( $items[ $tab['field_key'] ] ) ) { + $items[ $tab['field_key'] ] = $tab['tab_name']; + } + } + } + + return $items; + } + + /** + * WooCommerce Get My Account Page Permalink + * + * Modify the permalinks of the My Account menu items. By default the permalinks will go to the + * set WooCommerce My Account Page, even if the widget is on a different page. This function will override + * the permalinks to use the widget page URL as the base URL instead. + * + * This is a callback function for the woocommerce_get_myaccount_page_permalink filter. + * + * @since 3.5.0 + * + * @return string + */ + public function woocommerce_get_myaccount_page_permalink( $bool ) { + return get_permalink(); + } + + /** + * WooCommerce Logout Default Redirect URL + * + * Modify the permalink of the My Account Logout menu item. We add this so that we can add custom + * parameters to the URL, which we can later access to log the user out and redirect back to the widget + * page. Without this WooCommerce would have always just redirect back to the set My Account Page + * after log out. + * + * This is a callback function for the woocommerce_logout_default_redirect_url filter. + * + * @since 3.5.0 + * + * @return string + */ + public function woocommerce_logout_default_redirect_url( $redirect ) { + return $redirect . '?elementor_wc_logout=true&elementor_my_account_redirect=' . esc_url( get_permalink() ); + } + + protected function render() { + // Add actions & filters before displaying our Widget. + add_action( 'woocommerce_account_navigation', [ $this, 'woocommerce_account_navigation' ], 1 ); + add_filter( 'woocommerce_account_menu_items', [ $this, 'modify_menu_items' ], 10, 2 ); + add_action( 'woocommerce_account_content', [ $this, 'before_account_content' ], 2 ); + add_action( 'woocommerce_account_content', [ $this, 'after_account_content' ], 95 ); + add_filter( 'woocommerce_get_myaccount_page_permalink', [ $this, 'woocommerce_get_myaccount_page_permalink' ], 10, 1 ); + add_filter( 'woocommerce_logout_default_redirect_url', [ $this, 'woocommerce_logout_default_redirect_url' ], 10, 1 ); + add_filter( 'woocommerce_is_account_page', '__return_true' ); + + if ( $this->has_custom_template() && 'dashboard' === $this->get_current_endpoint() ) { + remove_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 ); + add_action( 'woocommerce_account_content', [ $this, 'display_custom_template' ], 10 ); + } + + // Display our Widget. + if ( ! Plugin::elementor()->editor->is_edit_mode() ) { + $this->render_html_front_end(); + } else { + $this->render_html_editor(); + } + + // Remove actions & filters after displaying our Widget. + remove_action( 'woocommerce_account_navigation', [ $this, 'woocommerce_account_navigation' ], 2 ); + remove_action( 'woocommerce_account_menu_items', [ $this, 'modify_menu_items' ], 10 ); + remove_action( 'woocommerce_account_content', [ $this, 'before_account_content' ], 5 ); + remove_action( 'woocommerce_account_content', [ $this, 'after_account_content' ], 99 ); + remove_filter( 'woocommerce_get_myaccount_page_permalink', [ $this, 'woocommerce_get_myaccount_page_permalink' ], 10, 1 ); + remove_filter( 'woocommerce_logout_default_redirect_url', [ $this, 'woocommerce_logout_default_redirect_url' ], 10, 1 ); + remove_filter( 'woocommerce_is_account_page', '__return_true' ); + + if ( $this->has_custom_template() && 'dashboard' === $this->get_current_endpoint() ) { + remove_action( 'woocommerce_account_content', [ $this, 'display_custom_template' ], 10 ); + add_action( 'woocommerce_account_content', 'woocommerce_account_content', 10 ); + } + } + + /** + * Get Account Pages + * + * Get all the pages that would render on the My Account page. + * We will use this array to be able to render all these pages' content when the editor loads. + * We will then switch between the pages via JS as all the content is already on the page. + * + * @since 3.5.0 + * + * @return array + */ + private function get_account_pages() { + $pages = [ + 'dashboard' => '', + 'orders' => '', + 'downloads' => '', + 'edit-address' => '', + ]; + + // Check if payment gateways support add new payment methods. + $support_payment_methods = false; + foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway ) { + if ( $gateway->supports( 'add_payment_method' ) || $gateway->supports( 'tokenization' ) ) { + $support_payment_methods = true; + break; + } + } + + if ( $support_payment_methods ) { + $pages['payment-methods'] = ''; + $pages['add-payment-method'] = ''; + } + + // Edit account. + $pages['edit-account'] = ''; + + // Get the latest order (if there is one) for view-order (order preview) page. + $recent_order = wc_get_orders( [ + 'limit' => 1, + 'orderby' => 'date', + 'order' => 'DESC', + ] ); + + if ( ! empty( $recent_order ) ) { + $pages['view-order'] = $recent_order[0]->get_id(); + } + + return $pages; + } + + /** + * Get Current Endpoint + * + * Used to determine which page Account Page the user is on currently. + * This is used so we can add a unique wrapper class around the page's content. + * + * @since 3.5.0 + * + * @return string + */ + private function get_current_endpoint() { + global $wp_query; + $current = ''; + + $pages = $this->get_account_pages(); + + foreach ( $pages as $page => $val ) { + if ( isset( $wp_query->query[ $page ] ) ) { + $current = $page; + break; + } + } + + if ( '' === $current && isset( $wp_query->query_vars['page'] ) ) { + $current = 'dashboard'; // Dashboard is not an endpoint so it needs a custom check. + } + + return $current; + } + + /** + * Render HTML Front End + * + * This function will output the content on the front-end. + * + * @since 3.5.0 + */ + private function render_html_front_end() { + $current_endpoint = $this->get_current_endpoint(); + $custom_dashboard_class = ''; + if ( 'dashboard' === $current_endpoint && $this->has_custom_template() && is_user_logged_in() ) { + $custom_dashboard_class = 'e-my-account-tab__dashboard--custom'; + } + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo ' + get_settings_for_display(); + // Add .e-my-account-tab__dashboard as the default class when the editor loads. + // This class will be replaced with JS when tabs are switched. + + $custom_dashboard_class = ''; + if ( $this->has_custom_template() && is_user_logged_in() ) { + $custom_dashboard_class = 'e-my-account-tab__dashboard--custom'; + } + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo ' + get_settings_for_display(); + + if ( 'horizontal' === $settings['tabs_layout'] ) { + ?> + + get_dashboard_template_id() ); + + return 0 < $template_id; + } + + /** + * Get Account Content Wrapper + * + * This function will determine the wrapper class around the main content. + * There are different wrappers depending on the following scenarios: + * 1. Are there orders/downloads or not. + * 2. A custom template been selected for the dashboard intro or not + * + * @since 3.5.0 + * + * @return string + */ + private function get_account_content_wrapper( $args ) { + $user_id = get_current_user_id(); + $num_orders = wc_get_customer_order_count( $user_id ); + $num_downloads = count( wc_get_customer_available_downloads( $user_id ) ); + $class = 'woocommerce-MyAccount-content-wrapper'; + $current_endpoint = $this->get_current_endpoint(); + + /* we need to render a different css class if there are no orders/downloads to display + * as the no orders/downloads screen should not have the default padding and border + * around it but show the 'no orders/downloads' notification only + */ + if ( 'frontend' === $args['context'] ) { // Front-end display + global $wp_query; + if ( ( 0 === $num_orders && isset( $wp_query->query_vars['orders'] ) ) || ( 0 === $num_downloads && isset( $wp_query->query_vars['downloads'] ) ) ) { + $class .= '-no-data'; + } + } else { // Editor display + if ( ( 0 === $num_orders && 'orders' === $args['page'] ) || ( 0 === $num_downloads && 'downloads' === $args['page'] ) ) { + $class .= '-no-data'; + } + } + + return $class; + } + + /** + * Before Account Content + * + * Output containing elements. Callback function for the woocommerce_account_content hook. + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function before_account_content() { + $wrapper_class = $this->get_account_content_wrapper( [ 'context' => 'frontend' ] ); + + echo '
          '; + } + + /** + * Get Dashboard Template ID + * + * Get the template_id for the dashboard intro section if a custom template should be displayed + * + * @since 3.7.0 + * + * @return int + */ + public function get_dashboard_template_id() { + $settings = $this->get_settings_for_display(); + if ( 'yes' === $settings['customize_dashboard_check'] ) { + $template_id = intval( $settings['customize_dashboard_select'] ); + } else { + $template_id = 0; + } + + return $template_id; + } + + /** + * Display a custom template inside the My Account dashboard section + * + * @since 3.7.0 + */ + public function display_custom_template() { + $template_id = intval( $this->get_dashboard_template_id() ); + + if ( 0 < $template_id ) { + echo do_shortcode( '[elementor-template id="' . $template_id . '"]' ); + + do_action( 'woocommerce_account_dashboard' ); + do_action( 'woocommerce_before_my_account' ); + do_action( 'woocommerce_after_my_account' ); + } + } + + /** + * After Account Content + * + * Output containing elements. Callback function for the woocommerce_account_content hook. + * + * This eliminates the need for template overrides. + * + * @since 3.5.0 + */ + public function after_account_content() { + echo '
          '; + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/notices.php b/modules/woocommerce/widgets/notices.php new file mode 100644 index 00000000..293561ac --- /dev/null +++ b/modules/woocommerce/widgets/notices.php @@ -0,0 +1,147 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + public function get_help_url() { + return 'https://go.elementor.com/widget-woocommerce-notices-location'; + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-notices' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section', + [ + 'label' => esc_html__( 'WooCommerce Notices', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'where_to_appear_notice', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => esc_html__( 'Drop this widget anywhere on the page or template where you want notices to appear.', 'elementor-pro' ), + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->add_control( + 'site_settings_notice', + [ + 'type' => Controls_Manager::RAW_HTML, + 'raw' => sprintf( + /* translators: 1: Link opening tag, 2: Link closing tag. */ + esc_html__( 'To change the design of your notices, go to your %1$sWooCommerce Settings%2$s', 'elementor-pro' ), + '', + '' + ), + 'content_classes' => 'elementor-descriptor elementor-descriptor-subtle', + ] + ); + + $this->add_control( + 'one_per_page_notice', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'heading' => esc_html__( 'Note:', 'elementor-pro' ), + 'content' => esc_html__( 'You can only add the Notices widget once per page.', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + } + + private function hide_woocommerce_notices() { + ?> + + editor->is_edit_mode() || Plugin::elementor()->preview->is_preview_mode() ) { + $this->render_demo_notice(); + } else { + $this->hide_woocommerce_notices(); + ?> +
          + +
          + +
          + [ + '0' => [ + 'notice' => esc_html__( 'This is an example of a WooCommerce notice. (You won\'t see this while previewing your site.)', 'elementor-pro' ), + 'data' => [], + ], + ], + ] ); + ?> +
          + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-add-to-cart' ]; + } + + protected function render() { + global $product; + + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + add_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 ); + add_action( 'woocommerce_before_add_to_cart_button', [ $this, 'before_add_to_cart_quantity' ], 5 ); + add_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 ); + ?> + +
          + is_loop_item() ) { + $this->render_loop_add_to_cart(); + } else { + woocommerce_template_single_add_to_cart(); + } ?> +
          + + get_loop_quantity_args(); + $button_args = [ 'quantity' => $quantity_args['min_value'] ]; + ?> +
          +
          + before_add_to_cart_quantity(); + + $this->render_loop_quantity_input( $quantity_args ); + woocommerce_template_loop_add_to_cart( $button_args ); + + $this->after_add_to_cart_button(); + ?> +
          +
          + get_type() + && 'yes' === $this->get_settings_for_display( 'show_quantity' ) + ) { + woocommerce_quantity_input( $quantity_args ); + } + } + + private function get_loop_quantity_args() { + global $product; + + $quantity_args = [ + 'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ), + 'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ), + 'input_value' => $product->get_min_purchase_quantity(), + 'classes' => [ 'input-text', 'qty', 'text' ], + ]; + + if ( 'no' === get_option( 'woocommerce_enable_ajax_add_to_cart' ) ) { + $quantity_args['min_value'] = $product->get_min_purchase_quantity(); + $quantity_args['input_value'] = $product->get_min_purchase_quantity(); + $quantity_args['classes'][] = 'disabled'; + } + + return $quantity_args; + } + + private function is_loop_item() { + return 'loop-item' === Plugin::elementor()->documents->get_current()->get_type(); + } + + private function is_loop_item_template_edit() { + return ( Plugin::elementor()->editor->is_edit_mode() && $this->is_loop_item() ); + } + + public function should_add_container() { + global $product; + + if ( ! in_array( $this->get_settings_for_display( 'layout' ), [ 'auto', 'stacked' ], true ) ) { + return false; + } + + switch ( current_action() ) { + case 'woocommerce_before_add_to_cart_quantity': + return in_array( $product->get_type(), [ 'simple', 'variable' ], true ); + case 'woocommerce_before_add_to_cart_button': + return in_array( $product->get_type(), [ 'grouped', 'external' ], true ); + case 'woocommerce_after_add_to_cart_button': + default: + return true; + } + } + + /** + * Before Add to Cart Quantity + * + * Added wrapper tag around the quantity input and "Add to Cart" button + * used to more solidly accommodate the layout when additional elements + * are added by 3rd party plugins. + * + * @since 3.6.0 + */ + public function before_add_to_cart_quantity() { + if ( ! $this->should_add_container() ) { + return; + } + ?> +
          + should_add_container() ) { + return; + } + ?> +
          + start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->maybe_add_send_app_promotion_control( $this ); + + $this->add_control( + 'layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Inline', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + 'auto' => esc_html__( 'Auto', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-add-to-cart--layout-', + 'render_type' => 'template', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_atc_button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'prefix_class' => 'elementor-add-to-cart%s--align-', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'button_border', + 'selector' => '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button', + 'exclude' => [ 'color' ], + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->start_controls_tabs( 'button_style_tabs' ); + + $this->start_controls_tab( 'button_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'button_style_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color_hover', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_bg_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_border_color_hover', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'button_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (s)', + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 0.2, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'transition: all {{SIZE}}s', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'heading_view_cart_style', + [ + 'label' => esc_html__( 'View Cart', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'view_cart_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .added_to_cart' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'view_cart_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}} .added_to_cart', + ] + ); + + $this->add_responsive_control( + 'view_cart_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--view-cart-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_atc_quantity_style', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'show_quantity', + [ + 'label' => esc_html__( 'Quantity', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'return_value' => 'yes', + 'default' => 'yes', + 'prefix_class' => 'e-add-to-cart--show-quantity-', + 'render_type' => 'template', + ] + ); + + $this->add_responsive_control( + 'spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--button-spacing: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'quantity_typography', + 'selector' => '{{WRAPPER}} .quantity .qty', + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'quantity_border', + 'selector' => '{{WRAPPER}} .quantity .qty', + 'exclude' => [ 'color' ], + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->add_control( + 'quantity_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->add_control( + 'quantity_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->start_controls_tabs( 'quantity_style_tabs', + [ + 'condition' => [ + 'show_quantity!' => '', + ], + ] + ); + + $this->start_controls_tab( 'quantity_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'quantity_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'quantity_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'quantity_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'quantity_style_focus', + [ + 'label' => esc_html__( 'Focus', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'quantity_text_color_focus', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty:focus' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'quantity_bg_color_focus', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty:focus' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'quantity_border_color_focus', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .quantity .qty:focus' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'quantity_transition', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (s)', + 'type' => Controls_Manager::SLIDER, + 'default' => [ + 'size' => 0.2, + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3, + 'step' => 0.1, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .quantity .qty' => 'transition: all {{SIZE}}s', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_atc_variations_style', + [ + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'variations_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart .variations' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'variations_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart .variations' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'variations_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations tr th, .woocommerce {{WRAPPER}} form.cart table.variations tr td' => 'padding-top: calc( {{SIZE}}{{UNIT}}/2 ); padding-bottom: calc( {{SIZE}}{{UNIT}}/2 );', + ], + ] + ); + + $this->add_control( + 'heading_variations_label_style', + [ + 'label' => esc_html__( 'Label', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'variations_label_color_focus', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations label' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'variations_label_typography', + 'selector' => '.woocommerce {{WRAPPER}} form.cart table.variations label', + ] + ); + + $this->add_control( + 'heading_variations_select_style', + [ + 'label' => esc_html__( 'Select field', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'variations_select_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations td.value select' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'variations_select_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'variations_select_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'border: 1px solid {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'variations_select_typography', + 'selector' => '.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce div.product.elementor{{WRAPPER}} form.cart table.variations td.value:before', + ] + ); + + $this->add_control( + 'variations_select_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-additional-information.php b/modules/woocommerce/widgets/product-additional-information.php new file mode 100644 index 00000000..1112f954 --- /dev/null +++ b/modules/woocommerce/widgets/product-additional-information.php @@ -0,0 +1,129 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-additional-information' ]; + } + + protected function register_controls() { + + $this->start_controls_section( 'section_additional_info_style', [ + 'label' => esc_html__( 'General', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] ); + + $this->add_control( + 'show_heading', + [ + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'render_type' => 'ui', + 'return_value' => 'yes', + 'default' => 'yes', + 'prefix_class' => 'elementor-show-heading-', + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} h2' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'selector' => '.woocommerce {{WRAPPER}} h2', + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_control( + 'content_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .shop_attributes' => 'color: {{VALUE}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_typography', + 'selector' => '.woocommerce {{WRAPPER}} .shop_attributes', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + global $product; + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + wc_get_template( 'single-product/tabs/additional-information.php' ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-content.php b/modules/woocommerce/widgets/product-content.php new file mode 100644 index 00000000..cc2d9817 --- /dev/null +++ b/modules/woocommerce/widgets/product-content.php @@ -0,0 +1,36 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } +} diff --git a/modules/woocommerce/widgets/product-data-tabs.php b/modules/woocommerce/widgets/product-data-tabs.php new file mode 100644 index 00000000..aa72d959 --- /dev/null +++ b/modules/woocommerce/widgets/product-data-tabs.php @@ -0,0 +1,303 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-data-tabs' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_tabs_style', + [ + 'label' => esc_html__( 'Tabs', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'tabs_style' ); + + $this->start_controls_tab( 'normal_tabs_style', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'tab_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li a' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'tab_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'alpha' => false, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'tabs_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel' => 'border-color: {{VALUE}}', + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'active_tabs_style', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'active_tab_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li.active a' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'active_tab_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'alpha' => false, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel, .woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li.active' => 'background-color: {{VALUE}}', + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li.active' => 'border-bottom-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'active_tabs_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel' => 'border-color: {{VALUE}}', + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li.active' => 'border-color: {{VALUE}} {{VALUE}} {{active_tab_bg_color.VALUE}} {{VALUE}}', + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li:not(.active)' => 'border-bottom-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'tab_typography', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li a', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'tab_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs li' => 'border-radius: {{SIZE}}{{UNIT}} {{SIZE}}{{UNIT}} 0 0', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_product_panel_style', + [ + 'label' => esc_html__( 'Panel', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-Tabs-panel' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_typography', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel', + ] + ); + + $this->add_control( + 'heading_panel_heading_style', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-Tabs-panel h2' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'content_heading_typography', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel h2', + ] + ); + + $this->add_control( + 'panel_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; margin-top: -{{TOP}}{{UNIT}}', + ], + 'separator' => 'before', + ] + ); + + $this->add_control( + 'panel_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + '.woocommerce {{WRAPPER}} .woocommerce-tabs ul.wc-tabs' => 'margin-left: {{TOP}}{{UNIT}}; margin-right: {{RIGHT}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'panel_box_shadow', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-tabs .woocommerce-Tabs-panel', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + global $product; + + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + setup_postdata( $product->get_id() ); + + wc_get_template( 'single-product/tabs/tabs.php' ); + + // On render widget from Editor - trigger the init manually. + if ( wp_doing_ajax() ) { + ?> + + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-images' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_gallery_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'sale_flash', + [ + 'label' => esc_html__( 'Sale Flash', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'render_type' => 'template', + 'return_value' => 'yes', + 'default' => 'yes', + 'prefix_class' => '', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'image_border', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-product-gallery__trigger + .woocommerce-product-gallery__wrapper, + .woocommerce {{WRAPPER}} .flex-viewport, .woocommerce {{WRAPPER}} .flex-control-thumbs img', + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-product-gallery__trigger + .woocommerce-product-gallery__wrapper, + .woocommerce {{WRAPPER}} .flex-viewport' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .flex-viewport:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_thumbs_style', + [ + 'label' => esc_html__( 'Thumbnails', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'thumbs_border', + 'selector' => '.woocommerce {{WRAPPER}} .flex-control-thumbs img', + ] + ); + + $this->add_responsive_control( + 'thumbs_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .flex-control-thumbs img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'spacing_thumbs', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .flex-control-thumbs li' => 'padding-right: calc({{SIZE}}{{UNIT}} / 2); padding-left: calc({{SIZE}}{{UNIT}} / 2); padding-bottom: {{SIZE}}{{UNIT}}', + '.woocommerce {{WRAPPER}} .flex-control-thumbs' => 'margin-right: calc(-{{SIZE}}{{UNIT}} / 2); margin-left: calc(-{{SIZE}}{{UNIT}} / 2)', + ], + ] + ); + + $this->end_controls_section(); + } + + public function render() { + global $product; + + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + $settings = $this->get_settings_for_display(); + + $is_library_preview = Utils::_unstable_get_super_global_value( $_GET, 'elementor_library' ) + && Utils::_unstable_get_super_global_value( $_GET, 'preview_id' ); + + if ( $is_library_preview ) { + // We need to enqueue these scripts manually on the Library preview. + $this->load_assets_dependencies(); + } + + if ( 'yes' === $settings['sale_flash'] ) { + wc_get_template( 'loop/sale-flash.php' ); + } + wc_get_template( 'single-product/product-image.php' ); + + // On render widget from Editor - trigger the init manually. + if ( Plugin::elementor()->editor->is_edit_mode() ) { + ?> + + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-meta' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_meta_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'view', + [ + 'label' => esc_html__( 'View', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'inline', + 'options' => [ + 'table' => esc_html__( 'Table', 'elementor-pro' ), + 'stacked' => esc_html__( 'Stacked', 'elementor-pro' ), + 'inline' => esc_html__( 'Inline', 'elementor-pro' ), + ], + 'prefix_class' => 'elementor-woo-meta--view-', + ] + ); + + $this->add_responsive_control( + 'space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child)' => 'padding-bottom: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:first-child)' => 'margin-top: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container' => 'margin-right: calc({{SIZE}}{{UNIT}}/2); margin-left: calc({{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta' => 'margin-right: calc(-{{SIZE}}{{UNIT}}/2); margin-left: calc(-{{SIZE}}{{UNIT}}/2)', + 'body:not(.rtl) {{WRAPPER}}.elementor-woo-meta--view-inline .detail-container:after' => 'right: calc( (-{{SIZE}}{{UNIT}}/2) + (-{{divider_weight.SIZE}}px/2) )', + 'body:not.rtl {{WRAPPER}}.elementor-woo-meta--view-inline .detail-container:after' => 'left: calc( (-{{SIZE}}{{UNIT}}/2) - ({{divider_weight.SIZE}}px/2) )', + ], + ] + ); + + $this->add_control( + 'divider', + [ + 'label' => esc_html__( 'Divider', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Off', 'elementor-pro' ), + 'label_on' => esc_html__( 'On', 'elementor-pro' ), + 'selectors' => [ + '{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'content: ""', + ], + 'return_value' => 'yes', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'divider_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'solid' => esc_html__( 'Solid', 'elementor-pro' ), + 'double' => esc_html__( 'Double', 'elementor-pro' ), + 'dotted' => esc_html__( 'Dotted', 'elementor-pro' ), + 'dashed' => esc_html__( 'Dashed', 'elementor-pro' ), + ], + 'default' => 'solid', + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child):after' => 'border-top-style: {{VALUE}}', + '{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container:not(:last-child):after' => 'border-left-style: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'divider_weight', + [ + 'label' => esc_html__( 'Weight', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 1, + ], + 'range' => [ + 'px' => [ + 'min' => 1, + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child):after' => 'border-top-width: {{SIZE}}{{UNIT}}; margin-bottom: calc(-{{SIZE}}{{UNIT}}/2)', + '{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container:not(:last-child):after' => 'border-left-width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'divider_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'condition' => [ + 'divider' => 'yes', + 'view!' => 'inline', + ], + 'selectors' => [ + '{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'width: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'divider_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'custom' ], + 'default' => [ + 'unit' => '%', + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'condition' => [ + 'divider' => 'yes', + 'view' => 'inline', + ], + 'selectors' => [ + '{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'height: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'divider_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '#ddd', + 'global' => [ + 'default' => Global_Colors::COLOR_TEXT, + ], + 'condition' => [ + 'divider' => 'yes', + ], + 'selectors' => [ + '{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_text_style', + [ + 'label' => esc_html__( 'Text', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '{{WRAPPER}}', + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_link_style', + [ + 'label' => esc_html__( 'Link', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'link_typography', + 'selector' => '{{WRAPPER}} a', + ] + ); + + $this->add_control( + 'link_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} a' => 'color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_product_meta_captions', + [ + 'label' => esc_html__( 'Captions', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'heading_category_caption', + [ + 'label' => esc_html__( 'Category', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'category_caption_single', + [ + 'label' => esc_html__( 'Singular', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'Category', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'category_caption_plural', + [ + 'label' => esc_html__( 'Plural', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'Categories', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'heading_tag_caption', + [ + 'label' => esc_html__( 'Tag', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'tag_caption_single', + [ + 'label' => esc_html__( 'Singular', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'Tag', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'tag_caption_plural', + [ + 'label' => esc_html__( 'Plural', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'Tags', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + ] + ); + + $this->add_control( + 'heading_sku_caption', + [ + 'label' => esc_html__( 'SKU', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sku_caption', + [ + 'label' => esc_html__( 'SKU', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'SKU', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->add_control( + 'sku_missing_caption', + [ + 'label' => esc_html__( 'Missing', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'placeholder' => esc_html__( 'N/A', 'elementor-pro' ), + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + ] + ); + + $this->end_controls_section(); + } + + private function get_plural_or_single( $single, $plural, $count ) { + return 1 === $count ? $single : $plural; + } + + protected function render() { + global $product; + + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + $sku = esc_html( $product->get_sku() ); + + $settings = $this->get_settings_for_display(); + $sku_caption = ! empty( $settings['sku_caption'] ) ? esc_html( $settings['sku_caption'] ) : esc_html__( 'SKU', 'elementor-pro' ); + $sku_missing = ! empty( $settings['sku_missing_caption'] ) ? esc_html( $settings['sku_missing_caption'] ) : esc_html__( 'N/A', 'elementor-pro' ); + $category_caption_single = ! empty( $settings['category_caption_single'] ) ? $settings['category_caption_single'] : esc_html__( 'Category', 'elementor-pro' ); + $category_caption_plural = ! empty( $settings['category_caption_plural'] ) ? $settings['category_caption_plural'] : esc_html__( 'Categories', 'elementor-pro' ); + $tag_caption_single = ! empty( $settings['tag_caption_single'] ) ? $settings['tag_caption_single'] : esc_html__( 'Tag', 'elementor-pro' ); + $tag_caption_plural = ! empty( $settings['tag_caption_plural'] ) ? $settings['tag_caption_plural'] : esc_html__( 'Tags', 'elementor-pro' ); + ?> +
          + + + + is_type( 'variable' ) ) ) : ?> + + + + + + + + + + + + + get_category_ids() ) ) : ?> + get_plural_or_single( $category_caption_single, $category_caption_plural, count( $product->get_category_ids() ) ) ); ?> get_id(), 'product_cat', '', ', ' ); ?> + + + get_tag_ids() ) ) : ?> + get_plural_or_single( $tag_caption_single, $tag_caption_plural, count( $product->get_tag_ids() ) ) ); ?> get_id(), 'product_tag', '', ', ' ); ?> + + + + +
          + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-price' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_price_style', + [ + 'label' => esc_html__( 'Price', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'text_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .price' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '.woocommerce {{WRAPPER}} .price', + ] + ); + + $this->add_control( + 'sale_heading', + [ + 'label' => esc_html__( 'Sale Price', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'sale_price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .price ins' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'sale_price_typography', + 'selector' => '.woocommerce {{WRAPPER}} .price ins', + ] + ); + + $this->add_control( + 'price_block', + [ + 'label' => esc_html__( 'Stacked', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'return_value' => 'yes', + 'prefix_class' => 'elementor-product-price-block-', + ] + ); + + $this->add_responsive_control( + 'sale_price_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + 'body:not(.rtl) {{WRAPPER}}:not(.elementor-product-price-block-yes) del' => 'margin-right: {{SIZE}}{{UNIT}}', + 'body.rtl {{WRAPPER}}:not(.elementor-product-price-block-yes) del' => 'margin-left: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-product-price-block-yes del' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + global $product; + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + wc_get_template( '/single-product/price.php' ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-rating.php b/modules/woocommerce/widgets/product-rating.php new file mode 100644 index 00000000..77ab5e89 --- /dev/null +++ b/modules/woocommerce/widgets/product-rating.php @@ -0,0 +1,211 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-product-rating' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_rating_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'star_color', + [ + 'label' => esc_html__( 'Star Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .star-rating' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'empty_star_color', + [ + 'label' => esc_html__( 'Empty Star Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .star-rating::before' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'link_color', + [ + 'label' => esc_html__( 'Link Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-review-link' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-review-link', + ] + ); + + $this->add_control( + 'star_size', + [ + 'label' => esc_html__( 'Star Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'unit' => 'em', + ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}} .star-rating' => 'font-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'unit' => 'em', + ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '.woocommerce:not(.rtl) {{WRAPPER}} .star-rating' => 'margin-right: {{SIZE}}{{UNIT}}', + '.woocommerce.rtl {{WRAPPER}} .star-rating' => 'margin-left: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'prefix_class' => 'elementor-product-rating--align-', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + if ( ! post_type_supports( 'product', 'comments' ) ) { + return; + } + + global $product; + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + wc_get_template( 'single-product/rating.php' ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-related.php b/modules/woocommerce/widgets/product-related.php new file mode 100644 index 00000000..5b26f030 --- /dev/null +++ b/modules/woocommerce/widgets/product-related.php @@ -0,0 +1,276 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-products' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_related_products_content', + [ + 'label' => esc_html__( 'Related Products', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Products Per Page', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 4, + 'range' => [ + 'px' => [ + 'max' => 20, + ], + ], + ] + ); + + $this->add_columns_responsive_control(); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'date', + 'options' => [ + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'price' => esc_html__( 'Price', 'elementor-pro' ), + 'popularity' => esc_html__( 'Popularity', 'elementor-pro' ), + 'rating' => esc_html__( 'Rating', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'section_design_box', + ] ); + + $this->start_controls_section( + 'section_heading_style', + [ + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'show_heading', + [ + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'return_value' => 'yes', + 'prefix_class' => 'show-heading-', + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2', + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'heading_text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'text-align: {{VALUE}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'heading_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + } + + protected function render() { + global $product; + + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + $settings = $this->get_settings_for_display(); + + // Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected. + if ( 'yes' === $settings['automatically_align_buttons'] ) { + add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 ); + } + + $args = [ + 'posts_per_page' => 4, + 'columns' => 4, + 'orderby' => $settings['orderby'], + 'order' => $settings['order'], + ]; + + if ( ! empty( $settings['posts_per_page'] ) ) { + $args['posts_per_page'] = $settings['posts_per_page']; + } + + if ( ! empty( $settings['columns'] ) ) { + $args['columns'] = $settings['columns']; + } + + $args = array_map( 'sanitize_text_field', $args ); + + // Get visible related products then sort them at random. + $args['related_products'] = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' ); + + // Handle orderby. + $args['related_products'] = wc_products_array_orderby( $args['related_products'], $args['orderby'], $args['order'] ); + + ob_start(); + + wc_get_template( 'single-product/related.php', $args ); + + $related_products_html = ob_get_clean(); + + if ( $related_products_html ) { + $related_products_html = str_replace( '
            experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_description_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'text_align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + 'justify' => [ + 'title' => esc_html__( 'Justified', 'elementor-pro' ), + 'icon' => 'eicon-text-align-justify', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .woocommerce-product-details__short-description' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '.woocommerce {{WRAPPER}} .woocommerce-product-details__short-description', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + global $product; + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + wc_get_template( 'single-product/short-description.php' ); + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-stock.php b/modules/woocommerce/widgets/product-stock.php new file mode 100644 index 00000000..05c4db78 --- /dev/null +++ b/modules/woocommerce/widgets/product-stock.php @@ -0,0 +1,92 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_product_stock_style', + [ + 'label' => esc_html__( 'Style', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '.woocommerce {{WRAPPER}} .stock' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'text_typography', + 'selector' => '.woocommerce {{WRAPPER}} .stock', + ] + ); + + $this->end_controls_section(); + } + + protected function render() { + global $product; + $product = $this->get_product(); + + if ( ! $product ) { + return; + } + + // PHPCS - the method wc_get_stock_html is safe. + echo wc_get_stock_html( $product ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/product-title.php b/modules/woocommerce/widgets/product-title.php new file mode 100644 index 00000000..7fa0c355 --- /dev/null +++ b/modules/woocommerce/widgets/product-title.php @@ -0,0 +1,92 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + protected function register_controls() { + parent::register_controls(); + + $this->update_control( + 'title', + [ + 'dynamic' => [ + 'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'woocommerce-product-title-tag' ), + ], + ], + [ + 'recursive' => true, + ] + ); + + $this->update_control( + 'header_size', + [ + 'default' => 'h1', + ] + ); + } + + protected function get_html_wrapper_class() { + return parent::get_html_wrapper_class() . ' elementor-page-title elementor-widget-' . parent::get_name(); + } + + protected function render() { + $this->add_render_attribute( 'title', 'class', [ 'product_title', 'entry-title' ] ); + parent::render(); + } + + /** + * Render Woocommerce Product Title output in the editor. + * + * Written as a Backbone JavaScript template and used to generate the live preview. + * + * @since 2.9.0 + * @access protected + */ + protected function content_template() { + ?> + <# view.addRenderAttribute( 'title', 'class', [ 'product_title', 'entry-title' ] ); #> + experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-products' ]; + } + + protected function register_controls() { + + $this->start_controls_section( + 'section_upsell_content', + [ + 'label' => esc_html__( 'Upsells', 'elementor-pro' ), + ] + ); + + $this->add_columns_responsive_control(); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'date', + 'options' => [ + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'price' => esc_html__( 'Price', 'elementor-pro' ), + 'popularity' => esc_html__( 'Popularity', 'elementor-pro' ), + 'rating' => esc_html__( 'Rating', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + + $this->start_injection( [ + 'at' => 'before', + 'of' => 'section_design_box', + ] ); + + $this->start_controls_section( + 'section_heading_style', + [ + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'show_heading', + [ + 'label' => esc_html__( 'Heading', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'return_value' => 'yes', + 'prefix_class' => 'show-heading-', + ] + ); + + $this->add_control( + 'heading_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .products > h2' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'heading_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products .products > h2', + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'heading_text_align', + [ + 'label' => esc_html__( 'Text Align', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .products > h2' => 'text-align: {{VALUE}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'heading_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .products > h2' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'show_heading!' => '', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + } + + protected function render() { + $settings = $this->get_settings_for_display(); + + // Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected. + if ( 'yes' === $settings['automatically_align_buttons'] ) { + add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 ); + } + + $limit = '-1'; + $columns = 4; + $orderby = 'rand'; + $order = 'desc'; + + if ( ! empty( $settings['columns'] ) ) { + $columns = $settings['columns']; + } + + if ( ! empty( $settings['orderby'] ) ) { + $orderby = $settings['orderby']; + } + + if ( ! empty( $settings['order'] ) ) { + $order = $settings['order']; + } + + ob_start(); + + woocommerce_upsell_display( + sanitize_text_field( $limit ), + sanitize_text_field( $columns ), + sanitize_text_field( $orderby ), + sanitize_text_field( $order ) + ); + + $upsells_html = ob_get_clean(); + + if ( $upsells_html ) { + $upsells_html = str_replace( '
              start_controls_section( + 'section_products_style', + [ + 'label' => esc_html__( 'Products', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'wc_style_warning', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'products_class', + [ + 'type' => Controls_Manager::HIDDEN, + 'default' => 'wc-products', + 'prefix_class' => 'elementor-products-grid elementor-', + ] + ); + + $this->add_responsive_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 20, + ], + 'tablet_default' => [ + 'size' => 20, + ], + 'mobile_default' => [ + 'size' => 20, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'row_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'size' => 40, + ], + 'tablet_default' => [ + 'size' => 40, + ], + 'mobile_default' => [ + 'size' => 40, + ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products' => 'grid-row-gap: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'align', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'prefix_class' => 'elementor-product-loop-item--align-', + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'text-align: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'heading_image_style', + [ + 'label' => esc_html__( 'Image', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'image_border', + 'selector' => '{{WRAPPER}}.elementor-wc-products .attachment-woocommerce_thumbnail', + ] + ); + + $this->add_responsive_control( + 'image_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .attachment-woocommerce_thumbnail' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'image_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .attachment-woocommerce_thumbnail' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-product__title' => 'color: {{VALUE}}', + '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-category__title' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-product__title, ' . + '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-category__title', + + ] + ); + + $this->add_responsive_control( + 'title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-product__title' => 'margin-bottom: {{SIZE}}{{UNIT}}', + '{{WRAPPER}}.elementor-wc-products ul.products li.product .woocommerce-loop-category__title' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_rating_style', + [ + 'label' => esc_html__( 'Rating', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'star_color', + [ + 'label' => esc_html__( 'Star Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .star-rating' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'empty_star_color', + [ + 'label' => esc_html__( 'Empty Star Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .star-rating::before' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'star_size', + [ + 'label' => esc_html__( 'Star Size', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'default' => [ + 'unit' => 'em', + ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .star-rating' => 'font-size: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'rating_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .star-rating' => 'margin-bottom: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'heading_price_style', + [ + 'label' => esc_html__( 'Price', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .price' => 'color: {{VALUE}}', + '{{WRAPPER}}.elementor-wc-products ul.products li.product .price ins' => 'color: {{VALUE}}', + '{{WRAPPER}}.elementor-wc-products ul.products li.product .price ins .amount' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'price_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .price', + ] + ); + + $this->add_control( + 'heading_old_price_style', + [ + 'label' => esc_html__( 'Regular Price', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'old_price_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .price del' => 'color: {{VALUE}}', + '{{WRAPPER}}.elementor-wc-products ul.products li.product .price del .amount' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'old_price_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .price del .amount ', + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .price del ', + ] + ); + + $this->add_control( + 'heading_button_style', + [ + 'label' => esc_html__( 'Button', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'button_hover_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button:hover' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_group_control( + Group_Control_Border::get_type(), [ + 'name' => 'button_border', + 'exclude' => [ 'color' ], + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product .button', + 'separator' => 'before', + ] + ); + + $this->add_control( + 'button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'button_text_padding', + [ + 'label' => esc_html__( 'Text Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'button_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product .button' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'automatically_align_buttons', + [ + 'label' => __( 'Automatically align buttons', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => __( 'Yes', 'elementor-pro' ), + 'label_off' => __( 'No', 'elementor-pro' ), + 'default' => '', + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => '--button-align-display: flex; --button-align-direction: column; --button-align-justify: space-between;', + ], + 'render_type' => 'template', + ] + ); + + $this->add_control( + 'heading_view_cart_style', + [ + 'label' => esc_html__( 'View Cart', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + ] + ); + + $this->add_control( + 'view_cart_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .added_to_cart' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'view_cart_typography', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_ACCENT, + ], + 'selector' => '{{WRAPPER}}.elementor-wc-products .added_to_cart', + ] + ); + + $this->add_responsive_control( + 'view_cart_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products .added_to_cart' => 'margin-inline-start: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_design_box', + [ + 'label' => esc_html__( 'Box', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'box_border_width', + [ + 'label' => esc_html__( 'Border Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'border-style: solid; border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'box_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 200, + ], + 'em' => [ + 'max' => 20, + ], + 'rem' => [ + 'max' => 20, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_responsive_control( + 'box_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 50, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}', + ], + ] + ); + + $this->start_controls_tabs( 'box_style_tabs' ); + + $this->start_controls_tab( 'classic_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow', + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product', + ] + ); + + $this->add_control( + 'box_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'box_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'classic_style_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'box_shadow_hover', + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product:hover', + ] + ); + + $this->add_control( + 'box_bg_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'box_border_color_hover', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product:hover' => 'border-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_pagination_style', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'paginate' => 'yes', + ], + ] + ); + + $this->add_control( + 'pagination_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination' => 'margin-top: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_control( + 'show_pagination_border', + [ + 'label' => esc_html__( 'Border', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'default' => 'yes', + 'return_value' => 'yes', + 'prefix_class' => 'elementor-show-pagination-border-', + ] + ); + + $this->add_control( + 'pagination_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul' => 'border-color: {{VALUE}}', + '{{WRAPPER}} nav.woocommerce-pagination ul li' => 'border-right-color: {{VALUE}}; border-left-color: {{VALUE}}', + ], + 'condition' => [ + 'show_pagination_border' => 'yes', + ], + ] + ); + + $this->add_control( + 'pagination_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 20, + ], + 'em' => [ + 'max' => 2, + ], + 'rem' => [ + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li a, {{WRAPPER}} nav.woocommerce-pagination ul li span' => 'padding: {{SIZE}}{{UNIT}}', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'pagination_typography', + 'selector' => '{{WRAPPER}} nav.woocommerce-pagination', + ] + ); + + $this->start_controls_tabs( 'pagination_style_tabs' ); + + $this->start_controls_tab( 'pagination_style_normal', + [ + 'label' => esc_html__( 'Normal', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_link_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li a' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'pagination_link_bg_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li a' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'pagination_style_hover', + [ + 'label' => esc_html__( 'Hover', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_link_color_hover', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li a:hover' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'pagination_link_bg_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li a:hover' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'pagination_style_active', + [ + 'label' => esc_html__( 'Active', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'pagination_link_color_active', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li span.current' => 'color: {{VALUE}}', + ], + ] + ); + + $this->add_control( + 'pagination_link_bg_color_active', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} nav.woocommerce-pagination ul li span.current' => 'background-color: {{VALUE}}', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'sale_flash_style', + [ + 'label' => esc_html__( 'Sale Flash', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'show_onsale_flash', + [ + 'label' => esc_html__( 'Sale Flash', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'separator' => 'before', + 'default' => 'yes', + 'return_value' => 'yes', + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'display: block', + ], + ] + ); + + $this->add_control( + 'onsale_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'color: {{VALUE}}', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_text_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'background-color: {{VALUE}}', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'onsale_typography', + 'selector' => '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale', + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'border-radius: {{SIZE}}{{UNIT}}', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'min-width: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_height', + [ + 'label' => esc_html__( 'Height', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'min-height: {{SIZE}}{{UNIT}}; line-height: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_horizontal_position', + [ + 'label' => esc_html__( 'Position', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'elementor-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'elementor-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => '{{VALUE}}', + ], + 'selectors_dictionary' => [ + 'left' => 'right: auto; left: 0', + 'right' => 'left: auto; right: 0', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->add_control( + 'onsale_distance', + [ + 'label' => esc_html__( 'Distance', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'min' => -20, + 'max' => 20, + ], + 'em' => [ + 'min' => -2, + 'max' => 2, + ], + 'rem' => [ + 'min' => -2, + 'max' => 2, + ], + ], + 'selectors' => [ + '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => 'margin: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'show_onsale_flash' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Add To Cart Wrapper + * + * Add a div wrapper around the Add to Cart & View Cart buttons on the product cards inside the product grid. + * The wrapper is used to vertically align the Add to Cart Button and the View Cart link to the bottom of the card. + * This wrapper is added when the 'Automatically align buttons' toggle is selected. + * Using the 'woocommerce_loop_add_to_cart_link' hook. + * + * @since 3.7.0 + * + * @param string $string + * @return string $string + */ + public function add_to_cart_wrapper( $string ) { + return '
              ' . $string . '
              '; + } +} diff --git a/modules/woocommerce/widgets/products-deprecated.php b/modules/woocommerce/widgets/products-deprecated.php new file mode 100644 index 00000000..3bc027bf --- /dev/null +++ b/modules/woocommerce/widgets/products-deprecated.php @@ -0,0 +1,292 @@ +query; + } + + protected function register_skins() { + $this->add_skin( new Skins\Skin_Classic( $this ) ); + } + + protected function register_controls() { + $this->deprecated_notice( Plugin::get_title(), '2.0.10', '', esc_html__( 'Products', 'elementor-pro' ) ); + + $this->start_controls_section( + 'section_layout', + [ + 'label' => esc_html__( 'Layout', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Products Count', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => '4', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_filter', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_group_control( + Group_Control_Posts::get_type(), + [ + 'name' => 'posts', + 'post_type' => 'product', + ] + ); + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__( 'Advanced', 'elementor-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'filter_by', + [ + 'label' => esc_html__( 'Filter By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'elementor-pro' ), + 'featured' => esc_html__( 'Featured', 'elementor-pro' ), + 'sale' => esc_html__( 'Sale', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'date', + 'options' => [ + 'date' => esc_html__( 'Date', 'elementor-pro' ), + 'title' => esc_html__( 'Title', 'elementor-pro' ), + 'price' => esc_html__( 'Price', 'elementor-pro' ), + 'popularity' => esc_html__( 'Popularity', 'elementor-pro' ), + 'rating' => esc_html__( 'Rating', 'elementor-pro' ), + 'rand' => esc_html__( 'Random', 'elementor-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'elementor-pro' ), + 'desc' => esc_html__( 'DESC', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'exclude', + [ + 'label' => esc_html__( 'Exclude', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT2, + 'multiple' => true, + 'options' => [ + 'current_post' => esc_html__( 'Current Post', 'elementor-pro' ), + 'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ), + ], + 'label_block' => true, + ] + ); + + $this->add_control( + 'exclude_ids', + [ + 'label' => esc_html__( 'Search & Select', 'elementor-pro' ), + 'type' => Module::QUERY_CONTROL_ID, + 'autocomplete' => [ + 'object' => Module::QUERY_OBJECT_POST, + ], + 'options' => [], + 'label_block' => true, + 'multiple' => true, + 'condition' => [ + 'exclude' => 'manual_selection', + ], + ] + ); + + $this->add_control( + 'avoid_duplicates', + [ + 'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up on the page. This only affects the frontend.', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + } + + public function query_posts() { + $settings = $this->get_settings(); + /** @var Module $query_module */ + $query_module = Module::instance(); + $query_args = $query_module->get_query_args( 'posts', $settings ); + + // Default ordering args + $ordering_args = WC()->query->get_catalog_ordering_args( $settings['orderby'], $settings['order'] ); + + $query_args['orderby'] = $ordering_args['orderby']; + $query_args['order'] = $ordering_args['order']; + + if ( ! empty( $ordering_args['meta_key'] ) ) { + $query_args['meta_key'] = $ordering_args['meta_key']; + } + + if ( 'sale' === $settings['filter_by'] ) { + // From WooCommerce `sale_products` shortcode + $query_args['post__in'] = array_merge( [ 0 ], wc_get_product_ids_on_sale() ); + } + + if ( version_compare( WC()->version, '3.0.0', '>=' ) ) { + $query_args = $this->get_wc_visibility_parse_query( $query_args ); + } else { + $query_args = $this->get_wc_legacy_visibility_parse_query( $query_args ); + } + + $this->query = new \WP_Query( $query_args ); + } + + private function get_wc_visibility_parse_query( $query_args ) { + $settings = $this->get_settings(); + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + if ( 'featured' === $settings['filter_by'] ) { + $query_args['tax_query'][] = [ + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_term_ids['featured'], + ]; + } + + return $query_args; + } + + private function get_wc_legacy_visibility_parse_query( $query_args ) { + $settings = $this->get_settings(); + + $query_args['meta_query'] = [ + [ + 'key' => '_visibility', + 'value' => [ 'catalog', 'visible' ], + 'compare' => 'IN', + ], + ]; + + if ( 'featured' === $settings['filter_by'] ) { + // From WooCommerce `featured_products` shortcode + $query_args['meta_query'][] = [ + 'key' => '_featured', + 'value' => 'yes', + ]; + } + + return $query_args; + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/products.php b/modules/woocommerce/widgets/products.php new file mode 100644 index 00000000..1d2f4635 --- /dev/null +++ b/modules/woocommerce/widgets/products.php @@ -0,0 +1,400 @@ +start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_query_controls( Products_Renderer::QUERY_CONTROL_NAME ); + + $this->end_controls_section(); + } + + protected function register_controls() { + $this->start_controls_section( + 'section_content', + [ + 'label' => esc_html__( 'Content', 'elementor-pro' ), + ] + ); + + $this->add_columns_responsive_control(); + + $this->add_control( + 'rows', + [ + 'label' => esc_html__( 'Rows', 'elementor-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => Products_Renderer::DEFAULT_COLUMNS_AND_ROWS, + 'render_type' => 'template', + 'range' => [ + 'px' => [ + 'max' => 20, + ], + ], + ] + ); + + $this->add_control( + 'paginate', + [ + 'label' => esc_html__( 'Pagination', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + Products_Renderer::QUERY_CONTROL_NAME . '_post_type!' => [ + 'related_products', + 'upsells', + 'cross_sells', + ], + ], + ] + ); + + $this->add_control( + 'allow_order', + [ + 'label' => esc_html__( 'Allow Order', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'paginate' => 'yes', + ], + ] + ); + + $this->add_control( + 'wc_notice_frontpage', + [ + 'type' => Controls_Manager::ALERT, + 'alert_type' => 'info', + 'content' => esc_html__( 'Ordering is not available if this widget is placed in your front page. Visible on frontend only.', 'elementor-pro' ), + 'condition' => [ + 'paginate' => 'yes', + 'allow_order' => 'yes', + ], + ] + ); + + $this->add_control( + 'show_result_count', + [ + 'label' => esc_html__( 'Show Result Count', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'paginate' => 'yes', + ], + ] + ); + + $this->end_controls_section(); + + $this->register_query_section(); + + $this->start_controls_section( + 'section_products_title', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'related_products', + ], + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'upsells', + ], + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'cross_sells', + ], + ], + ], + ] + ); + + $this->add_control( + 'products_title_show', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => '', + 'return_value' => 'show', + 'prefix_class' => 'products-heading-', + ] + ); + + $query_type_strings = [ + 'related_products' => esc_html__( 'Related Products', 'elementor-pro' ), + 'upsells' => esc_html__( 'You may also like...', 'elementor-pro' ), + 'cross_sells' => esc_html__( 'You may be interested in...', 'elementor-pro' ), + ]; + + foreach ( $query_type_strings as $query_type => $string ) { + $this->add_control( + 'products_' . $query_type . '_title_text', + [ + 'label' => esc_html__( 'Section Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'label_block' => true, + 'placeholder' => $string, + 'default' => $string, + 'dynamic' => [ + 'active' => true, + ], + 'condition' => [ + 'products_title_show!' => '', + Products_Renderer::QUERY_CONTROL_NAME . '_post_type' => $query_type, + ], + ] + ); + } + + $this->add_responsive_control( + 'products_title_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--products-title-alignment: {{VALUE}};', + ], + 'condition' => [ + 'products_title_show!' => '', + ], + ] + ); + + $this->end_controls_section(); + + parent::register_controls(); + + $this->start_injection( [ + 'type' => 'section', + 'at' => 'start', + 'of' => 'section_design_box', + ] ); + + $this->start_controls_section( + 'products_title_style', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => [ + 'products_title_show!' => '', + ], + 'conditions' => [ + 'relation' => 'or', + 'terms' => [ + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'related_products', + ], + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'upsells', + ], + [ + 'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type', + 'operator' => '=', + 'value' => 'cross_sells', + ], + ], + ], + ] + ); + + $this->add_control( + 'products_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'global' => [ + 'default' => Global_Colors::COLOR_PRIMARY, + ], + 'selectors' => [ + '{{WRAPPER}}' => '--products-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'products_title_typography', + 'selector' => '{{WRAPPER}}.products-heading-show .related-products > h2, {{WRAPPER}}.products-heading-show .upsells > h2, {{WRAPPER}}.products-heading-show .cross-sells > h2', + 'global' => [ + 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, + ], + ] + ); + + $this->add_responsive_control( + 'products_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--products-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->end_injection(); + } + + public static function get_shortcode_object( $settings ) { + if ( 'current_query' === $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ] ) { + return new Current_Query_Renderer( $settings, 'current_query' ); + } + return new Products_Renderer( $settings, 'products' ); + } + + protected function render() { + + if ( WC()->session ) { + wc_print_notices(); + } + + $settings = $this->get_settings_for_display(); + $post_type_setting = $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ]; + + // Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected. + if ( 'yes' === $settings['automatically_align_buttons'] ) { + add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 ); + } + + if ( 'related_products' === $post_type_setting ) { + $content = Module::get_products_related_content( $settings ); + } elseif ( 'upsells' === $post_type_setting ) { + $content = Module::get_upsells_content( $settings ); + } elseif ( 'cross_sells' === $post_type_setting ) { + $content = Module::get_cross_sells_content( $settings ); + } else { + // For Products_Renderer. + if ( ! isset( $GLOBALS['post'] ) ) { + $GLOBALS['post'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + } + + $shortcode = static::get_shortcode_object( $settings ); + $content = $shortcode->get_content(); + } + + if ( $content ) { + $content = str_replace( '
                get_settings_for_display( 'nothing_found_message' ) ) { + echo '
                ' . esc_html( $this->get_settings_for_display( 'nothing_found_message' ) ) . '
                '; + } + + if ( 'yes' === $settings['automatically_align_buttons'] ) { + remove_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ] ); + } + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/purchase-summary.php b/modules/woocommerce/widgets/purchase-summary.php new file mode 100644 index 00000000..9b9bfa69 --- /dev/null +++ b/modules/woocommerce/widgets/purchase-summary.php @@ -0,0 +1,1737 @@ +experiments->is_feature_active( 'e_optimized_markup' ); + } + + /** + * Get style dependencies. + * + * Retrieve the list of style dependencies the widget requires. + * + * @since 3.24.0 + * @access public + * + * @return array Widget style dependencies. + */ + public function get_style_depends(): array { + return [ 'widget-woocommerce-purchase-summary' ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'confirmation_message', + [ + 'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'confirmation_message_active', + [ + 'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'label_on' => esc_html__( 'Show', 'elementor-pro' ), + 'label_off' => esc_html__( 'Hide', 'elementor-pro' ), + 'default' => 'yes', + 'selectors' => [ + '{{WRAPPER}}' => '--confirmation-message-display: block;', + ], + ] + ); + + $this->add_control( + 'confirmation_message_text', + [ + 'label' => esc_html__( 'Message', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'default' => esc_html__( 'Thank You. Your order has been received.', 'elementor-pro' ), + 'label_block' => true, + 'condition' => [ + 'confirmation_message_active!' => '', + ], + ] + ); + + $this->add_responsive_control( + 'confirmation_message_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'condition' => [ + 'confirmation_message_active!' => '', + ], + 'selectors' => [ + '{{WRAPPER}}' => '--confirmation-message-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'payment_details', + [ + 'label' => esc_html__( 'Payment Details', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_number', + [ + 'label' => esc_html__( 'Number', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Order Number:', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_date', + [ + 'label' => esc_html__( 'Date:', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Order Date:', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_email', + [ + 'label' => esc_html__( 'Email', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Order Email:', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_total', + [ + 'label' => esc_html__( 'Total', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Order Total:', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_payment', + [ + 'label' => esc_html__( 'Payment', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Payment Method:', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'bank_details', + [ + 'label' => esc_html__( 'Bank Details', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'bank_details_text', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Our Bank Details', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'bank_details_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'downloads', + [ + 'label' => esc_html__( 'Downloads', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'downloads_text', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Downloads', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'downloads_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--downloads-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'order_summary', + [ + 'label' => esc_html__( 'Purchase Summary', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_summary_text', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Order Details', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'order_summary_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-summary-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'billing_details', + [ + 'label' => esc_html__( 'Billing Details', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'billing_details_text', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Billing Details', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'billing_details_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--billing-details-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'shipping_details', + [ + 'label' => esc_html__( 'Shipping Address', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'shipping_details_text', + [ + 'label' => esc_html__( 'Title', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'dynamic' => [ + 'active' => true, + ], + 'ai' => [ + 'active' => false, + ], + 'default' => esc_html__( 'Shipping Details', 'elementor-pro' ), + ] + ); + + $this->add_responsive_control( + 'shipping_details_alignment', + [ + 'label' => esc_html__( 'Alignment', 'elementor-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'start' => [ + 'title' => esc_html__( 'Start', 'elementor-pro' ), + 'icon' => 'eicon-text-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'elementor-pro' ), + 'icon' => 'eicon-text-align-center', + ], + 'end' => [ + 'title' => esc_html__( 'End', 'elementor-pro' ), + 'icon' => 'eicon-text-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--shipping-details-alignment: {{VALUE}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'preview_order', + [ + 'label' => esc_html__( 'Preview Settings', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'preview_order_type', + [ + 'label' => esc_html__( 'Preview order with', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Latest Order', 'elementor-pro' ), + 'custom-order' => esc_html__( 'Order ID', 'elementor-pro' ), + ], + ] + ); + + $this->add_control( + 'preview_order_custom', + [ + 'label' => esc_html__( 'Order ID', 'elementor-pro' ), + 'type' => Controls_Manager::TEXT, + 'condition' => [ + 'preview_order_type' => 'custom-order', + ], + 'ai' => [ + 'active' => false, + ], + 'render_type' => 'template', + 'description' => esc_html__( 'Note: To find an order ID, go to the WP dashboard: WooCommerce > Orders', 'elementor-pro' ), + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'sections_tabs_style', + [ + 'label' => esc_html__( 'Sections', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'sections_background_color', + [ + 'label' => esc_html__( 'Background Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'sections_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table, {{WRAPPER}} address', + ] + ); + + $this->add_control( + 'sections_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .shop_table, {{WRAPPER}} address' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'sections_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-color: {{VALUE}};', + ], + 'condition' => [ + 'sections_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'sections_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'sections_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--sections-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'typography_title', + [ + 'label' => esc_html__( 'Typography', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'confirmation_message_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'confirmation_message_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--confirmation-message-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'confirmation_message_typography', + 'selector' => '{{WRAPPER}} .woocommerce-thankyou-order-received', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'confirmation_message_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-thankyou-order-received', + ] + ); + + $this->add_control( + 'titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--titles-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'titles_typography', + 'selector' => '{{WRAPPER}} h2', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'titles_text_shadow', + 'selector' => '{{WRAPPER}} h2', + ] + ); + + $this->add_responsive_control( + 'titles_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--titles-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'general_text_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'General Text', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'general_text_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--general-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'general_text_typography', + 'selector' => '{{WRAPPER}} address, {{WRAPPER}} .product-purchase-note, {{WRAPPER}} .woocommerce-thankyou-order-details + p', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'payment_details_title', + [ + 'label' => esc_html__( 'Payment Details', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'payment_details_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-space-between: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'payment_details_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-titles-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_details_titles_typography', + 'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li', + 'exclude' => [ + 'text_decoration', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'payment_details_titles_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li', + ] + ); + + $this->add_responsive_control( + 'payment_details_titles_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-titles-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'payment_details_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'payment_details_items_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-items-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'payment_details_items_typography', + 'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li strong', + 'exclude' => [ + 'text_decoration', + ], + ] + ); + + $this->add_control( + 'payment_details_dividers_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'payment_details_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'payment_details_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-border-width: {{SIZE}}{{UNIT}};', + ], + + 'condition' => [ + 'payment_details_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'payment_details_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--payment-details-border-color: {{VALUE}};', + ], + 'condition' => [ + 'payment_details_border_type!' => 'none', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'bank_details_title', + [ + 'label' => esc_html__( 'Bank Details', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'bank_details_space_between', + [ + 'label' => esc_html__( 'Space Between', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-space-between: {{SIZE}}{{UNIT}};', + ], + 'separator' => 'after', + ] + ); + + $this->add_control( + 'bank_details_account_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Account Title', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'account_title_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--account-title-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'account_title_typography', + 'selector' => '{{WRAPPER}} .wc-bacs-bank-details-account-name', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'account_title_text_shadow', + 'selector' => '{{WRAPPER}} .wc-bacs-bank-details-account-name', + ] + ); + + $this->add_responsive_control( + 'account_title_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--account-title-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'bank_details_titles_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'bank_details_titles_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-titles-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'bank_details_titles_typography', + 'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li', + 'exclude' => [ + 'text_decoration', + ], + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'bank_details_titles_text_shadow', + 'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li', + ] + ); + + $this->add_responsive_control( + 'bank_details_titles_spacing', + [ + 'label' => esc_html__( 'Spacing', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-titles-spacing: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'bank_details_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'bank_details_items_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-items-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'bank_details_items_typography', + 'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong', + 'exclude' => [ + 'text_decoration', + ], + ] + ); + + $this->add_control( + 'bank_details_dividers_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'bank_details_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'bank_details_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-border-width: {{SIZE}}{{UNIT}};', + ], + + 'condition' => [ + 'bank_details_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'bank_details_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--bank-details-border-color: {{VALUE}};', + ], + 'condition' => [ + 'bank_details_border_type!' => 'none', + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'order_details_title', + [ + 'label' => esc_html__( 'Order Details', 'elementor-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_responsive_control( + 'order_details_rows_gap', + [ + 'label' => esc_html__( 'Rows Gap', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', 'em', 'rem', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 50, + ], + 'em' => [ + 'max' => 5, + ], + 'rem' => [ + 'max' => 5, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-rows-gap: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'order_details_titles_totals', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_details_titles_totals_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-titles-totals-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_details_titles_totals_typography', + 'selector' => '{{WRAPPER}} .shop_table thead tr th, {{WRAPPER}} .shop_table tfoot th, {{WRAPPER}} .shop_table tfoot tr td, {{WRAPPER}} .shop_table tfoot tr td span, {{WRAPPER}} .woocommerce-table--order-downloads tr td:before', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'order_details_titles_totals_text_shadow', + 'selector' => '{{WRAPPER}} .shop_table thead tr th, {{WRAPPER}} .shop_table tfoot th, {{WRAPPER}} .shop_table tfoot tr td, {{WRAPPER}} .shop_table tfoot tr td span, {{WRAPPER}} .woocommerce-table--order-downloads tr td:before', + ] + ); + + $this->add_control( + 'order_details_items_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Items', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_details_items_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-items-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_details_items_typography', + 'selector' => '{{WRAPPER}} .product-quantity, {{WRAPPER}} .woocommerce-table--order-details td a, {{WRAPPER}} td.product-total, {{WRAPPER}} td.download-product, {{WRAPPER}} td.download-remaining, {{WRAPPER}} td.download-expires, {{WRAPPER}} td.download-file', + ] + ); + + $this->add_control( + 'order_details_variations_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Variations', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'order_details_variations_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-variations-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_details_variations_typography', + 'selector' => '{{WRAPPER}} .product-name .wc-item-meta .wc-item-meta-label, {{WRAPPER}} .wc-item-meta li p', + ] + ); + + $this->add_control( + 'order_details_product_links_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Product Link', 'elementor-pro' ), + ] + ); + + $this->start_controls_tabs( 'order_details_product_links_colors' ); + + $this->start_controls_tab( 'order_details_product_links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_details_product_links_normal_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-product-links-normal-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'order_details_product_links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_details_product_links_hover_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--order-details-product-links-hover-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'order_details_dividers_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Dividers', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_control( + 'order_details_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-type: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_details_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::SLIDER, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'range' => [ + 'px' => [ + 'max' => 100, + ], + 'em' => [ + 'max' => 10, + ], + 'rem' => [ + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-width: {{SIZE}}{{UNIT}};', + ], + + 'condition' => [ + 'order_details_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_details_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--tables-divider-border-color: {{VALUE}};', + ], + 'condition' => [ + 'order_details_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_details_button_title', + [ + 'type' => Controls_Manager::HEADING, + 'label' => esc_html__( 'Buttons', 'elementor-pro' ), + 'separator' => 'before', + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'order_details_button_typography', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button', + ] + ); + + $this->add_group_control( + Group_Control_Text_Shadow::get_type(), + [ + 'name' => 'order_details_button_text_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button', + ] + ); + + $this->start_controls_tabs( 'order_details_button_styles' ); + + $this->start_controls_tab( 'order_details_button_styles_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_details_button_normal_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--button-normal-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'order_details_button_normal_background', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'order_details_button_normal_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( 'order_details_button_styles_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] ); + + $this->add_control( + 'order_details_button_hover_text_color', + [ + 'label' => esc_html__( 'Text Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}}' => '--button-hover-text-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Background::get_type(), + [ + 'name' => 'order_details_button_hover_background', + 'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover', + ] + ); + + $this->add_group_control( + Group_Control_Box_Shadow::get_type(), + [ + 'name' => 'order_details_button_hover_box_shadow', + 'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover', + ] + ); + + $this->add_control( + 'order_details_button_hover_border_color', + [ + 'label' => esc_html__( 'Border Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover' => 'border-color: {{VALUE}}', + ], + 'condition' => [ + 'order_details_button_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_details_button_hover_transition_duration', + [ + 'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)', + 'type' => Controls_Manager::SLIDER, + 'selectors' => [ + '{{WRAPPER}}' => '--button-hover-transition-duration: {{SIZE}}ms', + ], + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 3000, + 'step' => 100, + ], + ], + ] + ); + + $this->add_control( + 'order_details_button_hover_animation', + [ + 'label' => esc_html__( 'Hover Animation', 'elementor-pro' ), + 'type' => Controls_Manager::HOVER_ANIMATION, + 'frontend_available' => true, + 'render_type' => 'template', + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->add_control( + 'order_details_button_border_type', + [ + 'label' => esc_html__( 'Border Type', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->get_custom_border_type_options(), + 'selectors' => [ + '{{WRAPPER}}' => '--buttons-border-type: {{VALUE}};', + ], + 'separator' => 'before', + ] + ); + + $this->add_responsive_control( + 'order_details_button_border_width', + [ + 'label' => esc_html__( 'Width', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button, {{WRAPPER}} .woocommerce-pagination .button' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + 'condition' => [ + 'order_details_button_border_type!' => 'none', + ], + ] + ); + + $this->add_control( + 'order_details_button_border_color', + [ + 'label' => esc_html__( 'Color', 'elementor-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' => '--buttons-border-color: {{VALUE}};', + ], + 'condition' => [ + 'order_details_button_border_type!' => 'none', + ], + ] + ); + + $this->add_responsive_control( + 'order_details_button_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_responsive_control( + 'order_details_button_padding', + [ + 'label' => esc_html__( 'Padding', 'elementor-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], + 'selectors' => [ + '{{WRAPPER}}' => '--button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_section(); + } + + /** + * Init Gettext Modifications + * + * Sets the `$gettext_modifications` property used with the `filter_gettext()` in the extended Base_Widget. + * + * @since 3.5.0 + */ + protected function init_gettext_modifications() { + $instance = $this->get_settings_for_display(); + + $this->gettext_modifications = [ + 'Order number:' => isset( $instance['payment_details_number'] ) ? $instance['payment_details_number'] : '', + 'Date:' => isset( $instance['payment_details_date'] ) ? $instance['payment_details_date'] : '', + 'Email:' => isset( $instance['payment_details_email'] ) ? $instance['payment_details_email'] : '', + 'Total:' => isset( $instance['payment_details_total'] ) ? $instance['payment_details_total'] : '', + 'Payment method:' => isset( $instance['payment_details_payment'] ) ? $instance['payment_details_payment'] : '', + 'Our bank details' => isset( $instance['bank_details_text'] ) ? $instance['bank_details_text'] : '', + 'Order details' => isset( $instance['order_summary_text'] ) ? $instance['order_summary_text'] : '', + 'Billing address' => isset( $instance['billing_details_text'] ) ? $instance['billing_details_text'] : '', + 'Shipping address' => isset( $instance['shipping_details_text'] ) ? $instance['shipping_details_text'] : '', + 'Downloads' => isset( $instance['downloads_text'] ) ? $instance['downloads_text'] : '', + ]; + } + + /** + * Modify Order Received Text. + * + * @since 3.5.0 + * + * @param $text + * @return string + */ + public function modify_order_received_text( $text ) { + $instance = $this->get_settings_for_display(); + + if ( isset( $instance['confirmation_message_text'] ) ) { + $text = $instance['confirmation_message_text']; + } + + return $text; + } + + public function get_modified_order_id() { + return $this->order_id; + } + + public function get_modified_order_key() { + return $this->order_key; + } + + protected function render() { + $is_editor = Plugin::elementor()->editor->is_edit_mode(); + $is_preview = Module::is_preview(); + + if ( $is_editor || $is_preview ) { + $this->set_preview_order(); + + add_filter( 'woocommerce_thankyou_order_id', [ $this, 'get_modified_order_id' ] ); + add_filter( 'woocommerce_thankyou_order_key', [ $this, 'get_modified_order_key' ] ); + + /** + * The action `template_redirect` is not run during the re-loading of the Widget and as a result the + * `wc_template_redirect` function is not run which is responsible for loading the following, so we + * must load them ourselves. + */ + WC()->payment_gateways(); + WC()->shipping(); + } + + /* + * Add actions & filters before displaying our Widget. + */ + add_filter( 'gettext', [ $this, 'filter_gettext' ], 20, 3 ); + add_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'modify_order_received_text' ] ); + + /** + * Display our Widget. + */ + global $wp; + if ( isset( $wp->query_vars['order-received'] ) && wc_get_order( intval( $wp->query_vars['order-received'] ) ) ) { + echo do_shortcode( '[woocommerce_checkout]' ); + } elseif ( $is_editor || $is_preview ) { + $this->no_order_notice(); + } + + /* + * Remove actions & filters after displaying our Widget. + */ + remove_filter( 'gettext', [ $this, 'filter_gettext' ], 20 ); + remove_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'modify_order_received_text' ] ); + + if ( $is_editor || $is_preview ) { + remove_filter( 'woocommerce_thankyou_order_id', [ $this, 'get_modified_order_id' ] ); + remove_filter( 'woocommerce_thankyou_order_key', [ $this, 'get_modified_order_key' ] ); + } + } + + public function no_order_notice() { + ?> + + get_settings_for_display(); + $order = false; + + if ( 'custom-order' === $instance['preview_order_type'] ) { + $order = wc_get_order( $instance['preview_order_custom'] ); + } + + if ( ! $order ) { + $latest_order = wc_get_orders( [ + 'limit' => 1, + 'orderby' => 'date', + 'order' => 'DESC', + 'return' => 'ids', + ] ); + + if ( isset( $latest_order[0] ) ) { + $order = wc_get_order( $latest_order[0] ); + } + } + + if ( $order ) { + global $wp; + $wp->set_query_var( 'order-received', $order->get_id() ); + + $this->order_id = $order->get_id(); + $this->order_key = $order->get_order_key(); + } + } + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/woocommerce/widgets/single-elements.php b/modules/woocommerce/widgets/single-elements.php new file mode 100644 index 00000000..de24200e --- /dev/null +++ b/modules/woocommerce/widgets/single-elements.php @@ -0,0 +1,144 @@ +init_allowed_functions(); + } + + public function get_name() { + return 'wc-single-elements'; + } + + public function get_title() { + return esc_html__( 'Woo - Single Elements', 'elementor-pro' ); + } + + public function get_icon() { + return 'eicon-woocommerce'; + } + + /* Deprecated Widget */ + public function show_in_panel() { + return false; + } + + /** + * @return void + */ + private function init_allowed_functions(): void { + $this->allowed_functions = [ + '' => '— ' . esc_html__( 'Select', 'elementor-pro' ) . ' —', + 'woocommerce_output_product_data_tabs' => esc_html__( 'Data Tabs', 'elementor-pro' ), + 'woocommerce_template_single_title' => esc_html__( 'Title', 'elementor-pro' ), + 'woocommerce_template_single_rating' => esc_html__( 'Rating', 'elementor-pro' ), + 'woocommerce_template_single_price' => esc_html__( 'Price', 'elementor-pro' ), + 'woocommerce_template_single_excerpt' => esc_html__( 'Excerpt', 'elementor-pro' ), + 'woocommerce_template_single_meta' => esc_html__( 'Meta', 'elementor-pro' ), + 'woocommerce_template_single_sharing' => esc_html__( 'Sharing', 'elementor-pro' ), + 'woocommerce_show_product_sale_flash' => esc_html__( 'Sale Flash', 'elementor-pro' ), + 'woocommerce_product_additional_information_tab' => esc_html__( 'Additional Information Tab', 'elementor-pro' ), + 'woocommerce_upsell_display' => esc_html__( 'Upsell', 'elementor-pro' ), + 'wc_get_stock_html' => esc_html__( 'Stock Status', 'elementor-pro' ), + ]; + } + + protected function register_controls() { + $this->start_controls_section( + 'section_product', + [ + 'label' => esc_html__( 'Element', 'elementor-pro' ), + ] + ); + + $this->add_control( + 'element', + [ + 'label' => esc_html__( 'Element', 'elementor-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $this->allowed_functions, + ] + ); + + $this->end_controls_section(); + } + + public function remove_description_tab( $tabs ) { + unset( $tabs['description'] ); + + return $tabs; + } + + private function get_element() { + global $product; + $product = $this->get_product(); + + $settings = $this->get_settings(); + $html = ''; + + switch ( $settings['element'] ) { + case '': + break; + + case 'wc_get_stock_html': + $html = wc_get_stock_html( $product ); + break; + + case 'woocommerce_output_product_data_tabs': + add_filter( 'woocommerce_product_tabs', [ $this, 'remove_description_tab' ], 11 /* after default tabs*/ ); + ob_start(); + woocommerce_output_product_data_tabs(); + // Wrap with the internal woocommerce `product` class + $html = '
                ' . ob_get_clean() . '
                '; + remove_filter( 'woocommerce_product_tabs', [ $this, 'remove_description_tab' ], 11 ); + break; + + case 'woocommerce_template_single_rating': + $is_edit_mode = Plugin::elementor()->editor->is_edit_mode(); + + if ( 'no' === get_option( 'woocommerce_enable_review_rating' ) ) { + if ( $is_edit_mode ) { + $html = esc_html__( 'Admin Notice:', 'elementor-pro' ) . ' ' . esc_html__( 'Please enable the Review Rating', 'elementor-pro' ); + } + break; + } + + ob_start(); + woocommerce_template_single_rating(); + $html = ob_get_clean(); + if ( '' === $html && $is_edit_mode ) { + $html = esc_html__( 'Admin Notice:', 'elementor-pro' ) . ' ' . esc_html__( 'No Rating Reviews', 'elementor-pro' ); + } + break; + + default: + if ( is_callable( $settings['element'] ) && array_key_exists( $settings['element'], $this->allowed_functions ) ) { + $html = call_user_func( $settings['element'] ); + } + } + + return $html; + } + + protected function render() { + // PHPCS - the method get_content is safe. + echo $this->get_element(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + public function render_plain_content() {} + + public function get_group_name() { + return 'woocommerce'; + } +} diff --git a/modules/wp-cli/license-command.php b/modules/wp-cli/license-command.php new file mode 100644 index 00000000..b9bf47dc --- /dev/null +++ b/modules/wp-cli/license-command.php @@ -0,0 +1,37 @@ + + * - This will try activate your license key. + */ + public function activate( $args, $assoc_args ) { + } + + /** + * Deactivate Elementor Pro License key. + * + * ## EXAMPLES + * + * 1. wp elementor-pro license deactivate. + * - This will deactivate your license key. + */ + public function deactivate() { + } +} diff --git a/modules/wp-cli/module.php b/modules/wp-cli/module.php new file mode 100644 index 00000000..e21b791b --- /dev/null +++ b/modules/wp-cli/module.php @@ -0,0 +1,38 @@ +regenerate(); + + if ( is_wp_error( $cache_cleared ) ) { + \WP_CLI::error( $cache_cleared->get_error_message() ); + } + + \WP_CLI::success( 'Template conditions cache is cleared.' ); + } +} diff --git a/modules/wp-cli/update.php b/modules/wp-cli/update.php new file mode 100644 index 00000000..e8305c95 --- /dev/null +++ b/modules/wp-cli/update.php @@ -0,0 +1,18 @@ + 'ElementorPro\Modules\QueryControl\Module', + 'ElementorPro\Modules\PanelPostsControl\Controls\Group_Control_Posts' => 'ElementorPro\Modules\QueryControl\Controls\Group_Control_Posts', + 'ElementorPro\Modules\PanelPostsControl\Controls\Query' => 'ElementorPro\Modules\QueryControl\Controls\Query', + ]; + + /** + * @var PHP_Api + */ + public $php_api; + + /** + * Throw error on object clone + * + * The whole idea of the singleton design pattern is that there is a single + * object therefore, we don't want the object to be cloned. + * + * @since 1.0.0 + * @return void + */ + public function __clone() { + _doing_it_wrong( + __FUNCTION__, + sprintf( 'Cloning instances of the singleton "%s" class is forbidden.', get_class( $this ) ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + '1.0.0' + ); + } + + /** + * Disable unserializing of the class + * + * @since 1.0.0 + * @return void + */ + public function __wakeup() { + _doing_it_wrong( + __FUNCTION__, + sprintf( 'Unserializing instances of the singleton "%s" class is forbidden.', get_class( $this ) ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + '1.0.0' + ); + } + + /** + * @return \Elementor\Plugin + */ + + public static function elementor() { + return \Elementor\Plugin::$instance; + } + + /** + * @return Plugin + */ + public static function instance(): Plugin { + if ( is_null( self::$_instance ) ) { + self::$_instance = new self(); + } + + return self::$_instance; + } + + public function autoload( $class ) { + if ( 0 !== strpos( $class, __NAMESPACE__ ) ) { + return; + } + + $has_class_alias = isset( $this->classes_aliases[ $class ] ); + + // Backward Compatibility: Save old class name for set an alias after the new class is loaded + if ( $has_class_alias ) { + $class_alias_name = $this->classes_aliases[ $class ]; + $class_to_load = $class_alias_name; + } else { + $class_to_load = $class; + } + + if ( ! class_exists( $class_to_load ) ) { + $filename = strtolower( + preg_replace( + [ '/^' . __NAMESPACE__ . '\\\/', '/([a-z])([A-Z])/', '/_/', '/\\\/' ], + [ '', '$1-$2', '-', DIRECTORY_SEPARATOR ], + $class_to_load + ) + ); + $filename = ELEMENTOR_PRO_PATH . $filename . '.php'; + + if ( is_readable( $filename ) ) { + include( $filename ); + } + } + + if ( $has_class_alias ) { + class_alias( $class_alias_name, $class ); + } + } + + public static function get_frontend_file_url( $frontend_file_name, $custom_file ) { + if ( $custom_file ) { + $frontend_file = self::get_frontend_file( $frontend_file_name ); + + $frontend_file_url = $frontend_file->get_url(); + } else { + $frontend_file_url = ELEMENTOR_PRO_ASSETS_URL . 'css/' . $frontend_file_name; + } + + return $frontend_file_url; + } + + public static function get_frontend_file_path( $frontend_file_name, $custom_file ) { + if ( $custom_file ) { + $frontend_file = self::get_frontend_file( $frontend_file_name ); + + $frontend_file_path = $frontend_file->get_path(); + } else { + $frontend_file_path = ELEMENTOR_PRO_ASSETS_PATH . 'css/' . $frontend_file_name; + } + + return $frontend_file_path; + } + + /** + * @deprecated 3.26.0 + * @return void + */ + public function enqueue_styles(): void {} + + public function enqueue_frontend_scripts() { + $suffix = $this->get_assets_suffix(); + + wp_enqueue_script( + 'elementor-pro-frontend', + ELEMENTOR_PRO_URL . 'assets/js/frontend' . $suffix . '.js', + $this->get_frontend_depends(), + ELEMENTOR_PRO_VERSION, + true + ); + + wp_set_script_translations( 'elementor-pro-frontend', 'elementor-pro', ELEMENTOR_PRO_PATH . 'languages' ); + + wp_enqueue_script( 'pro-elements-handlers' ); + + $assets_url = ELEMENTOR_PRO_ASSETS_URL; + + /** + * Elementor Pro assets URL. + * + * Filters the assets URL used by Elementor Pro. + * + * By default Elementor Pro assets URL is set by the ELEMENTOR_PRO_ASSETS_URL + * constant. This hook allows developers to change this URL. + * + * @param string $assets_url Elementor Pro assets URL. + */ + $assets_url = apply_filters( 'elementor_pro/frontend/assets_url', $assets_url ); + + $locale_settings = [ + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'elementor-pro-frontend' ), + 'urls' => [ + 'assets' => $assets_url, + 'rest' => get_rest_url(), + ], + 'settings' => [ + 'lazy_load_background_images' => ( '1' === get_option( 'elementor_lazy_load_background_images', '1' ) ), + ], + ]; + + /** + * Localized frontend settings. + * + * Filters the localized settings used in the frontend as JavaScript variables. + * + * By default Elementor Pro passes some frontend settings to be consumed as JavaScript + * variables. This hook allows developers to add extra settings values to be consumed + * using JavaScript in the frontend. + * + * @since 1.0.0 + * + * @param array $locale_settings Localized frontend settings. + */ + $locale_settings = apply_filters( 'elementor_pro/frontend/localize_settings', $locale_settings ); + + Utils::print_js_config( + 'elementor-pro-frontend', + 'ElementorProFrontendConfig', + $locale_settings + ); + } + + public function register_frontend_scripts() { + $suffix = $this->get_assets_suffix(); + + wp_register_script( + 'elementor-pro-webpack-runtime', + ELEMENTOR_PRO_URL . 'assets/js/webpack-pro.runtime' . $suffix . '.js', + [], + ELEMENTOR_PRO_VERSION, + true + ); + + wp_register_script( + 'pro-elements-handlers', + ELEMENTOR_PRO_URL . 'assets/js/elements-handlers' . $suffix . '.js', + [ + 'elementor-frontend', + ], + ELEMENTOR_PRO_VERSION, + true + ); + + wp_register_script( + 'smartmenus', + ELEMENTOR_PRO_URL . 'assets/lib/smartmenus/jquery.smartmenus' . $suffix . '.js', + [ + 'jquery', + ], + '1.2.1', + true + ); + + $sticky_handle = $this->is_assets_loader_exist() ? 'e-sticky' : 'elementor-sticky'; + + wp_register_script( + $sticky_handle, + ELEMENTOR_PRO_URL . 'assets/lib/sticky/jquery.sticky' . $suffix . '.js', + [ + 'jquery', + ], + ELEMENTOR_PRO_VERSION, + true + ); + + if ( $this->is_assets_loader_exist() ) { + $this->register_assets(); + } + } + + public function register_preview_scripts() { + $suffix = $this->get_assets_suffix(); + + wp_enqueue_script( + 'elementor-pro-preview', + ELEMENTOR_PRO_URL . 'assets/js/preview' . $suffix . '.js', + [ + 'wp-i18n', + 'elementor-frontend', + ], + ELEMENTOR_PRO_VERSION, + true + ); + } + + public function get_responsive_stylesheet_templates( $templates ) { + $templates_paths = glob( $this->get_responsive_templates_path() . '*.css' ); + + foreach ( $templates_paths as $template_path ) { + $file_name = 'custom-pro-' . basename( $template_path ); + + $templates[ $file_name ] = $template_path; + } + + return $templates; + } + + public function on_elementor_init() { + $this->modules_manager = new Modules_Manager(); + + /** TODO: BC for Elementor v2.4.0 */ + if ( class_exists( '\Elementor\Core\Upgrade\Manager' ) ) { + $this->upgrade = UpgradeManager::instance(); + } + + /** + * Elementor Pro init. + * + * Fires on Elementor Pro initiation, after Elementor has finished loading + * but before any headers are sent. + * + * @since 1.0.0 + */ + do_action( 'elementor_pro/init' ); + } + + /** + * @param \Elementor\Core\Base\Document $document + */ + public function on_document_save_version( $document ) { + $document->update_meta( '_elementor_pro_version', ELEMENTOR_PRO_VERSION ); + } + + private function get_frontend_depends() { + $frontend_depends = [ + 'elementor-pro-webpack-runtime', + 'elementor-frontend-modules', + ]; + + if ( ! $this->is_assets_loader_exist() ) { + $frontend_depends[] = 'elementor-sticky'; + } + + return $frontend_depends; + } + + private static function get_responsive_templates_path() { + return ELEMENTOR_PRO_ASSETS_PATH . 'css/templates/'; + } + + private function add_subscription_template_access_level_to_settings( $settings ) { + // Core >= 3.2.0 + if ( isset( $settings['library_connect']['current_access_level'] ) ) { + $settings['library_connect']['current_access_level'] = API::get_library_access_level(); + } + + // Core >= 3.18.0 + if ( isset( $settings['library_connect']['current_access_tier'] ) ) { + $settings['library_connect']['current_access_tier'] = API::get_access_tier(); + } + + // Core >= 3.32.0 + if ( isset( $settings['library_connect']['plan_type'] ) ) { + $settings['library_connect']['plan_type'] = API::get_plan_type(); + } + + return $settings; + } + + private function setup_hooks() { + add_action( 'elementor/init', [ $this, 'on_elementor_init' ] ); + + add_action( 'elementor/frontend/before_register_scripts', [ $this, 'register_frontend_scripts' ] ); + add_action( 'elementor/preview/enqueue_scripts', [ $this, 'register_preview_scripts' ] ); + + add_action( 'elementor/frontend/before_enqueue_scripts', [ $this, 'enqueue_frontend_scripts' ] ); + + add_filter( 'elementor/core/breakpoints/get_stylesheet_template', [ $this, 'get_responsive_stylesheet_templates' ] ); + add_action( 'elementor/document/save_version', [ $this, 'on_document_save_version' ] ); + + add_filter( 'elementor/editor/localize_settings', function ( $settings ) { + return $this->add_subscription_template_access_level_to_settings( $settings ); + }, 11 /** After Elementor Core (Library) */ ); + + add_filter( 'elementor/common/localize_settings', function ( $settings ) { + return $this->add_subscription_template_access_level_to_settings( $settings ); + }, 11 /** After Elementor Core (Library) */ ); + } + + private function get_assets() { + $suffix = $this->get_assets_suffix(); + + return [ + 'scripts' => [ + 'e-sticky' => [ + 'src' => ELEMENTOR_PRO_URL . 'assets/lib/sticky/jquery.sticky' . $suffix . '.js', + 'version' => ELEMENTOR_PRO_VERSION, + 'dependencies' => [ + 'jquery', + ], + ], + ], + ]; + } + + private function register_assets() { + $assets = $this->get_assets(); + + if ( $assets ) { + self::elementor()->assets_loader->add_assets( $assets ); + } + } + + private function is_assets_loader_exist() { + return ! ! self::elementor()->assets_loader; + } + + /** + * Plugin constructor. + * @throws Exception + */ + private function __construct() { + spl_autoload_register( [ $this, 'autoload' ] ); + + Compatibility::register_actions(); + + new Connect\Manager(); + + $this->setup_hooks(); + + $this->editor = new Editor(); + + $this->preview = new Preview(); + + $this->app = new App(); + + $this->license_admin = new License\Admin(); + + $this->php_api = new PHP_Api(); + + $this->license_admin->register_actions(); + + if ( is_user_logged_in() ) { + $this->integrations = new Integrations_Manager(); // TODO: This one is safe to move out of the condition. + + $this->notifications = new Notifications_Manager(); + + + + if ( is_admin() ) { + $this->admin = new Admin(); + + require_once __DIR__ . '/updater/updater.php'; + $config = array( + 'slug' => 'pro-elements.php', + 'plugin_basename' => ELEMENTOR_PRO_PLUGIN_BASE, + 'proper_folder_name' => 'pro-elements', + 'api_url' => 'https://api.github.com/repos/proelements/proelements', + 'raw_url' => 'https://raw.githubusercontent.com/proelements/proelements/master', + 'github_url' => 'https://github.com/proelements/proelements', + 'zip_url' => 'https://github.com/proelements/proelements/archive/v{release_version}.zip', + 'sslverify' => true, + 'requires' => '5.0', + 'tested' => '5.4.2', + 'readme' => 'README.md', + 'access_token' => '', + ); + new Updater( $config ); + } + + Maintenance::init(); + } + } + + private function get_assets_suffix() { + return Utils::is_script_debug() ? '' : '.min'; + } + + private static function get_frontend_file( $frontend_file_name ) { + $template_file_path = self::get_responsive_templates_path() . $frontend_file_name; + + return self::elementor()->frontend->get_frontend_file( $frontend_file_name, 'custom-pro-', $template_file_path ); + } + + final public static function get_title() { + return esc_html__( 'Pro Elements', 'elementor-pro' ); + } +} + +if ( ! defined( 'ELEMENTOR_PRO_TESTS' ) ) { + // In tests we run the instance manually. + Plugin::instance(); +} diff --git a/pro-elements.php b/pro-elements.php new file mode 100644 index 00000000..6df8c70e --- /dev/null +++ b/pro-elements.php @@ -0,0 +1,187 @@ +=' ) ) { + add_action( 'admin_notices', 'pro_elements_plugin_fail_load_out_of_date' ); + + return; + } + + if ( ! pro_elements_compare_major_version( $core_version, $core_version_recommended, '>=' ) ) { + add_action( 'admin_notices', 'pro_elements_admin_notice_upgrade_recommendation' ); + } + + require ELEMENTOR_PRO_PATH . 'plugin.php'; +} + +function pro_elements_compare_major_version( $left, $right, $operator ) { + $pattern = '/^(\d+\.\d+).*/'; + $replace = '$1.0'; + + $left = preg_replace( $pattern, $replace, $left ); + $right = preg_replace( $pattern, $replace, $right ); + + return version_compare( $left, $right, $operator ); +} + +pro_elements_plugin_load_plugin(); + +function pro_elements_print_error( $message ) { + if ( ! $message ) { + return; + } + // PHPCS - $message should not be escaped + echo '
                ' . $message . '
                '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} +/** + * Show in WP Dashboard notice about the plugin is not activated. + * + * @since 1.0.0 + * + * @return void + */ +function pro_elements_plugin_fail_load() { + $screen = get_current_screen(); + if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) { + return; + } + + $plugin = 'elementor/elementor.php'; + + if ( _is_elementor_installed() ) { + if ( ! current_user_can( 'activate_plugins' ) ) { + return; + } + + $activation_url = wp_nonce_url( 'plugins.php?action=activate&plugin=' . $plugin . '&plugin_status=all&paged=1&s', 'activate-plugin_' . $plugin ); + + $message = '

                ' . esc_html__( 'You\'re not using PRO Elements yet!', 'elementor-pro' ) . '

                '; + $message .= '

                ' . esc_html__( 'Activate the Elementor plugin to start using all of PRO Elements plugin’s features.', 'elementor-pro' ) . '

                '; + $message .= '

                ' . sprintf( '%s', $activation_url, esc_html__( 'Activate Now', 'elementor-pro' ) ) . '

                '; + } else { + if ( ! current_user_can( 'install_plugins' ) ) { + return; + } + + $install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=elementor' ), 'install-plugin_elementor' ); + + $message = '

                ' . esc_html__( 'PRO Elements plugin requires installing the Elementor plugin', 'elementor-pro' ) . '

                '; + $message .= '

                ' . esc_html__( 'Install and activate the Elementor plugin to access all PRO Elements features.', 'elementor-pro' ) . '

                '; + $message .= '

                ' . sprintf( '%s', $install_url, esc_html__( 'Install Now', 'elementor-pro' ) ) . '

                '; + } + + pro_elements_print_error($message); +} + +function pro_elements_plugin_fail_load_out_of_date() { + if ( ! current_user_can( 'update_plugins' ) ) { + return; + } + + $file_path = 'elementor/elementor.php'; + + $upgrade_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file_path, 'upgrade-plugin_' . $file_path ); + $message = sprintf( + /* translators: 1: Title opening tag, 2: Title closing tag */ + esc_html__( '%1$ssPRO Elements requires newer version of the Elementor plugin%2$s Update the Elementor plugin to reactivate the Pro Elements plugin.', 'elementor-pro' ), + '

                ', + '

                ' + ); + $message .= '

                ' . sprintf( '%s', $upgrade_link, esc_html__( 'Update Now', 'elementor-pro' ) ) . '

                '; + + pro_elements_print_error($message); +} + +function pro_elements_admin_notice_upgrade_recommendation() { + if ( ! current_user_can( 'update_plugins' ) ) { + return; + } + + $file_path = 'elementor/elementor.php'; + + $upgrade_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file_path, 'upgrade-plugin_' . $file_path ); + $message = sprintf( + /* translators: 1: Title opening tag, 2: Title closing tag */ + esc_html__( '%1$sDon’t miss out on the new version of Elementor%2$s Update to the latest version of Elementor to enjoy new features, better performance and compatibility.', 'elementor-pro' ), + '

                ', + '

                ' + ); + $message .= '

                ' . sprintf( '%s', $upgrade_link, esc_html__( 'Update Now', 'elementor-pro' ) ) . '

                '; + + pro_elements_print_error($message); +} + +if ( ! function_exists( '_is_elementor_installed' ) ) { + + function _is_elementor_installed() { + $file_path = 'elementor/elementor.php'; + $installed_plugins = get_plugins(); + + return isset( $installed_plugins[ $file_path ] ); + } +} diff --git a/run-on-linux.js b/run-on-linux.js new file mode 100644 index 00000000..eb15d08e --- /dev/null +++ b/run-on-linux.js @@ -0,0 +1,44 @@ +const { spawn, exec } = require( 'child_process' ); +const packageJson = require( './package.json' ); + +function isDockerExist() { + return new Promise( ( resolve ) => { + exec( 'docker -v', ( error ) => { + resolve( ! error ); + } ); + } ); +} + +async function run( tag ) { + const playwrightVersion = packageJson.devDependencies[ '@playwright/test' ]; + const workingDir = process.cwd(); + + const command = 'docker run'; + const options = [ + '--rm', + '--network host', + `--volume ${ workingDir }:/work`, + '--workdir /work/', + '--interactive', + process.env.CI ? '' : '--tty', + ]; + const image = `mcr.microsoft.com/playwright:v${ playwrightVersion.replace( '^', '' ) }-jammy`; + const commandToRun = `/bin/bash -c "npm run test:playwright -- --grep="${ tag }""`; + + spawn( `${ command } ${ options.join( ' ' ) } ${ image } ${ commandToRun }`, { + stdio: 'inherit', + stderr: 'inherit', + shell: true, + } ); +} + +( async () => { + if ( ! await isDockerExist() ) { + // eslint-disable-next-line no-console + console.error( 'Docker is not installed, please install it first.' ); + + process.exit( 1 ); + } + + await run( process.argv.slice( 2 ) ); +} )(); diff --git a/sample-data/acf-extra-post-fields.json b/sample-data/acf-extra-post-fields.json new file mode 100644 index 00000000..8344f6a5 --- /dev/null +++ b/sample-data/acf-extra-post-fields.json @@ -0,0 +1,71 @@ +[ + { + "key": "group_65f84bafe0536", + "title": "Taxonomy Extras", + "fields": [ + { + "key": "field_65f84bb059d4d", + "label": "Custom Text", + "name": "custom_text", + "aria-label": "", + "type": "text", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "maxlength": "", + "placeholder": "", + "prepend": "", + "append": "" + }, + { + "key": "field_65f84be959d4e", + "label": "Taxonomy Image", + "name": "taxonomy_image", + "aria-label": "", + "type": "image", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "return_format": "array", + "library": "all", + "min_width": "", + "min_height": "", + "min_size": "", + "max_width": "", + "max_height": "", + "max_size": "", + "mime_types": "", + "preview_size": "medium" + } + ], + "location": [ + [ + { + "param": "taxonomy", + "operator": "==", + "value": "all" + } + ] + ], + "menu_order": 0, + "position": "normal", + "style": "default", + "label_placement": "top", + "instruction_placement": "label", + "hide_on_screen": "", + "active": true, + "description": "", + "show_in_rest": 1 + } +] diff --git a/sample-data/acf-fields-products.json b/sample-data/acf-fields-products.json new file mode 100644 index 00000000..ae3fb802 --- /dev/null +++ b/sample-data/acf-fields-products.json @@ -0,0 +1,68 @@ +[ + { + "key": "group_63db85f18df07", + "title": "Products", + "fields": [ + { + "key": "field_63db85f2d1709", + "label": "Test Image", + "name": "test_image", + "aria-label": "", + "type": "image", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "return_format": "array", + "library": "all", + "min_width": "", + "min_height": "", + "min_size": "", + "max_width": "", + "max_height": "", + "max_size": "", + "mime_types": "", + "preview_size": "medium" + }, + { + "key": "field_63dcef444bbde", + "label": "Test Video", + "name": "test_video", + "aria-label": "", + "type": "url", + "instructions": "", + "required": 0, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "default_value": "", + "placeholder": "" + } + ], + "location": [ + [ + { + "param": "post_type", + "operator": "==", + "value": "product" + } + ] + ], + "menu_order": 0, + "position": "normal", + "style": "default", + "label_placement": "top", + "instruction_placement": "label", + "hide_on_screen": "", + "active": true, + "description": "", + "show_in_rest": 0 + } +] \ No newline at end of file diff --git a/sample-data/sample_products_with_acf_meta.xml b/sample-data/sample_products_with_acf_meta.xml new file mode 100644 index 00000000..ff7f73fe --- /dev/null +++ b/sample-data/sample_products_with_acf_meta.xml @@ -0,0 +1,4904 @@ + + + + + + WooCommerce Demo Store + http: + Just another WooCommerce store + Wed, 16 Jan 2019 13:09:24 +0000 + en-US + 1.2 + http: + http: + + 1 + shopmanager + info@woocommerce.com + + + + + https://wordpress.org/?v=5.0.3 + + V-Neck T-Shirt + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/ + + + + 6 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + v-neck-t-shirt + publish + 0 + 0 + product + + 0 + + + + + + + + + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _thumbnail_id + + + + _price + + + + _price + + + + _regular_price + + + + _sale_price + + + + + Hoodie + https://woocommercecore.mystagingwebsite.com/product/hoodie/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie/ + + + + 7 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + hoodie + publish + 0 + 0 + product + + 0 + + + + + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _thumbnail_id + + + + _price + + + + _price + + + + _regular_price + + + + _sale_price + + + + + Hoodie with Logo + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-logo/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-logo/ + + + + 8 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + hoodie-with-logo + publish + 0 + 0 + product + + 0 + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + T-Shirt Hebrew + https://woocommercecore.mystagingwebsite.com/product/t-shirt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/t-shirt/ + + + + 9 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + t-shirt + publish + 0 + 0 + product + + 0 + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Beanie + https://woocommercecore.mystagingwebsite.com/product/beanie/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/beanie/ + + + + 10 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + beanie + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Belt + https://woocommercecore.mystagingwebsite.com/product/belt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/belt/ + + + + 11 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + belt + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Cap + https://woocommercecore.mystagingwebsite.com/product/cap/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/cap/ + + + + 12 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + cap + publish + 0 + 0 + product + + 0 + + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Sunglasses + https://woocommercecore.mystagingwebsite.com/product/sunglasses/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/sunglasses/ + + + + 13 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + sunglasses + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Hoodie with Pocket + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-pocket/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-pocket/ + + + + 14 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + hoodie-with-pocket + publish + 0 + 0 + product + + 0 + + + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Hoodie with Zipper + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-zipper/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-zipper/ + + + + 15 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + hoodie-with-zipper + publish + 0 + 0 + product + + 0 + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Long Sleeve Tee + https://woocommercecore.mystagingwebsite.com/product/long-sleeve-tee/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/long-sleeve-tee/ + + + + 16 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + long-sleeve-tee + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Polo + https://woocommercecore.mystagingwebsite.com/product/polo/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/polo/ + + + + 17 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + polo + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Album + https://woocommercecore.mystagingwebsite.com/product/album/ + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/album/ + + + + 18 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + open + closed + album + publish + 0 + 0 + product + + 0 + + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Single + https://woocommercecore.mystagingwebsite.com/product/single/ + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/single/ + + + + 19 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + open + closed + single + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + V-Neck T-Shirt - Red + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=red + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-red/ + + + + 20 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-red + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + V-Neck T-Shirt - Green + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=green + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-green/ + + + + 21 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-green + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + V-Neck T-Shirt - Blue + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=blue + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-blue/ + + + + 22 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-blue + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _wpcom_is_markdown + + + + _wp_old_slug + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + Hoodie - Red, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=red&attribute_logo=no + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-red-no + + + + 23 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + hoodie-red-no + publish + 7 + 1 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + Hoodie - Green, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=green&attribute_logo=No + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-green-no/ + + + + 24 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + hoodie-green-no + publish + 7 + 2 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + Hoodie - Blue, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=blue&attribute_logo=No + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-blue-no + + + + 25 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + closed + closed + hoodie-blue-no + publish + 7 + 3 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + T-Shirt with Logo + https://woocommercecore.mystagingwebsite.com/product/t-shirt-with-logo/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/t-shirt-with-logo/ + + + + 26 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + t-shirt-with-logo + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Beanie with Logo + https://woocommercecore.mystagingwebsite.com/product/beanie-with-logo/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/beanie-with-logo/ + + + + 27 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + beanie-with-logo + publish + 0 + 0 + product + + 0 + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + + + + + + + + + + + + + + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + + + + + + + + + Logo Collection + https://woocommercecore.mystagingwebsite.com/product/logo-collection/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/logo-collection/ + + + + 28 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + logo-collection + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _children + + + + _thumbnail_id + + + + _price + + + + _price + + + + + + + + + + + + + WordPress Pennant + https://woocommercecore.mystagingwebsite.com/product/wordpress-pennant/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/wordpress-pennant/ + + + + 29 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + wordpress-pennant + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + _product_url + + + + _button_text + + + + + + + + + + + + + Hoodie - Blue, Yes + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=blue&attribute_logo=Yes + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-blue-yes/ + + + + 30 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + closed + closed + hoodie-blue-yes + publish + 7 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + vneck-tee-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=31 + Wed, 16 Jan 2019 13:01:56 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg + + + + 31 + 2019-01-16 13:01:56 + 2019-01-16 13:01:56 + open + closed + vneck-tee-2-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg + + _wc_attachment_source + + + + + vnech-tee-green-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=32 + Wed, 16 Jan 2019 13:01:57 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg + + + + 32 + 2019-01-16 13:01:57 + 2019-01-16 13:01:57 + open + closed + vnech-tee-green-1-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg + + _wc_attachment_source + + + + + vnech-tee-blue-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=33 + Wed, 16 Jan 2019 13:01:58 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg + + + + 33 + 2019-01-16 13:01:58 + 2019-01-16 13:01:58 + open + closed + vnech-tee-blue-1-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg + + _wc_attachment_source + + + + + hoodie-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=34 + Wed, 16 Jan 2019 13:01:58 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg + + + + 34 + 2019-01-16 13:01:58 + 2019-01-16 13:01:58 + open + closed + hoodie-2-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg + + _wc_attachment_source + + + + + hoodie-blue-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=35 + Wed, 16 Jan 2019 13:01:59 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg + + + + 35 + 2019-01-16 13:01:59 + 2019-01-16 13:01:59 + open + closed + hoodie-blue-1-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg + + _wc_attachment_source + + + + + hoodie-green-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=36 + Wed, 16 Jan 2019 13:02:00 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg + + + + 36 + 2019-01-16 13:02:00 + 2019-01-16 13:02:00 + open + closed + hoodie-green-1-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg + + _wc_attachment_source + + + + + hoodie-with-logo-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=37 + Wed, 16 Jan 2019 13:02:01 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg + + + + 37 + 2019-01-16 13:02:01 + 2019-01-16 13:02:01 + open + closed + hoodie-with-logo-2-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg + + _wc_attachment_source + + + + + tshirt-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=38 + Wed, 16 Jan 2019 13:02:02 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/tshirt-2.jpg + + + + 38 + 2019-01-16 13:02:02 + 2019-01-16 13:02:02 + open + closed + tshirt-2-jpg + inherit + 9 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/tshirt-2.jpg + + _wc_attachment_source + + + + + beanie-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=39 + Wed, 16 Jan 2019 13:02:02 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-2.jpg + + + + 39 + 2019-01-16 13:02:02 + 2019-01-16 13:02:02 + open + closed + beanie-2-jpg + inherit + 10 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-2.jpg + + _wc_attachment_source + + + + + belt-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=40 + Wed, 16 Jan 2019 13:02:03 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/belt-2.jpg + + + + 40 + 2019-01-16 13:02:03 + 2019-01-16 13:02:03 + open + closed + belt-2-jpg + inherit + 11 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/belt-2.jpg + + _wc_attachment_source + + + + + cap-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=41 + Wed, 16 Jan 2019 13:02:04 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/cap-2.jpg + + + + 41 + 2019-01-16 13:02:04 + 2019-01-16 13:02:04 + open + closed + cap-2-jpg + inherit + 12 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/cap-2.jpg + + _wc_attachment_source + + + + + sunglasses-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=42 + Wed, 16 Jan 2019 13:02:05 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/sunglasses-2.jpg + + + + 42 + 2019-01-16 13:02:05 + 2019-01-16 13:02:05 + open + closed + sunglasses-2-jpg + inherit + 13 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/sunglasses-2.jpg + + _wc_attachment_source + + + + + hoodie-with-pocket-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=43 + Wed, 16 Jan 2019 13:02:06 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-pocket-2.jpg + + + + 43 + 2019-01-16 13:02:06 + 2019-01-16 13:02:06 + open + closed + hoodie-with-pocket-2-jpg + inherit + 14 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-pocket-2.jpg + + _wc_attachment_source + + + + + hoodie-with-zipper-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=44 + Wed, 16 Jan 2019 13:02:06 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-zipper-2.jpg + + + + 44 + 2019-01-16 13:02:06 + 2019-01-16 13:02:06 + open + closed + hoodie-with-zipper-2-jpg + inherit + 15 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-zipper-2.jpg + + _wc_attachment_source + + + + + long-sleeve-tee-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=45 + Wed, 16 Jan 2019 13:02:07 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/long-sleeve-tee-2.jpg + + + + 45 + 2019-01-16 13:02:07 + 2019-01-16 13:02:07 + open + closed + long-sleeve-tee-2-jpg + inherit + 16 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/long-sleeve-tee-2.jpg + + _wc_attachment_source + + + + + polo-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=46 + Wed, 16 Jan 2019 13:02:08 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/polo-2.jpg + + + + 46 + 2019-01-16 13:02:08 + 2019-01-16 13:02:08 + open + closed + polo-2-jpg + inherit + 17 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/polo-2.jpg + + _wc_attachment_source + + + + + album-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=47 + Wed, 16 Jan 2019 13:02:09 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2022/05/album-1.jpg + + + + 47 + 2019-01-16 13:02:09 + 2019-01-16 13:02:09 + open + closed + album-1-jpg + inherit + 18 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2022/05/album-1.jpg + + _wc_attachment_source + + + + + single-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=48 + Wed, 16 Jan 2019 13:02:10 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/single-1.jpg + + + + 48 + 2019-01-16 13:02:10 + 2019-01-16 13:02:10 + open + closed + single-1-jpg + inherit + 19 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/single-1.jpg + + _wc_attachment_source + + + + + t-shirt-with-logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=49 + Wed, 16 Jan 2019 13:02:11 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg + + + + 49 + 2019-01-16 13:02:11 + 2019-01-16 13:02:11 + open + closed + t-shirt-with-logo-1-jpg + inherit + 26 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg + + _wc_attachment_source + + + + + beanie-with-logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=50 + Wed, 16 Jan 2019 13:02:12 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg + + + + 50 + 2019-01-16 13:02:12 + 2019-01-16 13:02:12 + open + closed + beanie-with-logo-1-jpg + inherit + 27 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg + + _wc_attachment_source + + + + + logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=51 + Wed, 16 Jan 2019 13:02:13 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/logo-1.jpg + + + + 51 + 2019-01-16 13:02:13 + 2019-01-16 13:02:13 + open + closed + logo-1-jpg + inherit + 28 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/logo-1.jpg + + _wc_attachment_source + + + + + pennant-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=52 + Wed, 16 Jan 2019 13:02:13 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/pennant-1.jpg + + + + 52 + 2019-01-16 13:02:13 + 2019-01-16 13:02:13 + open + closed + pennant-1-jpg + inherit + 29 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/pennant-1.jpg + + _wc_attachment_source + + + + + diff --git a/sample-data/simple-taxonomy-loop-template.json b/sample-data/simple-taxonomy-loop-template.json new file mode 100644 index 00000000..8e8dee54 --- /dev/null +++ b/sample-data/simple-taxonomy-loop-template.json @@ -0,0 +1 @@ +{"content":[{"id":"ba28a8c","settings":[],"elements":[{"id":"59717e2b","settings":{"title":"Add Your Heading Text Here","align":"center","title_color":"#E46EC0","typography_typography":"custom","typography_font_family":"Assistant","typography_font_weight":"700","typography_text_transform":"uppercase","text_stroke_text_stroke":{"unit":"px","size":0,"sizes":[]},"_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"title":"[elementor-tag id=\"fddf42e\" name=\"archive-title\" settings=\"%7B%7D\"]"}},"elements":[],"isInner":false,"widgetType":"heading","elType":"widget"},{"id":"1f3c48a4","settings":{"text_columns":"1","align":"center","_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"editor":"[elementor-tag id=\"76b1db6\" name=\"archive-description\" settings=\"%7B%7D\"]"}},"elements":[],"isInner":false,"widgetType":"text-editor","elType":"widget"},{"id":"28993854","settings":{"_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"image":"[elementor-tag id=\"e1425e3\" name=\"woocommerce-category-image-tag\" settings=\"%7B%7D\"]"},"image":{"id":69,"url":"http:\/\/wordpress-dev.local\/wp-content\/uploads\/2024\/03\/placeholder.png"}},"elements":[],"isInner":false,"widgetType":"image","elType":"widget"},{"id":"4038b812","settings":{"width":{"unit":"%","size":100,"sizes":[]},"_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"image":"[elementor-tag id=\"b6ac506\" name=\"acf-image\" settings=\"%7B%22key%22%3A%22field_65f84be959d4e%3Ataxonomy_image%22%7D\"]"},"image":{"id":70,"url":"http:\/\/wordpress-dev.local\/wp-content\/uploads\/2024\/03\/placeholder-1.png"}},"elements":[],"isInner":false,"widgetType":"image","elType":"widget"},{"id":"46ec20a8","settings":{"align":"center","text_color":"#473C3C","typography_typography":"custom","typography_font_family":"Roboto","typography_font_size":{"unit":"px","size":24,"sizes":[]},"typography_font_weight":"400","typography_text_transform":"capitalize","typography_letter_spacing":{"unit":"px","size":0.10000000000000001,"sizes":[]},"typography_word_spacing":{"unit":"px","size":11,"sizes":[]},"_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"editor":"[elementor-tag id=\"e50714a\" name=\"acf-text\" settings=\"%7B%22key%22%3A%22field_65f84bb059d4d%3Acustom_text%22%7D\"]"}},"elements":[],"isInner":false,"widgetType":"text-editor","elType":"widget"},{"id":"255d6f31","settings":{"text":"Click here","align":"justify","typography_typography":"custom","typography_font_family":"Assistant","typography_font_size":{"unit":"px","size":21,"sizes":[]},"typography_font_weight":"300","typography_text_transform":"uppercase","typography_letter_spacing":{"unit":"px","size":1.8999999999999999,"sizes":[]},"typography_word_spacing":{"unit":"px","size":8,"sizes":[]},"background_color":"#CE61B2","_padding":{"unit":"%","top":"0","right":"4","bottom":"0","left":"4","isLinked":false},"_padding_widescreen":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_laptop":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_tablet":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile_extra":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"_padding_mobile":{"unit":"%","top":"","right":"","bottom":"","left":"","isLinked":true},"__dynamic__":{"link":"[elementor-tag id=\"74247d7\" name=\"archive-url\" settings=\"%7B%7D\"]"}},"elements":[],"isInner":false,"widgetType":"button","elType":"widget"}],"isInner":false,"elType":"container"}],"page_settings":{"preview_id":"1244"},"version":"0.4","title":"TaxonomyTemplate","type":"loop-item"} \ No newline at end of file diff --git a/updater/updater.php b/updater/updater.php new file mode 100644 index 00000000..ff9e24b9 --- /dev/null +++ b/updater/updater.php @@ -0,0 +1,403 @@ + plugin_basename( __FILE__ ), + 'plugin_basename' => plugin_basename( __FILE__ ), + 'proper_folder_name' => dirname( plugin_basename( __FILE__ ) ), + 'sslverify' => true, + 'access_token' => '', + ); + + $this->config = wp_parse_args( $config, $defaults ); + + $this->set_defaults(); + + add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) , 100 ); + + // Hook into the plugin details screen + add_filter( 'plugins_api', array( $this, 'get_plugin_info' ), 10, 3 ); + add_filter( 'upgrader_post_install', array( $this, 'upgrader_post_install' ), 10, 3 ); + + // set timeout + add_filter( 'http_request_timeout', array( $this, 'http_request_timeout' ) ); + + // set sslverify for zip download + add_filter( 'http_request_args', array( $this, 'http_request_sslverify' ), 10, 2 ); + } + + + /** + * Check wether or not the transients need to be overruled and API needs to be called for every single page load + * + * @return bool overrule or not + */ + public function overrule_transients() { + global $pagenow; + if ( 'update-core.php' === $pagenow && isset( $_GET['force-check'] ) ) { + return true; + } + return ( defined( 'WP_GITHUB_FORCE_UPDATE' ) && WP_GITHUB_FORCE_UPDATE ); + } + + + /** + * Set defaults + * + * @since 1.2 + * @return void + */ + public function set_defaults() { + if ( !empty( $this->config['access_token'] ) ) { + + extract( parse_url( $this->config['zip_url'] ) ); // $scheme, $host, $path + + $zip_url = $scheme . '://api.github.com/repos' . $path; + $zip_url = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $zip_url ); + + $this->config['zip_url'] = $zip_url; + } + + + if ( ! isset( $this->config['new_version'] ) ) + $this->config['new_version'] = $this->get_new_version(); + + if ( ! isset( $this->config['last_updated'] ) ) + $this->config['last_updated'] = $this->get_date(); + + if ( ! isset( $this->config['description'] ) ) + $this->config['description'] = $this->get_description(); + + $plugin_data = $this->get_plugin_data(); + if ( ! isset( $this->config['plugin_name'] ) ) + $this->config['plugin_name'] = $plugin_data['Name']; + + if ( ! isset( $this->config['version'] ) ) + $this->config['version'] = $plugin_data['Version']; + + if ( ! isset( $this->config['author'] ) ) + $this->config['author'] = $plugin_data['Author']; + + if ( ! isset( $this->config['homepage'] ) ) + $this->config['homepage'] = $plugin_data['PluginURI']; + + if ( ! isset( $this->config['readme'] ) ) + $this->config['readme'] = 'README.md'; + + } + + + /** + * Callback fn for the http_request_timeout filter + * + * @since 1.0 + * @return int timeout value + */ + public function http_request_timeout() { + return 2; + } + + /** + * Callback fn for the http_request_args filter + * + * @param unknown $args + * @param unknown $url + * + * @return mixed + */ + public function http_request_sslverify( $args, $url ) { + if ( $this->get_zip_url() == $url ) + $args[ 'sslverify' ] = $this->config[ 'sslverify' ]; + + return $args; + } + + private function get_zip_url() { + return $prev_icon_class = str_replace( '{release_version}', $this->config['new_version'], $this->config[ 'zip_url' ] ); + } + + /** + * Get New Version from GitHub + * + * @since 1.0 + * @return int $version the version number + */ + public function get_new_version() { + $version = get_site_transient( md5($this->config['slug']).'_new_version' ); + + if ( $this->overrule_transients() || ( !isset( $version ) || !$version || '' == $version ) ) { + + $raw_response = $this->remote_get( trailingslashit( $this->config['raw_url'] ) . basename( $this->config['slug'] ) ); + + if ( is_wp_error( $raw_response ) ) + $version = false; + + if (is_array($raw_response)) { + if (!empty($raw_response['body'])) + preg_match( '/.*Version\:\s*(.*)$/mi', $raw_response['body'], $matches ); + } + + if ( empty( $matches[1] ) ) + $version = false; + else + $version = $matches[1]; + + // back compat for older readme version handling + // only done when there is no version found in file name + if ( false === $version ) { + $raw_response = $this->remote_get( trailingslashit( $this->config['raw_url'] ) . $this->config['readme'] ); + + if ( is_wp_error( $raw_response ) ) + return $version; + + preg_match( '#^\s*`*~Current Version\:\s*([^~]*)~#im', $raw_response['body'], $__version ); + + if ( isset( $__version[1] ) ) { + $version_readme = $__version[1]; + if ( -1 == version_compare( $version, $version_readme ) ) + $version = $version_readme; + } + } + + // refresh every 6 hours + if ( false !== $version ) + set_site_transient( md5($this->config['slug']).'_new_version', $version, 60*60*6 ); + } + + return $version; + } + + + /** + * Interact with GitHub + * + * @param string $query + * + * @since 1.6 + * @return mixed + */ + public function remote_get( $query ) { + if ( ! empty( $this->config['access_token'] ) ) + $query = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $query ); + + $raw_response = wp_remote_get( $query, array( + 'sslverify' => $this->config['sslverify'] + ) ); + + return $raw_response; + } + + + /** + * Get GitHub Data from the specified repository + * + * @since 1.0 + * @return array $github_data the data + */ + public function get_github_data() { + if ( isset( $this->github_data ) && ! empty( $this->github_data ) ) { + $github_data = $this->github_data; + } else { + $github_data = get_site_transient( md5($this->config['slug']).'_github_data' ); + + if ( $this->overrule_transients() || ( ! isset( $github_data ) || ! $github_data || '' == $github_data ) ) { + $github_data = $this->remote_get( $this->config['api_url'] ); + + if ( is_wp_error( $github_data ) ) + return false; + + $github_data = json_decode( $github_data['body'] ); + + // refresh every 6 hours + set_site_transient( md5($this->config['slug']).'_github_data', $github_data, 60*60*6 ); + } + + // Store the data in this class instance for future calls + $this->github_data = $github_data; + } + + return $github_data; + } + + + /** + * Get update date + * + * @since 1.0 + * @return string $date the date + */ + public function get_date() { + $_date = $this->get_github_data(); + return ( !empty( $_date->updated_at ) ) ? date( 'Y-m-d', strtotime( $_date->updated_at ) ) : false; + } + + + /** + * Get plugin description + * + * @since 1.0 + * @return string $description the description + */ + public function get_description() { + $_description = $this->get_github_data(); + return ( !empty( $_description->description ) ) ? $_description->description : false; + } + + + /** + * Get Plugin data + * + * @since 1.0 + * @return object $data the data + */ + public function get_plugin_data() { + if ( ! function_exists( 'get_plugin_data' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + $plugin_file = rtrim( WP_PLUGIN_DIR, '/' ) . '/' . $this->config['proper_folder_name'] . '/' . $this->config['slug'] ; + if ( ! is_file( $plugin_file ) ) { + return false; + } + $data = get_plugin_data( $plugin_file, false, false ); + return $data; + } + + + /** + * Hook into the plugin update check and connect to GitHub + * + * @since 1.0 + * @param object $transient the plugin data transient + * @return object $transient updated plugin data transient + */ + public function check_update( $transient ) { + + // Check if the transient contains the 'checked' information + // If not, just return its value without hacking it + global $pagenow; + + if ( ! is_object( $transient ) ) { + $transient = new \stdClass(); + } + + if ( 'plugins.php' === $pagenow && is_multisite() ) { + return $transient; + } + // check the version and decide if it's new + $update = version_compare( $this->config['new_version'], $this->config['version'] ); + + if ( 1 === $update ) { + if (! empty( $transient->checked ) ) { + $transient->last_checked = current_time( 'timestamp' ); + $transient->checked[ $this->config['plugin_basename'] ] = $this->config['new_version']; + } + + $response = new \stdClass(); + $response->new_version = $this->config['new_version']; + $response->plugin = $this->config['plugin_basename']; + $response->slug = $this->config['proper_folder_name']; + $response->url = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $this->config['github_url'] ); + $response->package = $this->get_zip_url(); + + // If response is false, don't alter the transient + if ( false !== $response ) + $transient->response[ $this->config['plugin_basename'] ] = $response; + } + + return $transient; + } + + + /** + * Get Plugin info + * + * @since 1.0 + * @param bool $false always false + * @param string $action the API function being performed + * @param object $args plugin arguments + * @return object $response the plugin info + */ + public function get_plugin_info( $data, $action, $args ) { + + // Check if this call API is for the right plugin + if ( !isset( $args->slug ) || $args->slug != $this->config['slug'] ) + return $data; + + $data->slug = $this->config['slug']; + $data->plugin_name = $this->config['plugin_name']; + $data->version = $this->config['new_version']; + $data->author = $this->config['author']; + $data->homepage = $this->config['homepage']; + $data->requires = $this->config['requires']; + $data->tested = $this->config['tested']; + $data->downloaded = 0; + $data->last_updated = $this->config['last_updated']; + $data->sections = array( 'description' => $this->config['description'] ); + $data->download_link = $this->get_zip_url(); + + return $data; + } + + + /** + * Upgrader/Updater + * Move & activate the plugin, echo the update message + * + * @since 1.0 + * @param boolean $true always true + * @param mixed $hook_extra not used + * @param array $result the result of the move + * @return array $result the result of the move + */ + public function upgrader_post_install( $true, $hook_extra, $result ) { + + global $wp_filesystem; + + // Move & Activate + $proper_destination = WP_PLUGIN_DIR.'/'.$this->config['proper_folder_name']; + $wp_filesystem->move( $result['destination'], $proper_destination ); + $result['destination'] = $proper_destination; + $activate = activate_plugin( WP_PLUGIN_DIR.'/'.$this->config['slug'] ); + + // Output the update message + $fail = __( 'The plugin has been updated, but could not be reactivated. Please reactivate it manually.', 'elementor-pro' ); + $success = __( 'Plugin reactivated successfully.', 'elementor-pro' ); + echo is_wp_error( $activate ) ? $fail : $success; + return $result; + + } +} \ No newline at end of file diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000..2ed91d4a --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,22 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..2052022f --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,396 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool + */ + private static $installedIsLocalDir; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + $copiedLocalDir = false; + + if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; + } + } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array() && !$copiedLocalDir) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..0fb0a2c1 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..15a2ff3a --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ +register(true); + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000..e84b2c11 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,20 @@ + __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->classMap = ComposerStaticInit1c64e6ae6286dda73fba27a007337e79::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000..f20a6c47 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,5 @@ +{ + "packages": [], + "dev": false, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 00000000..770b694c --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,23 @@ + array( + 'name' => 'elementor/elementor-pro', + 'pretty_version' => '3.33.x-dev', + 'version' => '3.33.9999999.9999999-dev', + 'reference' => '410694aa0ccb5ce31eb77189aba8823ed58d52b0', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + 'elementor/elementor-pro' => array( + 'pretty_version' => '3.33.x-dev', + 'version' => '3.33.9999999.9999999-dev', + 'reference' => '410694aa0ccb5ce31eb77189aba8823ed58d52b0', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +);