Changeset 3340495
- Timestamp:
- 08/06/2025 03:59:08 PM (8 months ago)
- Location:
- shortpixel-adaptive-images
- Files:
-
- 40 edited
- 1 copied
-
tags/3.11.0 (copied) (copied from shortpixel-adaptive-images/trunk)
-
tags/3.11.0/assets/css/admin.css (modified) (2 diffs)
-
tags/3.11.0/assets/css/admin.min.css (modified) (1 diff)
-
tags/3.11.0/assets/js/notice.js (modified) (1 diff)
-
tags/3.11.0/assets/js/notice.min.js (modified) (1 diff)
-
tags/3.11.0/changelog.txt (modified) (1 diff)
-
tags/3.11.0/includes/actions/notice.actions.class.php (modified) (1 diff)
-
tags/3.11.0/includes/actions/page.actions.class.php (modified) (3 diffs)
-
tags/3.11.0/includes/controllers/feedback.class.php (modified) (2 diffs)
-
tags/3.11.0/includes/controllers/lqip.class.php (modified) (9 diffs)
-
tags/3.11.0/includes/controllers/notice.class.php (modified) (1 diff)
-
tags/3.11.0/includes/controllers/page.class.php (modified) (1 diff)
-
tags/3.11.0/includes/controllers/regex-parser.class.php (modified) (9 diffs)
-
tags/3.11.0/includes/controllers/short-pixel-ai.class.php (modified) (12 diffs)
-
tags/3.11.0/includes/front/jquery-js-loader.class.php (modified) (1 diff)
-
tags/3.11.0/includes/front/vanilla-js-loader.class.php (modified) (4 diffs)
-
tags/3.11.0/includes/helpers/url-tools.class.php (modified) (1 diff)
-
tags/3.11.0/includes/models/options.category.class.php (modified) (1 diff)
-
tags/3.11.0/includes/views/settings.tpl.php (modified) (5 diffs)
-
tags/3.11.0/readme.txt (modified) (3 diffs)
-
tags/3.11.0/short-pixel-ai.php (modified) (4 diffs)
-
trunk/assets/css/admin.css (modified) (2 diffs)
-
trunk/assets/css/admin.min.css (modified) (1 diff)
-
trunk/assets/js/notice.js (modified) (1 diff)
-
trunk/assets/js/notice.min.js (modified) (1 diff)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/includes/actions/notice.actions.class.php (modified) (1 diff)
-
trunk/includes/actions/page.actions.class.php (modified) (3 diffs)
-
trunk/includes/controllers/feedback.class.php (modified) (2 diffs)
-
trunk/includes/controllers/lqip.class.php (modified) (9 diffs)
-
trunk/includes/controllers/notice.class.php (modified) (1 diff)
-
trunk/includes/controllers/page.class.php (modified) (1 diff)
-
trunk/includes/controllers/regex-parser.class.php (modified) (9 diffs)
-
trunk/includes/controllers/short-pixel-ai.class.php (modified) (12 diffs)
-
trunk/includes/front/jquery-js-loader.class.php (modified) (1 diff)
-
trunk/includes/front/vanilla-js-loader.class.php (modified) (4 diffs)
-
trunk/includes/helpers/url-tools.class.php (modified) (1 diff)
-
trunk/includes/models/options.category.class.php (modified) (1 diff)
-
trunk/includes/views/settings.tpl.php (modified) (5 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/short-pixel-ai.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
shortpixel-adaptive-images/tags/3.11.0/assets/css/admin.css
r3209129 r3340495 381 381 } 382 382 383 .blue_link { 383 .blue_link, 384 .survey-rating-btn, #survey-feedback-submit { 384 385 cursor : pointer; 385 386 color : #ffffff !important; … … 402 403 } 403 404 404 .dark_blue_link:hover, .blue_link:hover { 405 .dark_blue_link:hover,.blue_link:hover, 406 .survey-rating-btn:hover, #survey-feedback-submit { 405 407 color : #ffffff !important; 406 408 border : none !important; 407 opacity : 0. 9!important;409 opacity : 0.7 !important; 408 410 } 409 411 -
shortpixel-adaptive-images/tags/3.11.0/assets/css/admin.min.css
r3209129 r3340495 1 .shortpixel-settings-wrap input,.shortpixel-settings-wrap textarea,.shortpixel-settings-wrap button{outline:unset!important}.plugins tr[data-slug=shortpixel-adaptive-images] td div p span{display:block;margin:5px 0;padding-left:25px}.shortpixel-on-boarding-wrap{background:#fff}.shortpixel-on-boarding-wrap .socials-block{width:100%;max-width:1e3px;margin-top:10px}.socials-block,.socials-block *{-webkit-box-sizing:border-box;box-sizing:border-box}.socials-block{position:relative;padding:20px;border-radius:15px;font-weight:600;margin-bottom:10px;background:#dfffff}.socials-block>.message-wrap{width:100%;color:#05869f;padding-right:200px}.socials-block:before{content:'';position:absolute;display:block;width:20px;height:20px;top:-8px;left:20px;background:url(../img/socials/share.svg)50%/contain no-repeat}.socials-block>.buttons-wrap{position:absolute;display:block;top:calc(50% - 20px);right:20px}.socials-block [data-social]:before{content:'';position:absolute;width:16px;height:16px;top:calc(50% - 8px);left:7px}.socials-block [data-social]:last-child{margin-right:0}.socials-block [data-social]{position:relative;display:block;float:left;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;line-height:20px;margin-right:5px;border-radius:10px;padding:10px 10px 10px 30px;text-decoration:unset;outline:none;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.socials-block [data-social=twitter]{background:#d9e9f9;color:#2c76ec}.socials-block [data-social=twitter]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(44,118,236,.2);box-shadow:inset 1px 2px 2px rgba(44,118,236,.2)}.socials-block [data-social=twitter]:before{background:url(../img/socials/twitter.svg)50%/contain no-repeat}.socials-block [data-social=facebook]{background:#d9e6ff;color:#2152b3}.socials-block [data-social=facebook]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(33,82,179,.2);box-shadow:inset 1px 2px 2px rgba(33,82,179,.2)}.socials-block [data-social=facebook]:before{background:url(../img/socials/facebook.svg)50%/contain no-repeat}.sp-obw__title-wrap img{height:64px;width:64px;float:left;margin:10px 20px 10px 10px}.sp-obw__title-wrap{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.sp-obw__title-wrap:after{position:absolute;bottom:0;left:0;clear:both;width:100%;height:1px;background:#ccc;content:'';display:block}.sp-obw__content-wrap{padding:20px}.sp-obw__content-wrap p{font-size:14px}.sp-obw__content-wrap span.sp-obw-step{line-height:36px}.sp-obw__content-wrap span.sp-obw-alert{font-weight:600;color:crimson}.sp-obw__content-wrap .step-message-wrap label{vertical-align:top;margin-right:10px}.sp-obw__content-wrap .step-message-wrap p button{margin:0 10px 0 0}.sp-obw__content-wrap .step-message-wrap p button:last-child{margin:0}.sp-obw__content-wrap .step-message-wrap button:disabled{color:#a0a5aa!important;border-color:#ddd!important;background:#f7f7f7!important;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3)!important;box-shadow:0 1px 1px rgba(171,170,170,.3)!important}.bordered_link{cursor:pointer;color:#1fbec9;font-size:14px;line-height:18px;padding:5px 10px;display:inline-block;background:#f5f5f5!important;border:1px solid #1fbec9!important;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3);box-shadow:0 1px 1px rgba(171,170,170,.3);border-radius:3px;text-decoration:none;margin-bottom:15px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.bordered_link:hover{color:#0f6b7e!important;background:0 0!important}.shortpixel-steps{max-width:670px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding-bottom:24px;margin:30px 0;position:relative}.shortpixel-steps:before{position:absolute;content:'';height:2px;background:#ccc;width:100%;left:0;top:18px;z-index:1}.shortpixel-steps:after{position:absolute;content:'';height:2px;background:#ec2c25;width:100%;left:0;top:18px;z-index:2;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.shortpixel-steps[data-step="0"]:after{width:39px}.shortpixel-steps[data-step="1"]:after{width:calc(((100% - 58px)/3) + 39px)}.shortpixel-steps[data-step="2"]:after{width:calc(((100% - 58px) * 2/3) + 39px)}.shortpixel-steps[data-step="3"]:after{width:100%}.shortpixel-steps .step:nth-child(1){padding-left:20px}.shortpixel-steps .step .number{position:relative;font-weight:700;font-size:20px;color:#ccc;line-height:32px;height:34px;width:34px;text-align:center;border:2px solid #ccc;border-radius:50%;background:#fff;z-index:3}.shortpixel-steps .step.active .number,.shortpixel-steps .step.passed .number{color:#1fbec9;border:2px solid #ec2c25}.shortpixel-steps .step .title{position:absolute;color:#555d66;width:80px;text-align:center;opacity:.4;text-transform:uppercase;left:-24px;font-size:14px;bottom:-30px}.shortpixel-steps .step.active .number .title{opacity:1}.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{margin-left:5px}div.spai-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background:#000;opacity:.4}div.spai-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100001;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-title{font-size:22px}div.spai-modal-body{margin-top:10px}div.spai-modal button.spai-close-upgrade-button{float:right;margin-top:0;background:0 0!important;border:none;font-size:22px;line-height:10px;cursor:pointer}.dark_blue_link{cursor:pointer;color:#fff;height:30px;line-height:30px;padding:0 20px;background:#116c7d!important;display:inline-block;-webkit-box-shadow:0 1px 1px #09343d!important;box-shadow:0 1px 1px #09343d!important;border:none!important;border-radius:3px;text-decoration:none;margin-right:10px;position:relative;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0;outline:none}.blue_link {cursor:pointer;color:#fff!important;height:30px;line-height:30px;padding:0 20px;background:#1fbec9!important;display:inline-block;-webkit-box-shadow:0 1px 1px #16858c;box-shadow:0 1px 1px #16858c;border-radius:3px;text-decoration:none;margin-right:10px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0!important;outline:none}.dark_blue_link:hover,.blue_link:hover{color:#fff!important;border:none!important;opacity:.9!important}.dark_blue_link:focus,.blue_link:focus,.dark_blue_link:active,.blue_link:active{color:#fff}.blue_link:disabled,.blue_link:disabled:hover,.dark_blue_link:disabled,.dark_blue_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#737373!important;background:#e2e2e2!important;-webkit-box-shadow:0 1px 1px #8a8a8a!important;box-shadow:0 1px 1px #8a8a8a!important}.bordered_link:disabled,.bordered_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#969696!important;background:#efefef!important;border-color:#ccc!important}.next_icon{padding-right:35px;position:relative}.next_icon:after{content:'';width:9px;height:11px;position:absolute;right:15px;top:10px;background:url(../img/next.svg)50%/cover no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.fast-forward_link{padding-right:40px;position:relative}.fast-forward_link:after{content:'';width:14px;height:13px;position:absolute;right:15px;top:9px;background:url(../img/fast-forward.svg)50%/contain no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.next_icon:hover:after,.fast-forward_link:hover:after{right:10px}@media(max-width:400px){.shortpixel-steps .step .title{text-transform:none}}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-position:50%;background-size:contain;background-repeat:no-repeat;background-image:url(../img/robo-happy.png)!important}.notice[data-plugin=short-pixel-ai]{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}.notice[data-plugin=short-pixel-ai] .body-wrap{position:relative;padding-left:75px}.notice[data-plugin=short-pixel-ai] .body-wrap .message-wrap span{font-weight:600;color:crimson}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap{padding-left:0}.notice[data-plugin=short-pixel-ai][data-icon] .body-wrap:before{content:'';position:absolute;left:0;width:64px;height:100%;background-position:50%;background-size:contain;background-repeat:no-repeat}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap:before{content:none;position:unset;left:0;width:0;height:0;background:0 0}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes.png)}.notice[data-plugin=short-pixel-ai] .buttons-wrap{margin:10px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin-right:5px}.dismissed-notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin:0 5px 5px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button:last-child{margin-right:0}div.spai-inline-help{float:right}div.spai-inline-help span{font-size:1.8em;color:#0bb5c1;cursor:pointer}div.spai-modal{background-color:#fefefe;padding:20px 16px 16px;border:1px solid #888;width:30%;max-width:610px;margin-left:-305px;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-spinner{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50%}.spai-loading{width:100%;min-height:200px;background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0}@media(max-width:610px){div.spai-modal{width:100%;margin-left:-50%;padding:20px 0 16px}}div.spai-modal .spai-close-help-button{position:absolute;top:5px;right:0;margin-top:0;background:0 0;border:none;font-size:22px;line-height:10px;cursor:pointer}div.spai-modal-title{font-size:22px}.spai-hide{display:none}.spai_settings_tab{display:none;background:#fff;border-right:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;padding:30px 20px}.spai_settings_tab.active{display:block}.shortpixel-settings-tabs{width:calc(100% - 370px);float:left}.shortpixel-settings-tabs .nav-tab-wrapper{position:relative}.shortpixel-settings-tabs .nav-tab:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.shortpixel-settings-tabs .nav-tab-active{background:#fff;border-bottom:1px solid #fff}.shortpixel-settings-tabs .form-table td label{display:inline-block}.children-wrap{display:block;visibility:visible;opacity:1;max-height:1e4px;margin:5px 0 5px 40px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.children-wrap.hidden{visibility:hidden;opacity:0;max-height:0}.children-wrap.hidden label{display:none}.children-wrap .shortpixel_radio_btns{margin-bottom:0}.children-wrap .bordered_link{margin-bottom:0}.spai_top_actions{cursor:pointer;float:right;border:1px solid #1fbec9;border-bottom:none;margin-left:.5em;padding:5px 10px;font-size:14px;line-height:1.71428571;font-weight:600;background:#1fbec9;color:#fff;text-decoration:none;white-space:nowrap;outline:none}.spai_top_actions:hover{background:#0fa9b4}.clearcss-icon{background:url(../img/clearcss-white.svg)no-repeat;background-size:auto;display:inline-block;height:20px;width:24px;margin-top:4px}#clear_css_cache{margin-bottom:0;padding:2px 5px;height:35px}.shortpixel_radio_btns input{display:none}.shortpixel_radio_btns{-webkit-box-shadow:0 1px 1px #b6b2b2;box-shadow:0 1px 1px #b6b2b2;border-radius:3px;height:32px;display:inline-block;overflow:hidden;font-size:0;vertical-align:middle;margin-right:0;margin-bottom:20px}.shortpixel_radio_btns label{background:#ccc;text-transform:uppercase;display:inline-block;color:#fff;line-height:32px;padding:0 29px;border-left:1px solid #b4b4b4;border-right:1px solid #b4b4b4;font-size:14px;font-weight:700;margin:0 -1px;-webkit-transition:all .2s ease-in;-o-transition:all .2s ease-in;transition:all .2s ease-in}.shortpixel_radio_btns input:checked+label{background:#1fbec9;-webkit-box-shadow:0 0 3px #2a6c78;box-shadow:0 0 3px #2a6c78;border-left:1px solid #1fbec9;border-right:1px solid #1fbec9;position:relative}.shortpixel_radio_btns label:hover{background:#bbb}.shortpixel_radio_btns input:checked+label:hover{background:#0fa9b4}.shortpixel-settings-tabs input[type=text],.shortpixel-settings-tabs textarea{border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input.error[type=text],.shortpixel-settings-tabs textarea.error,.shortpixel-settings-tabs input.error[type=text]:focus,.shortpixel-settings-tabs textarea.error:focus{border:1px solid crimson;-webkit-box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15);box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15)}.shortpixel-settings-tabs textarea{width:100%;max-width:100%;min-width:100%;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input[type=checkbox]:focus,.shortpixel-settings-tabs input[type=color]:focus,.shortpixel-settings-tabs input[type=date]:focus,.shortpixel-settings-tabs input[type=datetime-local]:focus,.shortpixel-settings-tabs input[type=datetime]:focus,.shortpixel-settings-tabs input[type=email]:focus,.shortpixel-settings-tabs input[type=month]:focus,.shortpixel-settings-tabs input[type=number]:focus,.shortpixel-settings-tabs input[type=password]:focus,.shortpixel-settings-tabs input[type=radio]:focus,.shortpixel-settings-tabs input[type=search]:focus,.shortpixel-settings-tabs input[type=tel]:focus,.shortpixel-settings-tabs input[type=text]:focus,.shortpixel-settings-tabs input[type=time]:focus,.shortpixel-settings-tabs input[type=url]:focus,.shortpixel-settings-tabs input[type=week]:focus,.shortpixel-settings-tabs select:focus,.shortpixel-settings-tabs textarea:focus{border-color:#1fbec9;-webkit-box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);outline:none;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs .exclusion-wrap{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap input{margin-right:10px}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content{position:relative;width:100%;padding:5px;margin-bottom:10px;min-height:100px;border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content *:not(.plus){z-index:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover{border:1px solid #aaa}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:after{visibility:visible;opacity:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{content:'';position:absolute;visibility:hidden;opacity:0;top:calc(50% - 1px);left:calc(50% - 10px);width:20px;height:2px;background:#ddd;-webkit-transition:opacity .15s ease-in;-o-transition:opacity .15s ease-in;transition:opacity .15s ease-in;z-index:0}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{top:calc(50% - 10px);left:calc(50% - 1px);width:2px;height:20px}.exclusion-wrap .exclusions-content>div[data-index]{position:relative;float:left;margin:2px;padding:5px 30px 5px 10px;background:#116c7d;color:#fff;border-radius:10px}.exclusion-wrap .exclusions-content span[data-action=delete]{cursor:pointer;position:absolute;top:calc(50% - 10px);right:5px;height:20px;width:20px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background:#1fbec9}.exclusion-wrap .exclusions-content span[data-action=delete]:before,.exclusion-wrap .exclusions-content span[data-action=delete]:after{content:'';position:absolute;display:block;width:60%;height:2px;top:calc(50% - 1px);right:20%;background:#fff;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.exclusion-wrap .exclusions-content span[data-action=delete]:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:after{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.shortpixel-settings-tabs .exclusion-wrap textarea{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{min-width:90px;vertical-align:unset}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap button{min-width:100px;margin-right:0}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 214px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:calc(100% - 111px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap .error-message{margin-bottom:10px}.support-and-preferences{display:block;margin:10px 0;font-size:16px}.support-and-preferences a{font-weight:400;margin-right:4px;font-size:18px;color:#176d84}.support-and-preferences a:last-child{margin-right:0}.spai_statusbox_wrap{border:1px solid #e5e5e5;width:350px;float:right;margin-left:20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:43px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.spai_statusbox_wrap .title_wrap{background:#fff;position:relative;border-bottom:1px solid #e1e1e1;font-size:16px;padding:20px 60px 20px 20px}.spai_statusbox_wrap .title_wrap .usage_msg{padding:10px 10px 0 0;font-size:13px}.spai_statusbox_wrap .success{color:#1fbec9;font-weight:600}.spai_statusbox_wrap .error{color:#e53935;font-weight:600}.spai_statusbox_wrap .title_wrap:before{content:'';position:absolute;right:10px;top:calc(50% - 21px);width:42px;height:42px;background-size:contain;background-position:50%;background-repeat:no-repeat}.spai_statusbox_wrap .chart-wrap{position:relative;width:100%}.spai_statusbox_wrap .chart-wrap .toggle{content:'';cursor:pointer;position:absolute;top:0;right:0;width:20px;height:20px;background:url(../img/full-screen.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded .toggle{top:20px;right:20px;background:url(../img/minimize.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded{display:block;position:fixed;background:#fff;width:80%;max-width:1e3px;padding:20px;top:calc(50% - 250px);left:calc(10% - 20px);z-index:10000;border-radius:10px;-webkit-box-shadow:0 0 10px 3px rgba(0,0,0,.2);box-shadow:0 0 10px 3px rgba(0,0,0,.2)}.spai_statusbox_wrap .chart-wrap.expanded canvas#chart{max-height:500px}.spai_statusbox_wrap .box_content canvas#chart{display:block;height:1px;max-height:350px}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared.png)}.spai_statusbox_wrap .box_content{padding:20px;background:#fff}.spai_statusbox_wrap .box_content .buttons-wrap{text-align:center}.spai_statusbox_wrap .login_btn{float:right;margin-top:-5px;margin-bottom:0}.btn_topup{color:#ed3833;float:right;margin-right:-40px;font-weight:700}.spai_statusbox_wrap img{max-width:100%}.spai_statusbox_wrap .full_width{width:calc(100% - 40px);text-align:center;margin:20px 0 0}.spai_statusbox_wrap .progress_wrap{margin-bottom:30px}.spai_statusbox_wrap .progress{height:5px;background:#1fbec9;position:relative;width:100%;clear:both}.spai_statusbox_wrap .progress_wrap .available{color:#1fbec9;float:right}.spai_statusbox_wrap .used{color:#ccc}.spai_statusbox_wrap .progress .used{height:5px;top:0;left:0;background:#ccc;position:absolute}.spai_statusbox_wrap .box_content .box_dropdown.first{margin:30px -20px -20px}.spai_statusbox_wrap .dismissed-notice-wrap{position:relative;border:1px dotted #116c7d;padding:10px;margin-bottom:10px}.spai_statusbox_wrap .dismissed-notice-wrap h4{padding-right:0;margin:5px 0;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap:hover h4{padding-right:100px}.spai_statusbox_wrap .dismissed-notice-wrap:hover:before{visibility:visible;opacity:1;top:0}.spai_statusbox_wrap .dismissed-notice-wrap:before{content:attr(data-key);position:absolute;visibility:hidden;opacity:0;top:-10px;right:0;padding:5px;max-width:100px;color:#909090;background:#eee;text-align:center;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap span{font-weight:600;color:crimson}.spai_statusbox_wrap .dismissed-notice-wrap .spai-modal span{color:#000}.shortpixel-offer-wso{width:100%;background-color:#dcfdff;display:flex;align-items:center;border:1px solid #ccc;margin-top:35px;margin-bottom:45px;position:relative}.shortpixel-offer-wso .red{color:red}.shortpixel-offer-wso span{text-align:center}.shortpixel-offer-wso .image{flex:1}.shortpixel-offer-wso .image img{width:45px;height:45px}.shortpixel-offer-wso .line{flex:3;padding:0 20px}.shortpixel-offer-wso .line h3{color:#00d0e5}.shortpixel-offer-wso .button-wrap{flex:2}.shortpixel-offer-wso .button-wrap .banner-button{background:red;padding:8px;font-weight:700;font-size:20px;margin:8px;color:#fff;text-transform:uppercase;height:auto;display:inline-block;text-decoration:none;white-space:nowrap;box-sizing:border-box;line-height:2.15384615;min-height:30px}.shortpixel-offer-wso .button-wrapper a{background-color:red;color:#fff;display:inline-block;padding:8px;text-decoration:none;font-weight:700;font-size:20px}.spai_statusbox_wrap .img-wrapper img{max-width:140px;max-height:140px}.box_dropdown{border-top:1px solid #e5e5e5;margin:20px -20px -20px}.box_dropdown .title{font-weight:600;font-size:16px;position:relative;padding:20px;cursor:pointer}.box_dropdown .title:before{content:"\f140";display:inline-block;font:20px/1 dashicons;position:absolute;right:15px}.box_dropdown.opened .title:before{content:"\f142"}.box_dropdown .dropdown_content{display:none;padding:10px 20px}.box_dropdown.opened .dropdown_content{display:block}.box_dropdown.spai_news .dropdown_content.loading{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0;min-height:200px}.shortpixel-settings-tabs input[type=submit]{padding:0 40px}.notification_popup{position:relative;background:rgba(0,0,0,2%);padding:15px 20px 20px;margin:20px 0 0;border:1px solid #1fbec9;border-radius:3px;-webkit-box-shadow:1px 1px 1px 0 rgba(31,190,201,.2);box-shadow:1px 1px 1px rgba(31,190,201,.2)}.notification_popup:before{background:#fafafa;border-left:1px solid #1fbec9;border-bottom:1px solid #1fbec9;width:14px;height:14px;display:block;position:absolute;top:-8px;left:22px;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);content:''}.notification_popup .text{margin:0 0 10px}.spai-modal .spai-modal-body{height:auto;min-height:400px;padding:0}.spai-modal.local{background-image:none}.spai-modal.local .spai-modal-body{min-height:auto}.deactivation-popup[data-type=wrapper],.deactivation-popup[data-type=wrapper] *{-webkit-box-sizing:border-box!important;box-sizing:border-box!important;-webkit-transition:all .2s ease-in-out!important;-o-transition:all .2s ease-in-out!important;transition:all .2s ease-in-out!important}.deactivation-popup[data-type=wrapper]{position:fixed;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;opacity:1;visibility:visible;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,.8);z-index:100000}.deactivation-popup[data-type=wrapper].hidden{opacity:0;visibility:hidden}.deactivation-popup[data-type=wrapper] .overlay{position:relative;padding:20px;background:#fff;overflow:auto;max-height:90%;max-width:90%;border-radius:10px;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar{width:6px}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar-thumb{border-radius:3px;background:#00c0ce}.deactivation-popup[data-type=wrapper] .body{position:relative;display:block;max-width:360px;background:#fff;border-radius:10px}.deactivation-popup[data-type=wrapper].hidden .overlay{-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}.deactivation-popup[data-type=wrapper] .overlay .close{cursor:pointer;position:absolute;top:6px;right:6px;width:30px;height:30px;background:rgba(0,192,206,.3);border-radius:10px;z-index:1}.deactivation-popup[data-type=wrapper] .overlay .close:hover{-webkit-box-shadow:inset 1px 2px 3px rgba(14,77,88,.3);box-shadow:inset 1px 2px 3px rgba(14,77,88,.3)}.deactivation-popup[data-type=wrapper] .overlay .close:before{content:'';display:block;width:100%;height:100%;background:url(../img/close.svg)50%/40% no-repeat}.deactivation-popup[data-type=wrapper] .body .title-wrap{position:relative;display:block;font-size:18px;font-weight:600;text-align:center;padding:23px 20px 23px 70px}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{content:'';position:absolute;top:0;left:0;display:block;width:64px;height:64px;background:url(../img/robo-happy.png)50%/contain no-repeat}.deactivation-popup[data-type=wrapper] .body button{float:right;margin:0}.deactivation-popup[data-type=wrapper] .body section{margin-bottom:15px}.deactivation-popup[data-type=wrapper] .body section:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .messages-wrap p{margin:5px 0}.deactivation-popup[data-type=wrapper] .body .options-wrap{padding:10px;border-radius:10px;background:#f3f3f3}.deactivation-popup[data-type=wrapper] .body .options-wrap *:not([type=radio]):not([type=checkbox]){width:100%}.deactivation-popup[data-type=wrapper] .body .options-wrap textarea{max-height:150px;min-height:50px}.deactivation-popup[data-type=wrapper] .options-wrap label{display:block;margin-bottom:5px}.deactivation-popup[data-type=wrapper] .options-wrap label:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .scroll-down{cursor:pointer;display:block;position:absolute;bottom:30px;left:calc(50% - 20px);width:40px;height:50px;background:rgba(178,236,240,.8);z-index:1;border-radius:10px;opacity:1;visibility:visible;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-transition:all .4s ease-in-out!important;-o-transition:all .4s ease-in-out!important;transition:all .4s ease-in-out!important;-webkit-animation:1.3s knock-bottom-small 3s ease-in-out;animation:1.3s knock-bottom-small 3s ease-in-out}.deactivation-popup[data-type=wrapper] .scroll-down.hidden{opacity:0;visibility:hidden;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-animation:unset;animation:unset}.deactivation-popup[data-type=wrapper] .scroll-down .mouse{position:absolute;width:26px;height:40px;top:calc(50% - 20px);left:calc(50% - 13px);border-radius:12px;border:2px solid #007cba}.deactivation-popup[data-type=wrapper] .scroll-down .wheel{position:absolute;top:5px;left:calc(50% - 5px);height:10px;width:10px;background:url(../img/down-arrow.svg)50%/contain no-repeat;border-radius:3px;-webkit-animation:wheel-scroll 2.2s infinite;animation:wheel-scroll 2.2s infinite}@-webkit-keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}@keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}div.shortpixel-settings-wrap .tgl{display:none}.tgl::-moz-selection,.tgl:after::-moz-selection,.tgl:before::-moz-selection,.tgl *::-moz-selection,.tgl *:after::-moz-selection,.tgl *:before::-moz-selection,.tgl+.tgl-btn::-moz-selection{background:0 0}.tgl::selection,.tgl:after::selection,.tgl:before::selection,.tgl *::selection,.tgl *:after::selection,.tgl *:before::selection,.tgl+.tgl-btn::selection{background:0 0}.tgl+.tgl-btn{line-height:28px}.tgl+.tgl-btn span{outline:0;display:block;width:35px;height:6px;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin:10px 10px 0 0}.tgl+.tgl-btn span:after,.tgl+.tgl-btn span:before{position:relative;display:block;content:"";width:18px;height:18px}.tgl+.tgl-btn span:after{left:-3px}.tgl+.tgl-btn span:before{display:none}.tgl:checked+.tgl-btn span:after{left:calc(100% - 15px)}.tgl+.tgl-btn span{background:#e2e2e2;border-radius:14px;padding:2px;-webkit-transition:all .4s ease;-o-transition:all .4s ease;transition:all .4s ease;float:left;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl+.tgl-btn span:after{border-radius:14px;background:#ccc;-webkit-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-o-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.31);box-shadow:0 1px 2px rgba(0,0,0,.31);top:-6px}.tgl:hover+.tgl-btn span:after{background:#bbb}.tgl+.tgl-btn span:hover:after{will-change:padding}.tgl+.tgl-btn span:active{-webkit-box-shadow:inset 0 0 0 2em #e8eae9;box-shadow:inset 0 0 0 2em #e8eae9}.tgl+.tgl-btn span:active:after{padding-right:.8em}.tgl:checked+.tgl-btn span{background:#92d4e2;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl:checked+.tgl-btn span:after{background:#1fbec9}.tgl:checked:hover+.tgl-btn span:after{background:#0fa9b4}.spai_top_actions .tgl:checked+.tgl-btn span:after{background:#72edf5}.tgl:checked+.tgl-btn span:active{-webkit-box-shadow:none;box-shadow:none}.tgl:checked+.tgl-btn span:active:after{margin-left:-.8em}.tgl:disabled+.tgl-btn span{background:#aaa}.tgl:disabled+.tgl-btn span:after{background:#909090}.tgl:checked:disabled+.tgl-btn span{background:#80bbc7}.tgl:checked:disabled+.tgl-btn span:after{background:#1a9ca5}.clearfix:after{content:''!important;display:block!important;clear:both!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu>.ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item{display:inline-block}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache .ab-item:before{background-image:url(../img/clearcss.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache .ab-item:before{background-image:url(../img/update.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache .ab-item:before{background-image:url(../img/robo-blurry.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_processing .ab-item:before{background-image:url(../img/spinner2.gif)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_success .ab-item:before{background-image:none!important;content:'\2713';display:inline-block;color:green;width:25px;font-size:20px;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_error .ab-item:before{background-image:none!important;content:'\203C';display:inline-block;color:red;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .shortpixel-ai-sniper .ab-item:before{background-image:url(../img/robo-sniper.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai-settings .ab-item:before{background-image:none!important;font-family:dashicons;content:"\f108";color:#93d7e5;width:25px;font-size:25px}@media(max-width:1400px){.spai_statusbox_wrap{}.shortpixel-settings-tabs{width:calc(100% - 370px)}}@media(min-width:1200px){.spai_statusbox_wrap .chart-wrap.expanded{left:calc(50% - 520px)}}@media(max-width:1200px){.spai_settings_tab th,.spai_settings_tab td{display:block}.spai_settings_tab th{padding:20px 0 10px}.spai_settings_tab td{padding:5px 0}}@media(max-width:850px){.spai_statusbox_wrap{width:100%;margin-left:0}.spai_statusbox_wrap .chart-wrap .toggle{display:none}.shortpixel-settings-tabs{width:100%}.spai_statusbox_wrap .title_wrap:after{content:'';display:block;position:absolute;opacity:1;visibility:visible;width:12px;height:12px;bottom:6px;left:calc(50% - 6px);background:url(../img/expand-button.svg)50%/contain no-repeat;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.spai_statusbox_wrap.expanded .title_wrap:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.spai_statusbox_wrap .box_content{display:none}.spai_statusbox_wrap .box_content.opened{position:relative;max-height:1e3px}}@media screen and (min-width:783px){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{left:0;padding:0;width:24px;height:100%}}@media screen and (max-width:782px){#wpadminbar li#wp-admin-bar-shortpixel-ai-on-boarding{display:block;position:static}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-size:70%}#export_settings,#import_settings_form{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:100%;display:inline-block;margin-right:0;margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 10px)}.deactivation-popup[data-type=wrapper] .options-wrap label{margin-bottom:10px}}@media(min-width:851px) and (max-width:1268px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.nav-tab{border-bottom:1px solid #c3c4c7}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}}@media(max-width:600px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}.socials-block .message-wrap{padding:0;margin-bottom:10px;text-align:center}.socials-block .buttons-wrap{position:unset;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto}}@media(max-width:450px){.sp-obw__content-wrap .step-message-wrap .dark_blue_link,.sp-obw__content-wrap .step-message-wrap .blue_link,.sp-obw__content-wrap .step-message-wrap .bordered_link,.sp-obw__content-wrap .step-message-wrap .action-wrap input,.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{width:100%;display:block;text-align:center;margin:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}.shortpixel-on-boarding-wrap .socials-block{margin-top:30px}}@media(max-width:400px){.shortpixel_radio_btns{width:100%;display:table}.shortpixel_radio_btns label{display:table-cell;text-align:center;padding:0 5px}}@media(-webkit-min-device-pixel-ratio:2),(-o-min-device-pixel-ratio:2/1),(min-resolution:192dpi){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item:before{background-image:url(../img/robo-happy@2x.png)!important}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes@2x.png)}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{background-image:url(../img/robo-happy@2x.png)}.shortpixel-ai-beacon:before{background-image:url(../img/notes@2x.png)}}@-webkit-keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}1 .shortpixel-settings-wrap input,.shortpixel-settings-wrap textarea,.shortpixel-settings-wrap button{outline:unset!important}.plugins tr[data-slug=shortpixel-adaptive-images] td div p span{display:block;margin:5px 0;padding-left:25px}.shortpixel-on-boarding-wrap{background:#fff}.shortpixel-on-boarding-wrap .socials-block{width:100%;max-width:1e3px;margin-top:10px}.socials-block,.socials-block *{-webkit-box-sizing:border-box;box-sizing:border-box}.socials-block{position:relative;padding:20px;border-radius:15px;font-weight:600;margin-bottom:10px;background:#dfffff}.socials-block>.message-wrap{width:100%;color:#05869f;padding-right:200px}.socials-block:before{content:'';position:absolute;display:block;width:20px;height:20px;top:-8px;left:20px;background:url(../img/socials/share.svg)50%/contain no-repeat}.socials-block>.buttons-wrap{position:absolute;display:block;top:calc(50% - 20px);right:20px}.socials-block [data-social]:before{content:'';position:absolute;width:16px;height:16px;top:calc(50% - 8px);left:7px}.socials-block [data-social]:last-child{margin-right:0}.socials-block [data-social]{position:relative;display:block;float:left;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;line-height:20px;margin-right:5px;border-radius:10px;padding:10px 10px 10px 30px;text-decoration:unset;outline:none;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.socials-block [data-social=twitter]{background:#d9e9f9;color:#2c76ec}.socials-block [data-social=twitter]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(44,118,236,.2);box-shadow:inset 1px 2px 2px rgba(44,118,236,.2)}.socials-block [data-social=twitter]:before{background:url(../img/socials/twitter.svg)50%/contain no-repeat}.socials-block [data-social=facebook]{background:#d9e6ff;color:#2152b3}.socials-block [data-social=facebook]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(33,82,179,.2);box-shadow:inset 1px 2px 2px rgba(33,82,179,.2)}.socials-block [data-social=facebook]:before{background:url(../img/socials/facebook.svg)50%/contain no-repeat}.sp-obw__title-wrap img{height:64px;width:64px;float:left;margin:10px 20px 10px 10px}.sp-obw__title-wrap{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.sp-obw__title-wrap:after{position:absolute;bottom:0;left:0;clear:both;width:100%;height:1px;background:#ccc;content:'';display:block}.sp-obw__content-wrap{padding:20px}.sp-obw__content-wrap p{font-size:14px}.sp-obw__content-wrap span.sp-obw-step{line-height:36px}.sp-obw__content-wrap span.sp-obw-alert{font-weight:600;color:crimson}.sp-obw__content-wrap .step-message-wrap label{vertical-align:top;margin-right:10px}.sp-obw__content-wrap .step-message-wrap p button{margin:0 10px 0 0}.sp-obw__content-wrap .step-message-wrap p button:last-child{margin:0}.sp-obw__content-wrap .step-message-wrap button:disabled{color:#a0a5aa!important;border-color:#ddd!important;background:#f7f7f7!important;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3)!important;box-shadow:0 1px 1px rgba(171,170,170,.3)!important}.bordered_link{cursor:pointer;color:#1fbec9;font-size:14px;line-height:18px;padding:5px 10px;display:inline-block;background:#f5f5f5!important;border:1px solid #1fbec9!important;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3);box-shadow:0 1px 1px rgba(171,170,170,.3);border-radius:3px;text-decoration:none;margin-bottom:15px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.bordered_link:hover{color:#0f6b7e!important;background:0 0!important}.shortpixel-steps{max-width:670px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding-bottom:24px;margin:30px 0;position:relative}.shortpixel-steps:before{position:absolute;content:'';height:2px;background:#ccc;width:100%;left:0;top:18px;z-index:1}.shortpixel-steps:after{position:absolute;content:'';height:2px;background:#ec2c25;width:100%;left:0;top:18px;z-index:2;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.shortpixel-steps[data-step="0"]:after{width:39px}.shortpixel-steps[data-step="1"]:after{width:calc(((100% - 58px)/3) + 39px)}.shortpixel-steps[data-step="2"]:after{width:calc(((100% - 58px) * 2/3) + 39px)}.shortpixel-steps[data-step="3"]:after{width:100%}.shortpixel-steps .step:nth-child(1){padding-left:20px}.shortpixel-steps .step .number{position:relative;font-weight:700;font-size:20px;color:#ccc;line-height:32px;height:34px;width:34px;text-align:center;border:2px solid #ccc;border-radius:50%;background:#fff;z-index:3}.shortpixel-steps .step.active .number,.shortpixel-steps .step.passed .number{color:#1fbec9;border:2px solid #ec2c25}.shortpixel-steps .step .title{position:absolute;color:#555d66;width:80px;text-align:center;opacity:.4;text-transform:uppercase;left:-24px;font-size:14px;bottom:-30px}.shortpixel-steps .step.active .number .title{opacity:1}.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{margin-left:5px}div.spai-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background:#000;opacity:.4}div.spai-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100001;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-title{font-size:22px}div.spai-modal-body{margin-top:10px}div.spai-modal button.spai-close-upgrade-button{float:right;margin-top:0;background:0 0!important;border:none;font-size:22px;line-height:10px;cursor:pointer}.dark_blue_link{cursor:pointer;color:#fff;height:30px;line-height:30px;padding:0 20px;background:#116c7d!important;display:inline-block;-webkit-box-shadow:0 1px 1px #09343d!important;box-shadow:0 1px 1px #09343d!important;border:none!important;border-radius:3px;text-decoration:none;margin-right:10px;position:relative;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0;outline:none}.blue_link,.survey-rating-btn,#survey-feedback-submit{cursor:pointer;color:#fff!important;height:30px;line-height:30px;padding:0 20px;background:#1fbec9!important;display:inline-block;-webkit-box-shadow:0 1px 1px #16858c;box-shadow:0 1px 1px #16858c;border-radius:3px;text-decoration:none;margin-right:10px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0!important;outline:none}.dark_blue_link:hover,.blue_link:hover,.survey-rating-btn:hover,#survey-feedback-submit{color:#fff!important;border:none!important;opacity:.7!important}.dark_blue_link:focus,.blue_link:focus,.dark_blue_link:active,.blue_link:active{color:#fff}.blue_link:disabled,.blue_link:disabled:hover,.dark_blue_link:disabled,.dark_blue_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#737373!important;background:#e2e2e2!important;-webkit-box-shadow:0 1px 1px #8a8a8a!important;box-shadow:0 1px 1px #8a8a8a!important}.bordered_link:disabled,.bordered_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#969696!important;background:#efefef!important;border-color:#ccc!important}.next_icon{padding-right:35px;position:relative}.next_icon:after{content:'';width:9px;height:11px;position:absolute;right:15px;top:10px;background:url(../img/next.svg)50%/cover no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.fast-forward_link{padding-right:40px;position:relative}.fast-forward_link:after{content:'';width:14px;height:13px;position:absolute;right:15px;top:9px;background:url(../img/fast-forward.svg)50%/contain no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.next_icon:hover:after,.fast-forward_link:hover:after{right:10px}@media(max-width:400px){.shortpixel-steps .step .title{text-transform:none}}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-position:50%;background-size:contain;background-repeat:no-repeat;background-image:url(../img/robo-happy.png)!important}.notice[data-plugin=short-pixel-ai]{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}.notice[data-plugin=short-pixel-ai] .body-wrap{position:relative;padding-left:75px}.notice[data-plugin=short-pixel-ai] .body-wrap .message-wrap span{font-weight:600;color:crimson}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap{padding-left:0}.notice[data-plugin=short-pixel-ai][data-icon] .body-wrap:before{content:'';position:absolute;left:0;width:64px;height:100%;background-position:50%;background-size:contain;background-repeat:no-repeat}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap:before{content:none;position:unset;left:0;width:0;height:0;background:0 0}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes.png)}.notice[data-plugin=short-pixel-ai] .buttons-wrap{margin:10px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin-right:5px}.dismissed-notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin:0 5px 5px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button:last-child{margin-right:0}div.spai-inline-help{float:right}div.spai-inline-help span{font-size:1.8em;color:#0bb5c1;cursor:pointer}div.spai-modal{background-color:#fefefe;padding:20px 16px 16px;border:1px solid #888;width:30%;max-width:610px;margin-left:-305px;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-spinner{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50%}.spai-loading{width:100%;min-height:200px;background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0}@media(max-width:610px){div.spai-modal{width:100%;margin-left:-50%;padding:20px 0 16px}}div.spai-modal .spai-close-help-button{position:absolute;top:5px;right:0;margin-top:0;background:0 0;border:none;font-size:22px;line-height:10px;cursor:pointer}div.spai-modal-title{font-size:22px}.spai-hide{display:none}.spai_settings_tab{display:none;background:#fff;border-right:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;padding:30px 20px}.spai_settings_tab.active{display:block}.shortpixel-settings-tabs{width:calc(100% - 370px);float:left}.shortpixel-settings-tabs .nav-tab-wrapper{position:relative}.shortpixel-settings-tabs .nav-tab:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.shortpixel-settings-tabs .nav-tab-active{background:#fff;border-bottom:1px solid #fff}.shortpixel-settings-tabs .form-table td label{display:inline-block}.children-wrap{display:block;visibility:visible;opacity:1;max-height:1e4px;margin:5px 0 5px 40px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.children-wrap.hidden{visibility:hidden;opacity:0;max-height:0}.children-wrap.hidden label{display:none}.children-wrap .shortpixel_radio_btns{margin-bottom:0}.children-wrap .bordered_link{margin-bottom:0}.spai_top_actions{cursor:pointer;float:right;border:1px solid #1fbec9;border-bottom:none;margin-left:.5em;padding:5px 10px;font-size:14px;line-height:1.71428571;font-weight:600;background:#1fbec9;color:#fff;text-decoration:none;white-space:nowrap;outline:none}.spai_top_actions:hover{background:#0fa9b4}.clearcss-icon{background:url(../img/clearcss-white.svg)no-repeat;background-size:auto;display:inline-block;height:20px;width:24px;margin-top:4px}#clear_css_cache{margin-bottom:0;padding:2px 5px;height:35px}.shortpixel_radio_btns input{display:none}.shortpixel_radio_btns{-webkit-box-shadow:0 1px 1px #b6b2b2;box-shadow:0 1px 1px #b6b2b2;border-radius:3px;height:32px;display:inline-block;overflow:hidden;font-size:0;vertical-align:middle;margin-right:0;margin-bottom:20px}.shortpixel_radio_btns label{background:#ccc;text-transform:uppercase;display:inline-block;color:#fff;line-height:32px;padding:0 29px;border-left:1px solid #b4b4b4;border-right:1px solid #b4b4b4;font-size:14px;font-weight:700;margin:0 -1px;-webkit-transition:all .2s ease-in;-o-transition:all .2s ease-in;transition:all .2s ease-in}.shortpixel_radio_btns input:checked+label{background:#1fbec9;-webkit-box-shadow:0 0 3px #2a6c78;box-shadow:0 0 3px #2a6c78;border-left:1px solid #1fbec9;border-right:1px solid #1fbec9;position:relative}.shortpixel_radio_btns label:hover{background:#bbb}.shortpixel_radio_btns input:checked+label:hover{background:#0fa9b4}.shortpixel-settings-tabs input[type=text],.shortpixel-settings-tabs textarea{border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input.error[type=text],.shortpixel-settings-tabs textarea.error,.shortpixel-settings-tabs input.error[type=text]:focus,.shortpixel-settings-tabs textarea.error:focus{border:1px solid crimson;-webkit-box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15);box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15)}.shortpixel-settings-tabs textarea{width:100%;max-width:100%;min-width:100%;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input[type=checkbox]:focus,.shortpixel-settings-tabs input[type=color]:focus,.shortpixel-settings-tabs input[type=date]:focus,.shortpixel-settings-tabs input[type=datetime-local]:focus,.shortpixel-settings-tabs input[type=datetime]:focus,.shortpixel-settings-tabs input[type=email]:focus,.shortpixel-settings-tabs input[type=month]:focus,.shortpixel-settings-tabs input[type=number]:focus,.shortpixel-settings-tabs input[type=password]:focus,.shortpixel-settings-tabs input[type=radio]:focus,.shortpixel-settings-tabs input[type=search]:focus,.shortpixel-settings-tabs input[type=tel]:focus,.shortpixel-settings-tabs input[type=text]:focus,.shortpixel-settings-tabs input[type=time]:focus,.shortpixel-settings-tabs input[type=url]:focus,.shortpixel-settings-tabs input[type=week]:focus,.shortpixel-settings-tabs select:focus,.shortpixel-settings-tabs textarea:focus{border-color:#1fbec9;-webkit-box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);outline:none;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs .exclusion-wrap{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap input{margin-right:10px}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content{position:relative;width:100%;padding:5px;margin-bottom:10px;min-height:100px;border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content *:not(.plus){z-index:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover{border:1px solid #aaa}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:after{visibility:visible;opacity:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{content:'';position:absolute;visibility:hidden;opacity:0;top:calc(50% - 1px);left:calc(50% - 10px);width:20px;height:2px;background:#ddd;-webkit-transition:opacity .15s ease-in;-o-transition:opacity .15s ease-in;transition:opacity .15s ease-in;z-index:0}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{top:calc(50% - 10px);left:calc(50% - 1px);width:2px;height:20px}.exclusion-wrap .exclusions-content>div[data-index]{position:relative;float:left;margin:2px;padding:5px 30px 5px 10px;background:#116c7d;color:#fff;border-radius:10px}.exclusion-wrap .exclusions-content span[data-action=delete]{cursor:pointer;position:absolute;top:calc(50% - 10px);right:5px;height:20px;width:20px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background:#1fbec9}.exclusion-wrap .exclusions-content span[data-action=delete]:before,.exclusion-wrap .exclusions-content span[data-action=delete]:after{content:'';position:absolute;display:block;width:60%;height:2px;top:calc(50% - 1px);right:20%;background:#fff;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.exclusion-wrap .exclusions-content span[data-action=delete]:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:after{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.shortpixel-settings-tabs .exclusion-wrap textarea{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{min-width:90px;vertical-align:unset}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap button{min-width:100px;margin-right:0}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 214px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:calc(100% - 111px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap .error-message{margin-bottom:10px}.support-and-preferences{display:block;margin:10px 0;font-size:16px}.support-and-preferences a{font-weight:400;margin-right:4px;font-size:18px;color:#176d84}.support-and-preferences a:last-child{margin-right:0}.spai_statusbox_wrap{border:1px solid #e5e5e5;width:350px;float:right;margin-left:20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:43px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.spai_statusbox_wrap .title_wrap{background:#fff;position:relative;border-bottom:1px solid #e1e1e1;font-size:16px;padding:20px 60px 20px 20px}.spai_statusbox_wrap .title_wrap .usage_msg{padding:10px 10px 0 0;font-size:13px}.spai_statusbox_wrap .success{color:#1fbec9;font-weight:600}.spai_statusbox_wrap .error{color:#e53935;font-weight:600}.spai_statusbox_wrap .title_wrap:before{content:'';position:absolute;right:10px;top:calc(50% - 21px);width:42px;height:42px;background-size:contain;background-position:50%;background-repeat:no-repeat}.spai_statusbox_wrap .chart-wrap{position:relative;width:100%}.spai_statusbox_wrap .chart-wrap .toggle{content:'';cursor:pointer;position:absolute;top:0;right:0;width:20px;height:20px;background:url(../img/full-screen.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded .toggle{top:20px;right:20px;background:url(../img/minimize.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded{display:block;position:fixed;background:#fff;width:80%;max-width:1e3px;padding:20px;top:calc(50% - 250px);left:calc(10% - 20px);z-index:10000;border-radius:10px;-webkit-box-shadow:0 0 10px 3px rgba(0,0,0,.2);box-shadow:0 0 10px 3px rgba(0,0,0,.2)}.spai_statusbox_wrap .chart-wrap.expanded canvas#chart{max-height:500px}.spai_statusbox_wrap .box_content canvas#chart{display:block;height:1px;max-height:350px}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared.png)}.spai_statusbox_wrap .box_content{padding:20px;background:#fff}.spai_statusbox_wrap .box_content .buttons-wrap{text-align:center}.spai_statusbox_wrap .login_btn{float:right;margin-top:-5px;margin-bottom:0}.btn_topup{color:#ed3833;float:right;margin-right:-40px;font-weight:700}.spai_statusbox_wrap img{max-width:100%}.spai_statusbox_wrap .full_width{width:calc(100% - 40px);text-align:center;margin:20px 0 0}.spai_statusbox_wrap .progress_wrap{margin-bottom:30px}.spai_statusbox_wrap .progress{height:5px;background:#1fbec9;position:relative;width:100%;clear:both}.spai_statusbox_wrap .progress_wrap .available{color:#1fbec9;float:right}.spai_statusbox_wrap .used{color:#ccc}.spai_statusbox_wrap .progress .used{height:5px;top:0;left:0;background:#ccc;position:absolute}.spai_statusbox_wrap .box_content .box_dropdown.first{margin:30px -20px -20px}.spai_statusbox_wrap .dismissed-notice-wrap{position:relative;border:1px dotted #116c7d;padding:10px;margin-bottom:10px}.spai_statusbox_wrap .dismissed-notice-wrap h4{padding-right:0;margin:5px 0;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap:hover h4{padding-right:100px}.spai_statusbox_wrap .dismissed-notice-wrap:hover:before{visibility:visible;opacity:1;top:0}.spai_statusbox_wrap .dismissed-notice-wrap:before{content:attr(data-key);position:absolute;visibility:hidden;opacity:0;top:-10px;right:0;padding:5px;max-width:100px;color:#909090;background:#eee;text-align:center;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap span{font-weight:600;color:crimson}.spai_statusbox_wrap .dismissed-notice-wrap .spai-modal span{color:#000}.shortpixel-offer-wso{width:100%;background-color:#dcfdff;display:flex;align-items:center;border:1px solid #ccc;margin-top:35px;margin-bottom:45px;position:relative}.shortpixel-offer-wso .red{color:red}.shortpixel-offer-wso span{text-align:center}.shortpixel-offer-wso .image{flex:1}.shortpixel-offer-wso .image img{width:45px;height:45px}.shortpixel-offer-wso .line{flex:3;padding:0 20px}.shortpixel-offer-wso .line h3{color:#00d0e5}.shortpixel-offer-wso .button-wrap{flex:2}.shortpixel-offer-wso .button-wrap .banner-button{background:red;padding:8px;font-weight:700;font-size:20px;margin:8px;color:#fff;text-transform:uppercase;height:auto;display:inline-block;text-decoration:none;white-space:nowrap;box-sizing:border-box;line-height:2.15384615;min-height:30px}.shortpixel-offer-wso .button-wrapper a{background-color:red;color:#fff;display:inline-block;padding:8px;text-decoration:none;font-weight:700;font-size:20px}.spai_statusbox_wrap .img-wrapper img{max-width:140px;max-height:140px}.box_dropdown{border-top:1px solid #e5e5e5;margin:20px -20px -20px}.box_dropdown .title{font-weight:600;font-size:16px;position:relative;padding:20px;cursor:pointer}.box_dropdown .title:before{content:"\f140";display:inline-block;font:20px/1 dashicons;position:absolute;right:15px}.box_dropdown.opened .title:before{content:"\f142"}.box_dropdown .dropdown_content{display:none;padding:10px 20px}.box_dropdown.opened .dropdown_content{display:block}.box_dropdown.spai_news .dropdown_content.loading{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0;min-height:200px}.shortpixel-settings-tabs input[type=submit]{padding:0 40px}.notification_popup{position:relative;background:rgba(0,0,0,2%);padding:15px 20px 20px;margin:20px 0 0;border:1px solid #1fbec9;border-radius:3px;-webkit-box-shadow:1px 1px 1px 0 rgba(31,190,201,.2);box-shadow:1px 1px 1px rgba(31,190,201,.2)}.notification_popup:before{background:#fafafa;border-left:1px solid #1fbec9;border-bottom:1px solid #1fbec9;width:14px;height:14px;display:block;position:absolute;top:-8px;left:22px;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);content:''}.notification_popup .text{margin:0 0 10px}.spai-modal .spai-modal-body{height:auto;min-height:400px;padding:0}.spai-modal.local{background-image:none}.spai-modal.local .spai-modal-body{min-height:auto}.deactivation-popup[data-type=wrapper],.deactivation-popup[data-type=wrapper] *{-webkit-box-sizing:border-box!important;box-sizing:border-box!important;-webkit-transition:all .2s ease-in-out!important;-o-transition:all .2s ease-in-out!important;transition:all .2s ease-in-out!important}.deactivation-popup[data-type=wrapper]{position:fixed;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;opacity:1;visibility:visible;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,.8);z-index:100000}.deactivation-popup[data-type=wrapper].hidden{opacity:0;visibility:hidden}.deactivation-popup[data-type=wrapper] .overlay{position:relative;padding:20px;background:#fff;overflow:auto;max-height:90%;max-width:90%;border-radius:10px;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar{width:6px}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar-thumb{border-radius:3px;background:#00c0ce}.deactivation-popup[data-type=wrapper] .body{position:relative;display:block;max-width:360px;background:#fff;border-radius:10px}.deactivation-popup[data-type=wrapper].hidden .overlay{-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}.deactivation-popup[data-type=wrapper] .overlay .close{cursor:pointer;position:absolute;top:6px;right:6px;width:30px;height:30px;background:rgba(0,192,206,.3);border-radius:10px;z-index:1}.deactivation-popup[data-type=wrapper] .overlay .close:hover{-webkit-box-shadow:inset 1px 2px 3px rgba(14,77,88,.3);box-shadow:inset 1px 2px 3px rgba(14,77,88,.3)}.deactivation-popup[data-type=wrapper] .overlay .close:before{content:'';display:block;width:100%;height:100%;background:url(../img/close.svg)50%/40% no-repeat}.deactivation-popup[data-type=wrapper] .body .title-wrap{position:relative;display:block;font-size:18px;font-weight:600;text-align:center;padding:23px 20px 23px 70px}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{content:'';position:absolute;top:0;left:0;display:block;width:64px;height:64px;background:url(../img/robo-happy.png)50%/contain no-repeat}.deactivation-popup[data-type=wrapper] .body button{float:right;margin:0}.deactivation-popup[data-type=wrapper] .body section{margin-bottom:15px}.deactivation-popup[data-type=wrapper] .body section:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .messages-wrap p{margin:5px 0}.deactivation-popup[data-type=wrapper] .body .options-wrap{padding:10px;border-radius:10px;background:#f3f3f3}.deactivation-popup[data-type=wrapper] .body .options-wrap *:not([type=radio]):not([type=checkbox]){width:100%}.deactivation-popup[data-type=wrapper] .body .options-wrap textarea{max-height:150px;min-height:50px}.deactivation-popup[data-type=wrapper] .options-wrap label{display:block;margin-bottom:5px}.deactivation-popup[data-type=wrapper] .options-wrap label:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .scroll-down{cursor:pointer;display:block;position:absolute;bottom:30px;left:calc(50% - 20px);width:40px;height:50px;background:rgba(178,236,240,.8);z-index:1;border-radius:10px;opacity:1;visibility:visible;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-transition:all .4s ease-in-out!important;-o-transition:all .4s ease-in-out!important;transition:all .4s ease-in-out!important;-webkit-animation:1.3s knock-bottom-small 3s ease-in-out;animation:1.3s knock-bottom-small 3s ease-in-out}.deactivation-popup[data-type=wrapper] .scroll-down.hidden{opacity:0;visibility:hidden;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-animation:unset;animation:unset}.deactivation-popup[data-type=wrapper] .scroll-down .mouse{position:absolute;width:26px;height:40px;top:calc(50% - 20px);left:calc(50% - 13px);border-radius:12px;border:2px solid #007cba}.deactivation-popup[data-type=wrapper] .scroll-down .wheel{position:absolute;top:5px;left:calc(50% - 5px);height:10px;width:10px;background:url(../img/down-arrow.svg)50%/contain no-repeat;border-radius:3px;-webkit-animation:wheel-scroll 2.2s infinite;animation:wheel-scroll 2.2s infinite}@-webkit-keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}@keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}div.shortpixel-settings-wrap .tgl{display:none}.tgl::-moz-selection,.tgl:after::-moz-selection,.tgl:before::-moz-selection,.tgl *::-moz-selection,.tgl *:after::-moz-selection,.tgl *:before::-moz-selection,.tgl+.tgl-btn::-moz-selection{background:0 0}.tgl::selection,.tgl:after::selection,.tgl:before::selection,.tgl *::selection,.tgl *:after::selection,.tgl *:before::selection,.tgl+.tgl-btn::selection{background:0 0}.tgl+.tgl-btn{line-height:28px}.tgl+.tgl-btn span{outline:0;display:block;width:35px;height:6px;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin:10px 10px 0 0}.tgl+.tgl-btn span:after,.tgl+.tgl-btn span:before{position:relative;display:block;content:"";width:18px;height:18px}.tgl+.tgl-btn span:after{left:-3px}.tgl+.tgl-btn span:before{display:none}.tgl:checked+.tgl-btn span:after{left:calc(100% - 15px)}.tgl+.tgl-btn span{background:#e2e2e2;border-radius:14px;padding:2px;-webkit-transition:all .4s ease;-o-transition:all .4s ease;transition:all .4s ease;float:left;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl+.tgl-btn span:after{border-radius:14px;background:#ccc;-webkit-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-o-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.31);box-shadow:0 1px 2px rgba(0,0,0,.31);top:-6px}.tgl:hover+.tgl-btn span:after{background:#bbb}.tgl+.tgl-btn span:hover:after{will-change:padding}.tgl+.tgl-btn span:active{-webkit-box-shadow:inset 0 0 0 2em #e8eae9;box-shadow:inset 0 0 0 2em #e8eae9}.tgl+.tgl-btn span:active:after{padding-right:.8em}.tgl:checked+.tgl-btn span{background:#92d4e2;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl:checked+.tgl-btn span:after{background:#1fbec9}.tgl:checked:hover+.tgl-btn span:after{background:#0fa9b4}.spai_top_actions .tgl:checked+.tgl-btn span:after{background:#72edf5}.tgl:checked+.tgl-btn span:active{-webkit-box-shadow:none;box-shadow:none}.tgl:checked+.tgl-btn span:active:after{margin-left:-.8em}.tgl:disabled+.tgl-btn span{background:#aaa}.tgl:disabled+.tgl-btn span:after{background:#909090}.tgl:checked:disabled+.tgl-btn span{background:#80bbc7}.tgl:checked:disabled+.tgl-btn span:after{background:#1a9ca5}.clearfix:after{content:''!important;display:block!important;clear:both!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu>.ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item{display:inline-block}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache .ab-item:before{background-image:url(../img/clearcss.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache .ab-item:before{background-image:url(../img/update.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache .ab-item:before{background-image:url(../img/robo-blurry.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_processing .ab-item:before{background-image:url(../img/spinner2.gif)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_success .ab-item:before{background-image:none!important;content:'\2713';display:inline-block;color:green;width:25px;font-size:20px;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_error .ab-item:before{background-image:none!important;content:'\203C';display:inline-block;color:red;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .shortpixel-ai-sniper .ab-item:before{background-image:url(../img/robo-sniper.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai-settings .ab-item:before{background-image:none!important;font-family:dashicons;content:"\f108";color:#93d7e5;width:25px;font-size:25px}@media(max-width:1400px){.spai_statusbox_wrap{}.shortpixel-settings-tabs{width:calc(100% - 370px)}}@media(min-width:1200px){.spai_statusbox_wrap .chart-wrap.expanded{left:calc(50% - 520px)}}@media(max-width:1200px){.spai_settings_tab th,.spai_settings_tab td{display:block}.spai_settings_tab th{padding:20px 0 10px}.spai_settings_tab td{padding:5px 0}}@media(max-width:850px){.spai_statusbox_wrap{width:100%;margin-left:0}.spai_statusbox_wrap .chart-wrap .toggle{display:none}.shortpixel-settings-tabs{width:100%}.spai_statusbox_wrap .title_wrap:after{content:'';display:block;position:absolute;opacity:1;visibility:visible;width:12px;height:12px;bottom:6px;left:calc(50% - 6px);background:url(../img/expand-button.svg)50%/contain no-repeat;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.spai_statusbox_wrap.expanded .title_wrap:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.spai_statusbox_wrap .box_content{display:none}.spai_statusbox_wrap .box_content.opened{position:relative;max-height:1e3px}}@media screen and (min-width:783px){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{left:0;padding:0;width:24px;height:100%}}@media screen and (max-width:782px){#wpadminbar li#wp-admin-bar-shortpixel-ai-on-boarding{display:block;position:static}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-size:70%}#export_settings,#import_settings_form{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:100%;display:inline-block;margin-right:0;margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 10px)}.deactivation-popup[data-type=wrapper] .options-wrap label{margin-bottom:10px}}@media(min-width:851px) and (max-width:1268px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.nav-tab{border-bottom:1px solid #c3c4c7}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}}@media(max-width:600px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}.socials-block .message-wrap{padding:0;margin-bottom:10px;text-align:center}.socials-block .buttons-wrap{position:unset;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto}}@media(max-width:450px){.sp-obw__content-wrap .step-message-wrap .dark_blue_link,.sp-obw__content-wrap .step-message-wrap .blue_link,.sp-obw__content-wrap .step-message-wrap .bordered_link,.sp-obw__content-wrap .step-message-wrap .action-wrap input,.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{width:100%;display:block;text-align:center;margin:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}.shortpixel-on-boarding-wrap .socials-block{margin-top:30px}}@media(max-width:400px){.shortpixel_radio_btns{width:100%;display:table}.shortpixel_radio_btns label{display:table-cell;text-align:center;padding:0 5px}}@media(-webkit-min-device-pixel-ratio:2),(-o-min-device-pixel-ratio:2/1),(min-resolution:192dpi){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item:before{background-image:url(../img/robo-happy@2x.png)!important}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes@2x.png)}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{background-image:url(../img/robo-happy@2x.png)}.shortpixel-ai-beacon:before{background-image:url(../img/notes@2x.png)}}@-webkit-keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}} -
shortpixel-adaptive-images/tags/3.11.0/assets/js/notice.js
r2900611 r3340495 94 94 } 95 95 } ); 96 // feedback survey handler 97 $document.on( 'click', '.notice[data-causer="recommend_survey"] .survey-rating-btn', function(e){ 98 e.preventDefault(); 99 var $btn = $( this ), 100 rating = $btn.data('rating'), 101 $notice = $btn.closest('.notice[data-causer="recommend_survey"]'); 102 103 $notice.find('.survey-rating-btn').removeClass('selected'); 104 $btn.addClass('selected'); 105 // send (only) rating first 106 $.post( ajaxurl, { 107 action: 'shortpixel_ai_send_rating', 108 data: { rating: rating } 109 }); 110 // for 9–10: show inline thank-you + review prompt for WP pagre 111 if ( rating >= 9 ) { 112 $notice.find('h3, .message-wrap > p').slideUp(); 113 114 var promptHtml = 115 '<p>Thank you for your high rating! ' + 116 'If you have a moment, the ShortPixel team would be very happy ' + 117 'if you could leave a short review for our plugin.</p>'; 118 119 var reviewLinkHtml = 120 '<p>' + 121 '<button id="survey-feedback-submit" class="button button-primary" '+ 122 'onclick="window.open(\'https://wordpress.org/support/plugin/shortpixel-adaptive-images/reviews/?filter=5\', \'_blank\')">' + 123 'Leave a review' + 124 '</button>' + 125 '</p>'; 126 127 $notice 128 .find('#survey-feedback-area') 129 .html( promptHtml + reviewLinkHtml ) 130 .slideDown(); 131 132 return; 133 } 134 // 1–8: close title + buttons & open feedback area 135 $notice.find('h3').slideUp(); 136 $notice.find('.survey-rating-btn').closest('p').slideUp(); 137 var prompt = rating <= 4 138 ? 'Thank you for your feedback! If you have encountered any issues with our plugin, we are more than eager to help solving them! Please give us more details:' 139 : 'Thank you for your feedback! Please let us know what we can improve:'; 140 141 $notice.find('#survey-feedback-prompt').text( prompt ); 142 $notice.find('#survey-feedback-area').slideDown(); 143 }); 144 145 // now, when click on submit button send 2nd ajax with feedback 146 $document.on( 'click', '.notice[data-causer="recommend_survey"] #survey-feedback-submit', function(e){ 147 e.preventDefault(); 148 var $notice = $( this ).closest( '.notice[data-causer="recommend_survey"]'), 149 rating = $notice.find('.survey-rating-btn.selected').data('rating'), 150 feedbackText = $notice.find('#survey-feedback').val() || ''; 151 152 $.post( ajaxurl, { 153 action: 'shortpixel_ai_send_feedback', 154 data: { 155 rating: rating, 156 feedback: feedbackText 157 } 158 }) 159 .done(function( resp ){ 160 var $msgWrap = $notice.find('.message-wrap'); 161 if ( resp.success ) { 162 $msgWrap.html('<p>Thank you for your feedback!</p>'); 163 $notice.find('#survey-feedback-area, .buttons-wrap').slideUp(); 164 } 165 else { 166 var error = resp.data || 'Something went wrong sending feedback!'; 167 $msgWrap.html('<p>' + error + '</p>'); 168 } 169 }); 170 }); 171 96 172 } ); 97 173 } )( jQuery, document, window ); -
shortpixel-adaptive-images/tags/3.11.0/assets/js/notice.min.js
r2900611 r3340495 1 (function( t,i,e){t((function(){var a=t(this);var n=false;a.on("click",'.notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .notice[data-plugin="short-pixel-ai"] button.notice-dismiss, .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap button.notice-dismiss',(function(){var o=t(this),d=o.parents('.notice[data-plugin="short-pixel-ai"], .dismissed-notice[data-plugin="short-pixel-ai"]');o.prop("disabled",true);var r=d.attr("data-causer"),s=o.attr("data-type"),c=o.attr("data-action"),u=o.attr("data-additional");r=typeof r==="string"&&r!==""?r:undefined;c=typeof c==="string"&&c!==""?c:r!==undefined&&o.hasClass("notice-dismiss")?"dismiss":undefined;try{u=JSON.parse(u)}catch(t){u=undefined}if(r!==undefined){if(s==="js"){if(typeof jQuery[c]==="function"){jQuery[c](u)}}else if(!n){t.ajax({method:"post",url:typeof ajaxurl==="string"&&ajaxurl!==""?ajaxurl:"/wp-admin/admin-ajax.php",data:{action:"shortpixel_ai_handle_notice_action",causer:d.attr("data-causer"),data:{action:c,additional:u}},beforeSend:function(){n=true},success:function(n){d.slideUp("fast",(function(){if(typeof n.notice==="string"&&n.notice!==""){var i=t(n.notice).hide();d.after(i);a.trigger("wp-updates-notice-added");i.slideDown("fast",(function(){i.removeAttr("style")}))}d.remove()}));if(typeof n.redirect!=="undefined"&&!!n.redirect.allowed){if(typeof n.redirect.url==="string"&&n.redirect.url!==""){if(!!n.redirect.blank){e.open(n.redirect.url)}else{i.location.href=n.redirect.url}}}if(typeof n.reload!=="undefined"&&!!n.reload.allowed){i.location.reload()}},complete:function(){n=false}})}}}))}))})(jQuery,document,window);1 (function(e,t,a){e((function(){var i=e(this);var n=false;i.on("click",'.notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .notice[data-plugin="short-pixel-ai"] button.notice-dismiss, .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap button.notice-dismiss',(function(){var r=e(this),o=r.parents('.notice[data-plugin="short-pixel-ai"], .dismissed-notice[data-plugin="short-pixel-ai"]');r.prop("disabled",true);var s=o.attr("data-causer"),d=r.attr("data-type"),u=r.attr("data-action"),c=r.attr("data-additional");s=typeof s==="string"&&s!==""?s:undefined;u=typeof u==="string"&&u!==""?u:s!==undefined&&r.hasClass("notice-dismiss")?"dismiss":undefined;try{c=JSON.parse(c)}catch(e){c=undefined}if(s!==undefined){if(d==="js"){if(typeof jQuery[u]==="function"){jQuery[u](c)}}else if(!n){e.ajax({method:"post",url:typeof ajaxurl==="string"&&ajaxurl!==""?ajaxurl:"/wp-admin/admin-ajax.php",data:{action:"shortpixel_ai_handle_notice_action",causer:o.attr("data-causer"),data:{action:u,additional:c}},beforeSend:function(){n=true},success:function(n){o.slideUp("fast",(function(){if(typeof n.notice==="string"&&n.notice!==""){var t=e(n.notice).hide();o.after(t);i.trigger("wp-updates-notice-added");t.slideDown("fast",(function(){t.removeAttr("style")}))}o.remove()}));if(typeof n.redirect!=="undefined"&&!!n.redirect.allowed){if(typeof n.redirect.url==="string"&&n.redirect.url!==""){if(!!n.redirect.blank){a.open(n.redirect.url)}else{t.location.href=n.redirect.url}}}if(typeof n.reload!=="undefined"&&!!n.reload.allowed){t.location.reload()}},complete:function(){n=false}})}}}));i.on("click",'.notice[data-causer="recommend_survey"] .survey-rating-btn',(function(t){t.preventDefault();var a=e(this),i=a.data("rating"),n=a.closest('.notice[data-causer="recommend_survey"]');n.find(".survey-rating-btn").removeClass("selected");a.addClass("selected");e.post(ajaxurl,{action:"shortpixel_ai_send_rating",data:{rating:i}});if(i>=9){n.find("h3, .message-wrap > p").slideUp();var r="<p>Thank you for your high rating! "+"If you have a moment, the ShortPixel team would be very happy "+"if you could leave a short review for our plugin.</p>";var o="<p>"+'<button id="survey-feedback-submit" class="button button-primary" '+"onclick=\"window.open('https://wordpress.org/support/plugin/shortpixel-adaptive-images/reviews/?filter=5', '_blank')\">"+"Leave a review"+"</button>"+"</p>";n.find("#survey-feedback-area").html(r+o).slideDown();return}n.find("h3").slideUp();n.find(".survey-rating-btn").closest("p").slideUp();var s=i<=4?"Thank you for your feedback! If you have encountered any issues with our plugin, we are more than eager to help solving them! Please give us more details:":"Thank you for your feedback! Please let us know what we can improve:";n.find("#survey-feedback-prompt").text(s);n.find("#survey-feedback-area").slideDown()}));i.on("click",'.notice[data-causer="recommend_survey"] #survey-feedback-submit',(function(t){t.preventDefault();var a=e(this).closest('.notice[data-causer="recommend_survey"]'),i=a.find(".survey-rating-btn.selected").data("rating"),n=a.find("#survey-feedback").val()||"";e.post(ajaxurl,{action:"shortpixel_ai_send_feedback",data:{rating:i,feedback:n}}).done((function(e){var t=a.find(".message-wrap");if(e.success){t.html("<p>Thank you for your feedback!</p>");a.find("#survey-feedback-area, .buttons-wrap").slideUp()}else{var i=e.data||"Something went wrong sending feedback!";t.html("<p>"+i+"</p>")}}))}))}))})(jQuery,document,window); -
shortpixel-adaptive-images/tags/3.11.0/changelog.txt
r2614181 r3340495 1 = 2.3.3 = 2 Release date: June 30th, 2021 3 * Fix: issue with validating API key 4 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 5 6 = 2.3.2 = 7 Release date: June 29th, 2021 8 * Temporarily deactivate AVIF pending codec bug fix (https://github.com/xiph/rav1e/issues/2757); 9 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 10 11 = 2.3.1 = 12 Release date: June 28th, 2021 13 * New: Version the javascript in the file name in order to get around more stubborn caches; 14 * Fix: do not parse AJAX responses to uploads; 15 * Fix: nested element that has a different background - was taking the background of the parent element; 16 * Fix: notice in logs sometimes when domain info from server; 17 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 18 19 = 2.3.0 = 20 Release date: June 17th, 2021 21 * New: images (including the ones from CSS files) are now served automatically in the new AVIF format to supporting browsers; 22 * New: moved the JS detection mechanism for WebP/AVIF support directly to the CDN level, so no JS is required anymore for this; 23 * Language: 0 new strings added, 6 updated, 0 fuzzed, and 0 obsoleted. 24 25 = 2.2.4 = 26 Release date: June 14th, 2021 27 * Compat: added a constant - `SPAI_ELEMENTOR_WORKAROUND` - to deactivate the parsing of Elementor modules that are resulting in critical errors; 28 * Compat: workaround for WP Rocket that calls in certain circumstances the filter `rocket_css_content` with only one parameter; 29 * Fix: some warnings when lqip queue is not array were showing up in some cases; 30 * Fix: wrong array key when the no background calculation can't determine crop size and returns just width and height; 31 * Fix: iPhone issues with parsing stylesheets while also improving page responsiveness while parsing them (async); 32 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 33 34 = 2.2.3 = 35 Release date: May 18th, 2021 36 * New: also parse inside `<script type="text/template">` blocks; 37 * Fix: the background crop resize wasn't working in several cases, which is now fixed; 38 * Fix: update the notification text about the next generation images served by SPIO; 39 * Fix: cases when a mutation has backgrounds from an existing CSS block are now properly handled; 40 * Fix: the special crop feature now handles correctly the situations when the width parameter isn't the first one; 41 * Fix: the inline background selector will handle situations with no space before the CSS class definition; 42 * Fix: remove the default values for JS parameters in order to support IE11; 43 * Fix: the images from `li` elements added with `data-thumb` are now replaced; 44 * Fix: the URL exclusions are checked when replacing inside JS blocks too; 45 * Language: 0 new strings added, 2 updated, 0 fuzzed, and 0 obsoleted. 46 47 = 2.2.2 = 48 Release date: April 29th, 2021 49 * Fix: the minified version of the plugin CSS files was bigger than the not minified one; 50 * Fix: find local file when URL contains a path element before wp-content, that is not present on disk; 51 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 52 53 = 2.2.1 = 54 Release date: April 26th, 2021 55 * Compat: added integration with Real3D Flipbook; 56 * Fix: there was a "Class not found" error in some cases when purging LiteSpeed cache from our plugin; 57 * Fix: in some cases, the size of background images wasn't properly set; 58 * Fix: protection added for very large number of product variations; the plugin will now work properly in these cases; 59 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 60 61 = 2.2.0 = 62 Release date: April 20th, 2021 63 * New: added filter `shortpixel/ai/customRules` for custom replacement rules; 64 * New: added proper lazy loading for background images; 65 * New: take into account the `background-*` CSS styles: size, position, etc.; 66 * New: lazy load the images in the CSS blocks; 67 * New: handle correctly multiple URLs in the same `background-image:` declaration; 68 * New: when running out of credits you can now have an option to top-up directly from the plugin settings; 69 * Compat: added an integration with the Uncode theme and its iLightBox component; 70 * Compat: added integration with WPC Variations Table; 71 * Compat: added integration with Soliloquy Slider Plugin; 72 * Compat: also integrate properly with Divi child themes; 73 * Compat: improved the integration with Elementor, all images should now be properly replaced; 74 * Fix: WooCommerce product variations were broken if srcset was present, but false; 75 * Fix: in certain cases, background images with important CSS priority weren't properly handled; 76 * Fix: also remove the sizes attribute if we remove the srcset; 77 * Fix: replacement error when html attribute contains "<style>.." data; 78 * Fix: various small fixes to settings, fonts, debug messages, ShortPixel account login and lazy loading; 79 * Language: 7 new strings added, 2 updated, 0 fuzzed, and 3 obsoleted. 80 1 81 = 2.1.6 = 2 82 Release date: March 19th, 2021 -
shortpixel-adaptive-images/tags/3.11.0/includes/actions/notice.actions.class.php
r3209129 r3340495 50 50 die; 51 51 } 52 53 private static function handleRecommendSurvey( $data ) { 54 if ( ( $data['action'] ?? '' ) === 'dismiss' ) { 55 return [ 56 'success' => Notice::dismiss( 'recommend_survey' ), 57 ]; 58 } 59 return null; 60 } 52 61 53 62 private static function handleRemoteInfoNotice ($data){ -
shortpixel-adaptive-images/tags/3.11.0/includes/actions/page.actions.class.php
r3337681 r3340495 60 60 } 61 61 62 if (isset($options->behaviour->storage_url)) { 63 $options->behaviour->storage_url = sanitize_text_field(trim($options->behaviour->storage_url)); 64 } 65 66 if (isset($options->behaviour->host_removal)) { 67 $options->behaviour->host_removal = sanitize_text_field(trim($options->behaviour->host_removal)); 68 } 69 70 62 71 63 72 //translate simple meta options 64 73 $options = ShortPixelAI::translateSimpleOptions( $options ); 65 66 74 $current_options = Options::_()->settings; 75 76 // if user just disabled the LQIP option, delete the LQIP state from DB 77 if (($options->behaviour->lqip ?? null) === false && ($current_options->behaviour->lqip ?? null) === true) { 78 delete_option('shortpixel_ai_lqip_state'); 79 } 67 80 68 81 $success = true; … … 176 189 $cdnMessage = ''; 177 190 $cdnErrorMessage = ''; 178 $messageData = $api_response['message'][' Message'] ?? [];191 $messageData = $api_response['message']['Details'] ?? []; 179 192 //getting the array of messages 180 193 if (!empty($messageData['0']['Message']) || !empty($messageData['CDN']['Message']) || !empty($messageData['CDN']['Error']) ) { … … 252 265 else if ( $action === 'clear lqip cache' ) { 253 266 $success = LQIP::clearCache(); 254 //var_dump('HERE:', $success, $response);exit('this is only for admin button');255 267 $response[ 'success' ] = $success; 256 268 $response[ 'notice' ] = Notice::get( null, [ -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/feedback.class.php
r2627986 r3340495 15 15 */ 16 16 protected $controller; 17 18 private $logger; 17 19 18 20 /** … … 301 303 self::$instance = $this; 302 304 } 303 305 $this->logger = \ShortPixelAILogger::instance(); 304 306 $this->controller = $controller; 305 307 306 308 add_action( 'admin_footer-plugins.php', [ $this, 'generatePopUp' ] ); 307 309 add_action( 'wp_ajax_shortpixel_ai_handle_feedback_action', [ 'ShortPixel\AI\Feedback\Actions', 'handle' ] ); 308 } 309 } 310 311 add_action( 'wp_ajax_shortpixel_ai_send_rating', [ $this, 'handleSurveyAjax' ] ); 312 add_action( 'wp_ajax_shortpixel_ai_send_feedback', [ $this, 'handleSurveyAjax' ] ); 313 } 314 315 public function handleSurveyAjax() { 316 317 318 $rating = isset($_POST['data']['rating']) ? intval($_POST['data']['rating']) : 0; 319 $feedback = isset($_POST['data']['feedback']) ? sanitize_text_field($_POST['data']['feedback']) : ''; 320 321 if ( ! $rating || $rating < 1 || $rating > 10 ) { 322 wp_send_json_error(__('Invalid rating', 'shortpixel-adaptive-images')); 323 } 324 $response = self::sendSurvey( $rating, $feedback ); 325 326 if ( is_wp_error($response) ) { 327 wp_send_json_error(__('Feedback could not be sent.', 'shortpixel-adaptive-images')); 328 } 329 330 Notice::dismiss( 'recommend_survey' ); 331 wp_send_json_success(); 332 333 } 334 335 336 public function sendSurvey( $rating, $feedback, $anonymous = false ) { 337 338 if ( ! is_int( $rating ) || $rating < 1 || $rating > 10 ) { 339 return false; 340 } 341 $wordpress = self::collectWordpressData( ShortPixelAI::is_beta() ); 342 $wordpress['deactivated_plugin']['uninstall_reason'] = 'rating'; 343 $wordpress['deactivated_plugin']['uninstall_details'] = 'Rating: ' . $rating 344 . ( $feedback ? ' – Feedback: ' . $feedback : '' ); 345 346 $body = [ 347 'user' => self::collectUserData( $anonymous ), 348 'wordpress' => $wordpress, 349 ]; 350 $spai_key = Options::_()->settings_general_apiKey; 351 if ( $spai_key && ! $anonymous ) { 352 $body['key'] = $spai_key; 353 } 354 355 return Request::post( 'https://api.shortpixel.com/v2/feedback.php', true, [ 'body' => $body ] ); 356 } 357 } -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/lqip.class.php
r3209129 r3340495 120 120 private $ctrl; 121 121 122 private function normalizeLqipItem(array $item): array { 123 if (!isset($item['source']) || !isset($item['url'])) { 124 return $item; 125 } 126 127 if ($item['source'] === $item['url']) { 128 $item['lqipUrl'] = $item['url']; 129 unset($item['source'], $item['url']); 130 } else {// log to catch them and see if it's really useful to keep both sourcce & url 131 $this->log('LQIP normalize: source ≠ url', [ 132 'source' => $item['source'], 133 'url' => $item['url'], 134 'referer' => $item['referer'] ?? null 135 ]); 136 137 $item['source'] = null; 138 $item['lqipUrl'] = $item['url']; 139 unset($item['url']); 140 } 141 return $item; 142 } 143 144 145 private function provideTimestamp(array $collection): array { 146 $now = time(); 147 foreach ($collection as &$item) { 148 if (!isset($item['timestamp'])) { 149 $item['timestamp'] = $now; 150 } 151 } 152 unset($item); 153 return $collection; 154 } 155 156 private function removeOldItemsFromCollection(array $collection, int $maxAgeSeconds = 86400): array { 157 $threshold = time() - $maxAgeSeconds; 158 return array_filter($collection, function($item) use ($threshold) { 159 return !isset($item['timestamp']) || $item['timestamp'] >= $threshold; 160 }); 161 } 162 163 private function getLqipState() { 164 $state = get_option('shortpixel_ai_lqip_state', null); 165 166 if ($state === null) { 167 // get previous data from old options 168 $state = [ 169 'collection' => Options::_()->get('collection', self::OPTIONS_CATEGORY, []), 170 'processed' => Options::_()->get('processed', self::OPTIONS_CATEGORY, []), 171 ]; 172 $state['collection'] = $this->provideTimestamp($state['collection']); 173 174 update_option('shortpixel_ai_lqip_state', $state); 175 Options::_()->delete('collection', self::OPTIONS_CATEGORY); 176 Options::_()->delete('processed', self::OPTIONS_CATEGORY); 177 } 178 179 if (!is_array($state)) { 180 $state = [ 'collection' => [], 'processed' => [] ]; 181 } 182 183 if (!isset($state['collection']) || !is_array($state['collection'])) $state['collection'] = []; 184 if (!isset($state['processed']) || !is_array($state['processed'])) $state['processed'] = []; 185 186 return $state; 187 } 188 189 private function saveLqipState($state) { 190 update_option('shortpixel_ai_lqip_state', $state); 191 } 192 193 194 122 195 /** 123 196 * Single ton implementation … … 179 252 $valid = !$this->exists( $name ) || $this->expired( $name ); 180 253 if(!$valid) { 181 $this->log("Dropping URL: " . $item. ' name: ' . $name);254 $this->log("Dropping URL: " . json_encode($item) . ' name: ' . $name); 182 255 } 183 256 … … 251 324 */ 252 325 public function eventHandler() { 253 $collection = Options::_()->get( 'collection', self::OPTIONS_CATEGORY, [] ); 254 if(!is_array($collection)) $collection = []; 255 $this->log('LQIP EVT HANLER: COLLECTION: ', $collection); 256 257 if ( empty( $collection ) ) { 258 return; 259 } 260 261 $processed = Options::_()->get( 'processed', self::OPTIONS_CATEGORY, [] ); 262 $this->log('LQIP EVT HANLER: PROCESSED REQUESTS: ', $processed); 326 $state = $this->getLqipState(); 327 $collection = $state['collection']; 328 $processed = $state['processed']; 329 330 $this->log('LQIP EVT HANDLER: PROCESSED REQUESTS: ', $processed); 263 331 264 332 265 333 $collection = $this->filterWithProcessed( $collection, $processed ); 266 267 334 $bundle = array_splice( $collection, 0, self::BUNDLE_CAPACITY ); 268 335 269 $this->log('LQIP EVT HANLER: SETTING COLLECTION: ', $collection); 270 Options::_()->set( $collection, 'collection', self::OPTIONS_CATEGORY ); 271 272 $this->log('LQIP EVT HANLER: GENERATE BUNDLE: ', $bundle); 336 $this->log('LQIP EVT HANDLER: GENERATE BUNDLE: ', $bundle); 337 $state['collection'] = $collection; 338 $this->saveLqipState($state); 273 339 $this->generate( $bundle ); 274 340 … … 291 357 private function schedule( $collection ) { 292 358 if ( !empty( $collection ) && is_array( $collection ) ) { 293 $scheduled_collection = Options::_()->get( 'collection', self::OPTIONS_CATEGORY, [] ); 294 if(!is_array($scheduled_collection)) $scheduled_collection = []; 295 359 $state = $this->getLqipState(); 360 $scheduled_collection = $state['collection']; 296 361 $collection = array_merge( $scheduled_collection, $collection ); 362 $collection = $this->provideTimestamp($collection); 363 $collection = $this->removeOldItemsFromCollection($collection); 297 364 $collection = $this->replaceWithParent( $collection ); 298 365 $collection = $this->filterCollection( $collection ); 299 366 367 $collection = array_map(function($item) { 368 return $this->normalizeLqipItem($item); 369 }, $collection); 370 300 371 $collection = array_filter( $collection, function( $item ) { 301 $name = $this->getFileName( $item[ 'source' ]);372 $name = $this->getFileName( $item[ 'source' ] ?? $item['lqipUrl'] ?? '' ); 302 373 303 374 return !$this->exists( $name ) || $this->expired( $name ); 304 375 } ); 305 376 306 $this->log('SETTING LQIP COLLECTION: ', $collection); 307 308 $ option_set = Options::_()->set( $collection, 'collection', self::OPTIONS_CATEGORY);377 378 $state['collection'] = $collection; 379 $this->saveLqipState($state); 309 380 310 381 if ( empty( $collection ) ) { … … 316 387 $this->reschedule( 'quick' ); 317 388 318 return ['processed' => !!$option_set, 'message' => (!!$option_set ? '' : 'Could not set lqip option.')];389 return ['processed' => true]; 319 390 } 320 391 } … … 337 408 if ( !empty( $collection ) && is_array( $collection ) ) { 338 409 339 $processed = Options::_()->get( 'processed', self::OPTIONS_CATEGORY, [] ); 410 $state = $this->getLqipState(); 411 $processed = $state['processed']; 340 412 $this->log( 'LQIP REQUESTS START. ALREADY PROCESSED: ', $processed ); 341 413 … … 411 483 $return = $this->countAttempts( $return, $processed ); 412 484 $processed = $this->filterCollection( array_merge( $processed, $return ) ); 413 Options::_()->set( $processed, 'processed', self::OPTIONS_CATEGORY ); 485 $state['processed'] = $processed; 486 $this->saveLqipState($state); 414 487 415 488 return $return; … … 435 508 */ 436 509 private function isPlaceholder( $content ) { 437 return empty( $content ) ? false : $this->isSvg( $content ) && strpos( $content, 'feGaussianBlur' ) !== false; 510 return empty( $content ) ? false : $this->isSvg( $content ) && (strpos( $content, 'feGaussianBlur' ) !== false || 511 strpos( $content, 'filter="blur' ) !== false); 438 512 } 439 513 … … 959 1033 if ( !!$this->ctrl->options->settings_behaviour_lqip && $this->ctrl->options->settings_behaviour_processWay === LQIP::USE_INSTANT) 960 1034 { 1035 961 1036 wp_register_script( 'spai-lqip', $this->ctrl->plugin_url . $file, $this->ctrl->options->settings_behaviour_nojquery <= 0 ? [ 'spai-scripts' ] : [], $version, true ); 962 1037 wp_localize_script( 'spai-lqip', 'lqipConstants', [ -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/notice.class.php
r3258698 r3340495 373 373 } 374 374 375 if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] === 'shortpixel-ai-settings') { 376 $installed = get_option( 'shortpixel_ai_installed_time' ); 377 if ( ! $installed ) { 378 update_option( 'shortpixel_ai_installed_time', time() ); 379 } 380 elseif ( time() - $installed >= 30 * DAY_IN_SECONDS ) { 381 $dismissed = self::getDismissed(); 382 if ( !isset( $dismissed->recommend_survey ) ) { 383 Notice::render('recommend_survey', [ 384 'notice' => [ 385 'type' => 'info', 386 'icon' => 'notes', 387 'dismissible' => true, 388 ], 389 'message' => [ 390 'title' => __('How likely are you to recommend ShortPixel AI to a friend or colleague?', 'shortpixel-adaptive-images'), 391 'body' => [ 392 '<p><span style="margin-right:1em;">' . __('Not likely', 'shortpixel-adaptive-images') . '</span>' 393 . implode('', array_map(function ($i) { 394 return '<button class="button survey-rating-btn" ' 395 . 'data-rating="'. $i .'" ' 396 . 'style="margin:0 3px; min-width:2.5em; text-align:center; line-height:1.6;">' 397 . $i 398 . '</button>'; 399 }, range(1, 10))) 400 . '<span style="margin-left:1em;">' . __('Very likely', 'shortpixel-adaptive-images') . '</span></p>', 401 '<div id="survey-feedback-area" style="display:none;margin-top:10px;">' 402 . '<p><strong id="survey-feedback-prompt">' . __('Give us your feedback:', 'shortpixel-adaptive-images') . '</strong></p>' 403 . '<textarea id="survey-feedback" rows="3" style="width:100%;"></textarea><br><br>' 404 . '<button id="survey-feedback-submit" class="button button-primary">' 405 . __('Submit', 'shortpixel-adaptive-images') 406 . '</button>' 407 . '</div>', 408 ], 409 ], 410 ]); 411 } 412 } 413 } 414 375 415 if ( !isset( $dismissed->wp_rocket_defer_js ) && $integrations->has( 'wp-rocket', 'defer-all-js' ) ) { 376 416 self::render( 'wp rocket defer js', [ -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/page.class.php
r3074757 r3340495 244 244 header('Content-Type: application/json'); 245 245 header('Content-Disposition: attachment; filename=SPAI-settings.json'); 246 echo(json_encode($this->ctrl->options->get()->settings , JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));246 echo(json_encode($this->ctrl->options->get()->settings->exportRecursive(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); 247 247 die(); 248 248 } ); -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/regex-parser.class.php
r3209129 r3340495 26 26 private $forceEager = false; 27 27 private $isTemplate = false; 28 private $content; 28 29 29 30 … … 42 43 ]; 43 44 45 46 protected function markTotalExclude(string $tagHtml, string $origUrl): string 47 { 48 $attrs = ' data-spai-target="src"'; 49 $attrs .= ' data-spai-orig="' . esc_attr($origUrl) . '"'; 50 $attrs .= ' data-spai-exclude="nocdn"'; 51 return preg_replace( 52 '/<img\b([^>]*)>/i', 53 '<img$1' . $attrs . '>', 54 $tagHtml, 55 1 56 ); 57 } 44 58 45 59 public function __construct(ShortPixelAI $ctrl) … … 160 174 //In some cases the regex fails with this limit reached (default is 1000000) so make it larger (HS#75940) 161 175 ini_set('pcre.backtrack_limit', 2000000); 176 177 $this->content = $content; 162 178 163 179 foreach (\ShortPixel\AI\TagRules::_()->items() as $tagRule) { … … 670 686 if( !ShortPixelUrlTools::isValid($url) 671 687 && (!$this->isTemplate || strpos($url, '{{:') === false)) {$this->logger->log('NOT VALID');return $text;} 672 if($this->ctrl->urlIsExcluded($url)) {$this->logger->log('EXCLUDED');return $text;} 688 if ($this->ctrl->urlIsExcluded($url)) { 689 $this->logger->log('EXCLUDED TOTALLY: ' . $url); 690 return $this->markTotalExclude($text, $url); 691 } 673 692 674 693 //custom exclusion for SliderRevolution TODO unhack … … 699 718 } 700 719 701 $eager = $this->isEager || $this->ctrl->tagIs('eager', $text) ;720 $eager = $this->isEager || $this->ctrl->tagIs('eager', $text) || $this->ctrl->urlIsEager($url);; 702 721 703 722 SHORTPIXEL_AI_DEBUG && $this->logger->log("Including: " . $url . ($eager ? ' EAGER' : ' LAZY')); … … 776 795 777 796 if($eager) { 778 //we set any CSS or JS to ret_wait because of the many CORS issues we've seen with these.779 $wait = $ext == 'css' || $ext == 'js';797 //we set any CSS or JS or FONTS to ret_wait because of the many CORS issues we've seen with these. 798 $wait = in_array($ext, ShortPixelUrlTools::$EAGER_WAIT); 780 799 $cacheVer = $wait ? $this->ctrl->cssCacheVer : false; 781 800 if($this->isTemplate && strpos($url, '{{:') === 0) { … … 783 802 . '/' . $url; 784 803 } else { 785 $inlinePlaceholder = $this->ctrl->get_api_url( $absoluteUrl, false, false, $this->ctrl->get_extension( $url ), $this->tagRule->getCustomCompression(), $wait, $cacheVer); 804 $separator = strpos($this->content, $absoluteUrl) > 0 && $this->tagRule->attrValFilter == "preload" ? "," : ShortPixelAI::SEP; 805 $inlinePlaceholder = $this->ctrl->get_api_url($absoluteUrl, false, false, $this->ctrl->get_extension($url), $this->tagRule->getCustomCompression(), $wait, $cacheVer, $separator); 786 806 } 787 807 $spaiMarker = ' data-spai-egr=' . $qm . '1' . $qm; … … 1030 1050 $aiSrcsetItems = array(); 1031 1051 $aiUrl = $this->ctrl->get_api_url(false, false); 1032 $aiUrlBase = $this->ctrl->settings->behaviour->api_url; 1052 $aiUrlBase = $this->ctrl->settings->behaviour->api_url; //ex: https://cdn.shortpixel.ai/spai 1053 $aiUrlBaseAmazon = $this->ctrl->settings->behaviour->storage_url; //ex: https://cdn.shortpixel.ai/x9 1033 1054 $srcsetItems = explode(',', $srcset); 1034 1055 foreach($srcsetItems as $srcsetItem) { … … 1040 1061 return $srcset; 1041 1062 } 1042 if(strpos($srcsetItem, $aiUrlBase) !== false || strpos($srcsetItem, 'data:image/') === 0) {1063 if(strpos($srcsetItem, $aiUrlBase) !== false || strpos($srcsetItem, $aiUrlBaseAmazon) !== false || strpos($srcsetItem, 'data:image/') === 0) { 1043 1064 SHORTPIXEL_AI_DEBUG && $this->logger->log("REPLACE SRCSET abort - AI url: " . $srcsetItem); 1044 1065 return $srcset; //already parsed by the hook. -
shortpixel-adaptive-images/tags/3.11.0/includes/controllers/short-pixel-ai.class.php
r3310531 r3340495 470 470 if ( is_null( $this->options->get( 'api_url', [ 'settings', 'behaviour' ], null ) ) ) { 471 471 $this->options->settings_behaviour_apiUrl = ShortPixelAI::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 472 $this->options->settings_behaviour_amazonS3 = false; 472 473 $this->options->settings_behaviour_replaceMethod = 'src'; 473 474 $this->options->settings_behaviour_fadein = true; … … 1133 1134 $result['message'] = __('Invalid selector has been provided.', 'shortpixel-adaptive-images' ); 1134 1135 } 1135 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_ selectors'))) {1136 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_paths', 'eager_selectors'))) { 1136 1137 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1137 1138 } … … 1141 1142 $selectors_now = $this->options->$wp_option_name; 1142 1143 $result['status'] = 'ok'; 1143 if($which === 'excluded_paths' ) {1144 if($which === 'excluded_paths' || $which === 'eager_paths' ) { 1144 1145 $name = 'URL'; 1145 1146 $delimiter = "\n"; … … 1214 1215 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1215 1216 } 1216 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_selectors' ))) {1217 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_selectors', 'eager_paths'))) { 1217 1218 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1218 1219 } … … 1303 1304 $options->settings_behaviour_replaceMethod = $replace_method == 1 ? 'src' : ( $replace_method == 3 ? 'both' : 'srcset' ); 1304 1305 $options->settings_behaviour_apiUrl = get_option( 'spai_settings_api_url' ); 1305 $options->settings_behaviour_hoverHandling = !!get_option( 'spai_settings_hover_handling' );1306 $options->settings_behaviour_hoverHandling = !!get_option( 'spai_settings_hover_handling' ); 1306 1307 $options->settings_behaviour_nativeLazy = !!get_option( 'spai_settings_native_lazy' ); 1307 1308 … … 1503 1504 if (function_exists('is_plugin_active') && is_plugin_active('sg-cachepress/sg-cachepress.php')) { 1504 1505 $speedoptimizer = get_option('siteground_optimizer_combine_javascript', false); 1505 //var_dump($speedoptimizer);1506 1506 if ($speedoptimizer === '1') { 1507 1507 $this->conflict = 'speedoptimizer'; … … 1551 1551 } 1552 1552 1553 public function get_api_url( $url = false, $width = '%WIDTH%', $height = '%HEIGHT%', $type = false, $compression = false, $retAuto = false, $cacheVer = false) { 1553 1554 /** 1555 * This function checks whether the CDN returned by get_cdn_url() is different 1556 * from the default "https://cdn.shortpixel.ai/spai". 1557 * 1558 * If it is different, we consider it a "custom CDN". 1559 */ 1560 private function is_custom_cdn() 1561 { 1562 $cdn = $this->get_cdn_url(); 1563 if (!$cdn) { 1564 $cdn = self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 1565 } 1566 $cdn = rtrim($cdn, '/'); 1567 $defaultCdn = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1568 $isBasicCustom = ($cdn !== $defaultCdn); 1569 1570 return $isBasicCustom; 1571 } 1572 1573 private function is_amazon_cdn(){ 1574 $amazonGet = $this->settings->behaviour->amazon_s3; 1575 $amazonEnabled = !empty($amazonGet); 1576 $amazonStorageGet = $this->settings->behaviour->storage_url; // tha's the user input 1577 $amazonStorage = !empty($amazonStorageGet); 1578 // only if user has a storage_url (and amazon_s3 is enabled), we consider that is 'custom as well. 1579 $isAmazonCustom = ($amazonEnabled && $amazonStorage); 1580 1581 return $isAmazonCustom; 1582 } 1583 1584 /** 1585 * chooses the appropriate API base URL based on CDN settings. 1586 * 1587 * @param string|false $url The original URL. 1588 * @return string The selected base URL. 1589 */ 1590 public function choose_api_base() 1591 { 1592 $isAmazonCdn = $this->is_amazon_cdn(); 1593 1594 if ($isAmazonCdn) { 1595 return rtrim($this->settings->behaviour->storage_url, '/'); 1596 } else { 1597 $cdnUrl = rtrim($this->get_cdn_url(), '/'); 1598 if (!$cdnUrl) { 1599 $cdnUrl = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1600 } 1601 return $cdnUrl; 1602 } 1603 } 1604 1605 private function do_host_removal(){ 1606 $hostRemovalGet = $this->settings->behaviour->host_removal; 1607 $isHostRemoval = !empty($hostRemovalGet); 1608 return$isHostRemoval; 1609 } 1610 1611 /** 1612 * Applies host removal to the API URL if conditions are met. 1613 * 1614 * @param string $api_url The constructed API URL. 1615 * @param string|false $url The original URL. 1616 * @return string The final URL after host removal (if applied). 1617 */ 1618 private function host_removal_logic($api_url, $url) 1619 { 1620 if (!$url) { 1621 return $api_url; 1622 } 1623 1624 $doHostRemoval = $this->do_host_removal(); 1625 $hostRemoval = $this->settings->behaviour->host_removal; 1626 1627 if ($doHostRemoval && $url){ 1628 $parsedUrl = parse_url($url); 1629 $host = $parsedUrl['host'] ?? ''; 1630 1631 if (strpos($host, $hostRemoval) !== false) { 1632 $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; 1633 $query = isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : ''; 1634 $frag = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : ''; 1635 $final = rtrim($api_url, '/') . $path . $query . $frag; 1636 return $final; 1637 } 1638 } 1639 1640 return $api_url; 1641 } 1642 1643 1644 1645 1646 /** 1647 * This helper method builds the final URL by appending ShortPixel parameters 1648 * (w_, q_, ex_, to_, etc.) to the base URL using self::SEP. 1649 * 1650 * @param string $baseUrl e.g. "https://cdn.shortpixel.ai/spai" 1651 * @param array $args e.g. [ ['w' => 300], ['q' => 'lossy'], ['ex' => '1'] ] 1652 * @return string e.g. "https://cdn.shortpixel.ai/spai/w_300+q_lossy+ex_1" 1653 */ 1654 private function build_spai_url($baseUrl, array $args, $separator = self::SEP){ 1655 $api_url = trailingslashit($baseUrl); 1656 foreach ($args as $arg) { 1657 foreach ($arg as $k => $v) { 1658 $api_url .= $k . '_' . $v . $separator; 1659 } 1660 } 1661 return rtrim($api_url, $separator); 1662 1663 } 1664 public function get_api_url( $url = false, $width = '%WIDTH%', $height = '%HEIGHT%', $type = false, $compression = false, $retAuto = false, $cacheVer = false, $separator = self::SEP) { 1665 1666 if ($url && $this->urlIsExcluded($url)) { 1667 $this->logger->log("DEBUG get_api_url: URL completly excluded. Returning original URL: " . $url); 1668 return $url; 1669 } 1554 1670 $args = array(); 1555 1671 $http = $url === false ? !is_ssl() : !self::is_ssl($url); 1556 1672 1557 if ($compression == 'orig' && defined('SHORTPIXEL_AI_ORIG_NO_CDN')) {1673 if ($compression == 'orig' && defined('SHORTPIXEL_AI_ORIG_NO_CDN')) { 1558 1674 return ''; 1559 1675 } … … 1590 1706 } 1591 1707 1592 $api_url = $this->get_cdn_url(); 1593 1594 if ( !$api_url ) { 1595 $api_url = self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 1596 } 1597 1598 $api_url = trailingslashit($api_url); 1599 1600 /* 1601 Make args to be in desired format 1602 */ 1603 foreach ($args as $arg) { 1604 foreach ($arg as $k => $v) { 1605 $api_url .= $k . '_' . $v . self::SEP; 1606 } 1607 } 1608 $api_url = rtrim($api_url, self::SEP); 1609 //$api_url = trailingslashit( $api_url ); 1610 return $api_url . ($url ? '/' . self::rem_proto($url) : ''); 1611 } 1708 1709 $isAmazonCdn = $this->is_amazon_cdn(); //verify if it is amazon CDN 1710 1711 // detect bucket name presence in host 1712 $hostFound = false; 1713 if ($isAmazonCdn) { 1714 $hostRemovalGet = $this->settings->behaviour->host_removal ?? null; 1715 1716 if ($hostRemovalGet && $url) { 1717 $parsed = parse_url($url); 1718 $host = $parsed['host'] ?? ''; 1719 if (strpos($host, $hostRemovalGet) !== false) { 1720 $hostFound = true; 1721 } 1722 } 1723 } 1724 if ($hostFound){ 1725 // case 1: amazon CDN active and URL contains host_removal, will apply amazon cdn + host removal 1726 $amazonStorageGet = $this->settings->behaviour->storage_url; 1727 $base = rtrim($amazonStorageGet, '/'); // Amazon base 1728 $api_url = $this->build_spai_url($base, $args, $separator); 1729 $this->logger->log("BUILT Amazon api_url => ", $api_url); 1730 1731 $final_url = $this->host_removal_logic($api_url, $url); 1732 if ($final_url !== $api_url) { 1733 return $final_url; 1734 } 1735 if (!$url) { 1736 return $api_url; 1737 } 1738 1739 $ret = $api_url . '/' . self::rem_proto($url); 1740 return $ret; 1741 } else { 1742 // case 2: Amazon CDN active but URL does't match host_removal will not put amazon cdn and not remove host 1743 // case 3: Amazon CDN disabled ... get as usual with normal cdn 1744 $base = rtrim($this->get_cdn_url(), '/'); 1745 if (!$base) { 1746 $base = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1747 } 1748 $api_url = $this->build_spai_url($base, $args, $separator); 1749 1750 if (!$url) { 1751 return $api_url; 1752 } 1753 1754 $final = $api_url . '/' . self::rem_proto($url); 1755 return $final; 1756 } 1757 } 1612 1758 1613 1759 public function maybe_replace_images_src($content) … … 1753 1899 'noresize_selectors' => $this->splitSelectors( @$ex->noresize_selectors, ',' ), 1754 1900 'excluded_paths' => $this->splitSelectors( @$ex->excluded_paths, "\n" ), 1901 'eager_paths' => $this->splitSelectors( @$ex->eager_paths, "\n" ), 1755 1902 'excluded_pages' => $this->splitSelectors( @$ex->excluded_pages, "\n" ), 1756 1903 ]; … … 1811 1958 } 1812 1959 1813 public function urlIsExcluded($url) { 1814 1815 //exclude generated images like JetPack's admin bar hours stats 1816 if(strpos($url, '?page=')) { 1817 $admin = parse_url(admin_url()); 1818 if(isset($admin['path']) && strpos($url, $admin['path'])) { 1819 return true; 1820 } 1821 } 1822 1823 if( strlen($this->settings->exclusions->excluded_paths)) { 1824 return $this->isExcluded($url, $this->settings->exclusions->excluded_paths); 1825 } else { 1826 return false; 1827 } 1828 1829 } 1830 1960 1961 /** 1962 * 1963 * This function parses the given URL and removes any resolution suffix (e.g., "-1024x576") 1964 * that is automatically appended by some WordPress themes for images. * 1965 * 1966 * useful when comparing image URLs against exclusion rules, insuring that any 1967 * appended resolution suffix does not prevent a match with the base URL. 1968 * 1969 * @param string $url - original image URL. 1970 * @return string - normalized image URL without the resolution suffix, or the original URL if parsing fails. 1971 */ 1972 public function normalizeUrlForExcluded($url) { 1973 $parsed = parse_url($url); 1974 $this->logger->log("DEBUG: parsed " . json_encode($parsed, JSON_PRETTY_PRINT)); //var_export($parsed) //print_r($parsed) 1975 if (!isset($parsed['path'])) { 1976 return $url; 1977 } 1978 $normalizedPath = preg_replace( 1979 '/-\d+x\d+(?=\.\w+$)/', 1980 '', 1981 $parsed['path'] 1982 ); 1983 $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : (is_ssl() ? 'https' : 'http'); 1984 $siteUrl = home_url(); 1985 $siteHost = parse_url($siteUrl, PHP_URL_HOST); 1986 return $scheme . '://' . $siteHost . $normalizedPath; 1987 } 1988 1989 /** 1990 * Core URL-matching method to test either total or eager exclusion. 1991 * 1992 * @param string $mode Either 'excluded' (full exclusion) or 'eager' (skip lazy only) 1993 * @param string $url The image URL (may include CDN, Amazon, any host or size suffix) 1994 * @return bool True for matching either one mode’s rules 1995 */ 1996 public function urlIs($mode, $url) 1997 { 1998 //revert CDN url to original 1999 if ($this->urlIsApi($url)) { 2000 $stripped = self::rem_proto($url); 2001 $scheme = self::is_ssl($url) ? 'https://' : 'http://'; 2002 $url = $scheme . $stripped; 2003 $this->logger->log("DEBUG urlIs: Reverted CDN URL to original: $url"); 2004 } 2005 //exclude generated images like JetPack's admin bar hours stats 2006 if (strpos($url, '?page=')) { 2007 $admin = parse_url(admin_url()); 2008 if (strpos($url, $admin['path'])) { 2009 return true; 2010 } 2011 } 2012 //normalize any resolution suffix... 2013 $normalizedUrl = $this->normalizeUrlForExcluded($url); 2014 $this->logger->log("DEBUG urlIsExcluded: Normalized URL: " . $normalizedUrl); 2015 //2 posibilities URL -> total exclusion('excluded') or eager exclusion('eager') 2016 $list = ($mode === 'excluded') 2017 ? $this->settings->exclusions->excluded_paths 2018 : $this->settings->exclusions->eager_paths; 2019 if (strlen($list)) { 2020 if ($this->isExcluded($url, $list) || $this->isExcluded($normalizedUrl, $list)) { 2021 return true; 2022 } 2023 } 2024 2025 return false; 2026 2027 } 2028 2029 /** 2030 * FULL-EXCLUSION wrapper: 2031 * Returns true if this URL must skip CDN entirely (no lazy, no CDN). 2032 * 2033 * @param string $url 2034 * @return bool 2035 */ 2036 public function urlIsExcluded(string $url): bool 2037 { 2038 return $this->urlIs('excluded', $url); 2039 } 2040 2041 /** 2042 * EAGER-ONLY wrapper: 2043 * Returns true if this URL should load eagerly (CDN OK but no lazy loading). 2044 * 2045 * @param string $url 2046 * @return bool 2047 */ 2048 public function urlIsEager(string $url): bool 2049 { 2050 return $this->urlIs('eager', $url); 2051 } 1831 2052 1832 2053 /** … … 1876 2097 case 'http': //being so kind to accept urls as they are. :) 1877 2098 case 'https': 1878 if(!isset($urlParsed['host'])) {1879 $valueParsed = parse_url($value);1880 if(isset($valueParsed['host'])) {1881 $url = ShortPixelUrlTools::absoluteUrl($url);1882 }1883 }1884 2099 if(strpos($url, $value) !== false) { 1885 2100 $this->logger->log("EXCLUDED by $type $value RULE:", $rule); 1886 2101 return true; 1887 2102 } 2103 2104 if (isset($urlParsed['path'])) { 2105 $ruleParsed = parse_url($value); 2106 if (!empty($ruleParsed['path'])) { 2107 $rulePathNorm = preg_replace('/-\d+x\d+(?=\.\w+$)/', '', $ruleParsed['path']); 2108 $urlPathNorm = preg_replace('/-\d+x\d+(?=\.\w+$)/', '', $urlParsed['path']); 2109 if ($rulePathNorm === $urlPathNorm) { 2110 $this->logger->log("EXCLUDED by HOST-INSENSITIVE PATH MATCH: $rulePathNorm"); 2111 return true; 2112 } 2113 } 2114 } 1888 2115 if(isset($urlParsed['path'])) { 1889 2116 preg_match(self::THUMBNAIL_REGEX, $urlParsed['path'], $matches); … … 2059 2286 'exclusions' => [ 2060 2287 'excluded_paths' => self::GRAVATAR_REGEX, 2061 'eager_selectors' => '', 2288 'eager_paths' => '', 2289 'eager_selectors' => '', 2062 2290 'noresize_selectors' => '', 2063 2291 'excluded_selectors' => '', -
shortpixel-adaptive-images/tags/3.11.0/includes/front/jquery-js-loader.class.php
r3209129 r3340495 70 70 //the excluded_paths can contain URLs so we base64 encode them in order to pass our own JS parser :) 71 71 'excluded_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->excluded_paths, PHP_EOL ) ), 72 'eager_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL ) ), 72 73 ] ); 73 74 -
shortpixel-adaptive-images/tags/3.11.0/includes/front/vanilla-js-loader.class.php
r3337681 r3340495 17 17 add_action( 'wp_head', function() { 18 18 $apiUrlParts = explode('/', rtrim($this->ctrl->get_cdn_url(), '/')); 19 $customApiUrlParts = explode('/', rtrim($this->ctrl->choose_api_base(), '/')); 20 $customKeys = []; 21 if ($this->settings->behaviour->amazon_s3) { 22 $hostRemoval = $this->settings->behaviour->host_removal; 23 $customKey = end($customApiUrlParts); 24 if ($hostRemoval && $customKey) { 25 $customKeys[$hostRemoval] = $customKey; 26 } 27 } 28 19 29 $convert = 'none'; 20 30 if(!!$this->settings->compression->webp || !!$this->settings->compression->avif) { … … 47 57 version: "<?= esc_js(SHORTPIXEL_AI_VERSION) ?>", 48 58 key: "<?= esc_js(end($apiUrlParts)) ?>", 59 customKeys: <?= wp_json_encode($customKeys) ?>, 49 60 quality: "<?= esc_js($this->settings->compression->level) ?>", 50 61 convert: "<?= esc_js($convert) ?>", … … 91 102 'noresize_selectors' => $this->ctrl->splitSelectors( $this->settings->exclusions->noresize_selectors, ',' ), 92 103 'excluded_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->excluded_paths, PHP_EOL ) ), 104 'eager_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL ) ), 93 105 ]); 94 106 wp_enqueue_script( 'spai-snip-action' ); … … 273 285 ['lazy' => 0, 'cdn' => 0, 'resize' => 0, 'crop' => -1]); 274 286 } 287 288 foreach($this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL) as $eagerPath) { 289 $this->alterExclusion($exclusions, 'urls', $eagerPath, ['lazy' => 0]); 290 } 291 275 292 foreach($this->ctrl->splitSelectors( $this->settings->exclusions->excluded_selectors, ',') as $excludedSel) { 276 293 $this->alterExclusion($exclusions, 'selectors', $excludedSel, -
shortpixel-adaptive-images/tags/3.11.0/includes/helpers/url-tools.class.php
r3160580 r3340495 17 17 'eot', 'woff', 'woff2', 'ttf', 'otf' ]; 18 18 public static $ONLY_STORE = [ 'svg', 'js', 'eot', 'webp', 'avif', 'woff', 'woff2', 'ttf', 'otf' ]; 19 public static $EAGER_WAIT = [ 'css', 'js', 'woff2', 'woff', 'otf', 'ttf', 'eot' ]; 19 20 private static $SIZE_CACHE = []; 20 21 -
shortpixel-adaptive-images/tags/3.11.0/includes/models/options.category.class.php
r3125365 r3340495 15 15 public function getData() { 16 16 return $this->__dyna; 17 } 18 19 /** 20 * exports the internal data structure of the Category object 21 * - traverses internal proteected __dyna object, and for each property, 22 * it checks if the value is another Category, Option, stdClass. 23 * @return array fully expanded data structure. 24 */ 25 public function exportRecursive() { 26 $result = []; 27 28 foreach ((array) $this->getData() as $key => $value) { 29 if ($value instanceof \ShortPixel\AI\Options\Category) { 30 $result[$key] = $value->getData(); 31 } elseif ($value instanceof \ShortPixel\AI\Options\Option) { 32 $result[$key] = $value->getData(); 33 } elseif ($value instanceof \stdClass) { 34 $result[$key] = json_decode(json_encode($value), true); 35 } else { 36 $result[$key] = $value; 37 } 38 } 39 return $result; 17 40 } 18 41 -
shortpixel-adaptive-images/tags/3.11.0/includes/views/settings.tpl.php
r3209129 r3340495 706 706 </td> 707 707 </tr> 708 709 710 <tr> 711 <th scope="row"> 712 <?= __( 'Amazon S3', 'shortpixel-adaptive-images' ); ?> 713 </th> 714 <td> 715 <div class="spai-inline-help"> 716 <span class="dashicons dashicons-editor-help" 717 title="Inline help" 718 data-link="https://shortpixel.com/knowledge-base/article/using-shortpixel-adaptive-images-with-images-on-amazon-s3/"></span> 719 </div> 720 <input 721 id="amazon_s3" 722 type="checkbox" 723 name="amazon_s3" 724 class="tgl" 725 data-type="bool" 726 value="1" 727 <?php checked( 1, $options->settings_behaviour_amazonS3, true ); ?> 728 /> 729 730 <label for="amazon_s3" class="tgl-btn"> 731 <span></span> 732 <?= __( 'Deliver the images stored on Amazon S3 using ShortPixel CDN', 'shortpixel-adaptive-images' ); ?> 733 </label> 734 <p class="description"> 735 <?= __( 'Enable this option if you are offloading the images to an Amazon S3 bucket and you want to deliver them via our CDN to reduce costs. Read the configuration guide in <a href="https://shortpixel.com/knowledge-base/article/using-shortpixel-adaptive-images-with-images-on-amazon-s3/" target="_blank">our knowledge base</a>', 'shortpixel-adaptive-images' ); ?> 736 </p> 737 <div class="amazon-s3-fields-wrapper"> 738 <p> 739 <label for="storage_url" style="display: inline-block; width: 140px;"> 740 <strong><?= __( 'Base URL', 'shortpixel-adaptive-images' ); ?></strong> 741 </label> 742 <input 743 id="storage_url" 744 type="text" 745 data-type="string" 746 name="storage_url" 747 size="40" 748 placeholder="<?= __( 'Paste Base URL from ShortPixel Dashboard', 'shortpixel-adaptive-images' ); ?>" 749 value="<?= esc_attr( $options->settings_behaviour_storageUrl ); ?>" 750 <?php disabled(!$options->settings_behaviour_amazonS3, true); ?> 751 /> 752 753 754 </p> 755 <p> 756 <label for="host_removal" style="display: inline-block; width: 140px;"> 757 <strong><?= __( 'S3 Bucket URL', 'shortpixel-adaptive-images' ); ?></strong> 758 </label> 759 <input 760 id="host_removal" 761 type="text" 762 data-type="string" 763 name="host_removal" 764 size="40" 765 placeholder="<?= __( 'Get it from your Amazon S3 bucket details', 'shortpixel-adaptive-images' ); ?>" 766 value="<?= esc_attr( $options->settings_behaviour_hostRemoval ); ?>" 767 <?php disabled(!$options->settings_behaviour_amazonS3, true); ?> 768 /> 769 </p> 770 </div> 771 <script> 772 jQuery(document).ready(function($){ 773 $('#amazon_s3').on('change', function() { 774 var isChecked = $(this).is(':checked'); 775 $('#storage_url, #host_removal').prop('disabled', !isChecked); 776 }).trigger('change'); 777 }); 778 </script> 779 </td> 780 </tr> 781 782 708 783 <tr> 709 784 <th scope="row"> … … 1366 1441 $no_resize_selectors = $options->settings_exclusions_noresizeSelectors; 1367 1442 $excluded_selectors = $options->settings_exclusions_excludedSelectors; 1443 $eager_paths = $options->settings_exclusions_eagerPaths; 1368 1444 $excluded_paths = $options->settings_exclusions_excludedPaths; 1369 1445 $excluded_pages = $options->settings_exclusions_excludedPages; … … 1373 1449 'no_resize_selectors' => $controller->splitSelectors( $no_resize_selectors, ',' ), 1374 1450 'excluded_selectors' => $controller->splitSelectors( $excluded_selectors, ',' ), 1451 'eager_paths' => $controller->splitSelectors( $eager_paths, PHP_EOL ), 1375 1452 'excluded_paths' => $controller->splitSelectors( $excluded_paths, PHP_EOL ), 1376 1453 ]; … … 1382 1459 1383 1460 $excluded_selectors_qty = count( $split_selectors[ 'eager_selectors' ] ) + count( $split_selectors[ 'no_resize_selectors' ] ) + count( $split_selectors[ 'excluded_selectors' ] ); 1384 $excluded_paths_qty = count( $split_selectors[ 'excluded_paths' ] ) ;1461 $excluded_paths_qty = count( $split_selectors[ 'excluded_paths' ] ) + count( $split_selectors[ 'eager_paths' ] ); 1385 1462 ?> 1386 1463 <table class="form-table"> … … 1448 1525 <?= str_replace( '{{QTY}}', $excluded_paths_qty, __( 'You already have <span>{{QTY}}</span> URL exclusions active. Please keep the number of exclusion selectors low for best performance.', 'shortpixel-adaptive-images' ) ); ?> 1449 1526 </p> 1450 <div> 1527 1528 <div><label for="eager_paths"><?= __( 'Don\'t lazy-load Url\'s:', 'shortpixel-adaptive-images' ); ?></label><br> 1529 <textarea 1530 id="eager_paths" 1531 name="eager_paths" 1532 rows="5" 1533 data-type="string" 1534 data-exclusion-type="urls" 1535 data-setting="exclusion" 1536 data-separator="<?= PHP_EOL; ?>" 1537 ><?= $eager_paths; ?></textarea> 1538 </div> 1539 <div><label for="excluded_paths"><?= __( 'Leave out completely Url\'s:', 'shortpixel-adaptive-images' ); ?></label><br> 1451 1540 <textarea 1452 1541 id="excluded_paths" -
shortpixel-adaptive-images/tags/3.11.0/readme.txt
r3337681 r3340495 5 5 Tested up to: 6.8 6 6 Requires PHP: 5.6.40 7 Stable tag: 3.1 0.57 Stable tag: 3.11.0 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 249 249 250 250 == Changelog == 251 252 = 3.11.0 = 253 254 🌩️ The S3 & Speed Boost Update 255 256 Release Date: August 6, 2025 257 258 ✨ New Features 259 260 * Amazon S3 Integration: Images stored on Amazon S3 can now be seamlessly served through the ShortPixel CDN — faster delivery, no matter where your files live. 261 * Lazy-Load Exclusions by URL: You can now exclude specific images from lazy-loading by their URL for greater control over your image loading strategy. 262 263 ⚙️ Improvements 264 265 * Smarter LQIP Handling: Optimized the way Low-Quality Image Placeholders (LQIPs) are processed to boost performance on sites with lots of images. 266 267 🛠️ Fixes 268 269 * Settings Export Restored: Exporting your plugin settings now works reliably in all scenarios. 270 * LQIP Fixes: Addressed several minor issues to ensure LQIPs behave correctly across different setups. 271 * Security Enhancements: Added extra security checks to strengthen protection and prevent potential vulnerabilities. 272 273 Update now to enjoy smarter performance, better control, and enhanced flexibility with your image delivery! 🚀 251 274 252 275 = 3.10.5 = … … 691 714 * Language: 18 new strings added, 51 updated, 0 fuzzed, and 12 obsoleted. 692 715 693 = 2.3.3 =694 Release date: June 30th, 2021695 * Fix: issue with validating API key696 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.697 698 = 2.3.2 =699 Release date: June 29th, 2021700 * Temporarily deactivate AVIF pending codec bug fix (https://github.com/xiph/rav1e/issues/2757);701 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.702 703 = 2.3.1 =704 Release date: June 28th, 2021705 * New: Version the javascript in the file name in order to get around more stubborn caches;706 * Fix: do not parse AJAX responses to uploads;707 * Fix: nested element that has a different background - was taking the background of the parent element;708 * Fix: notice in logs sometimes when domain info from server;709 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.710 711 = 2.3.0 =712 Release date: June 17th, 2021713 * New: images (including the ones from CSS files) are now served automatically in the new AVIF format to supporting browsers;714 * New: moved the JS detection mechanism for WebP/AVIF support directly to the CDN level, so no JS is required anymore for this;715 * Language: 0 new strings added, 6 updated, 0 fuzzed, and 0 obsoleted.716 717 = 2.2.4 =718 Release date: June 14th, 2021719 * Compat: added a constant - `SPAI_ELEMENTOR_WORKAROUND` - to deactivate the parsing of Elementor modules that are resulting in critical errors;720 * Compat: workaround for WP Rocket that calls in certain circumstances the filter `rocket_css_content` with only one parameter;721 * Fix: some warnings when lqip queue is not array were showing up in some cases;722 * Fix: wrong array key when the no background calculation can't determine crop size and returns just width and height;723 * Fix: iPhone issues with parsing stylesheets while also improving page responsiveness while parsing them (async);724 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.725 726 = 2.2.3 =727 Release date: May 18th, 2021728 * New: also parse inside `<script type="text/template">` blocks;729 * Fix: the background crop resize wasn't working in several cases, which is now fixed;730 * Fix: update the notification text about the next generation images served by SPIO;731 * Fix: cases when a mutation has backgrounds from an existing CSS block are now properly handled;732 * Fix: the special crop feature now handles correctly the situations when the width parameter isn't the first one;733 * Fix: the inline background selector will handle situations with no space before the CSS class definition;734 * Fix: remove the default values for JS parameters in order to support IE11;735 * Fix: the images from `li` elements added with `data-thumb` are now replaced;736 * Fix: the URL exclusions are checked when replacing inside JS blocks too;737 * Language: 0 new strings added, 2 updated, 0 fuzzed, and 0 obsoleted.738 739 = 2.2.2 =740 Release date: April 29th, 2021741 * Fix: the minified version of the plugin CSS files was bigger than the not minified one;742 * Fix: find local file when URL contains a path element before wp-content, that is not present on disk;743 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.744 745 = 2.2.1 =746 Release date: April 26th, 2021747 * Compat: added integration with Real3D Flipbook;748 * Fix: there was a "Class not found" error in some cases when purging LiteSpeed cache from our plugin;749 * Fix: in some cases, the size of background images wasn't properly set;750 * Fix: protection added for very large number of product variations; the plugin will now work properly in these cases;751 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.752 753 = 2.2.0 =754 Release date: April 20th, 2021755 * New: added filter `shortpixel/ai/customRules` for custom replacement rules;756 * New: added proper lazy loading for background images;757 * New: take into account the `background-*` CSS styles: size, position, etc.;758 * New: lazy load the images in the CSS blocks;759 * New: handle correctly multiple URLs in the same `background-image:` declaration;760 * New: when running out of credits you can now have an option to top-up directly from the plugin settings;761 * Compat: added an integration with the Uncode theme and its iLightBox component;762 * Compat: added integration with WPC Variations Table;763 * Compat: added integration with Soliloquy Slider Plugin;764 * Compat: also integrate properly with Divi child themes;765 * Compat: improved the integration with Elementor, all images should now be properly replaced;766 * Fix: WooCommerce product variations were broken if srcset was present, but false;767 * Fix: in certain cases, background images with important CSS priority weren't properly handled;768 * Fix: also remove the sizes attribute if we remove the srcset;769 * Fix: replacement error when html attribute contains "<style>.." data;770 * Fix: various small fixes to settings, fonts, debug messages, ShortPixel account login and lazy loading;771 * Language: 7 new strings added, 2 updated, 0 fuzzed, and 3 obsoleted.772 716 773 717 = EARLIER VERSIONS = -
shortpixel-adaptive-images/tags/3.11.0/short-pixel-ai.php
r3337681 r3340495 4 4 * Plugin URI: https://shortpixel.com/ 5 5 * Description: Display properly sized, smart cropped and optimized images on your website. Images are processed on the fly and served from our CDN. 6 * Version: 3.1 0.56 * Version: 3.11.0 7 7 * Author: ShortPixel 8 8 * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-adaptive-images … … 16 16 17 17 if ( !class_exists( 'ShortPixelAI' ) ) { 18 define( 'SHORTPIXEL_AI_VERSION', '3.1 0.5' );18 define( 'SHORTPIXEL_AI_VERSION', '3.11.0' ); 19 19 define( 'SPAI_SNIP_VERSION', '3.1.0' ); 20 20 define( 'SHORTPIXEL_AI_VANILLAJS_VER', '1.1' ); … … 103 103 $old_error_handler = set_error_handler( [ 'ShortPixelAILogger', 'errorHandler' ] ); 104 104 } 105 function activatedTimeCollect(){ 106 update_option('shortpixel_ai_installed_time', time()); 107 } 105 108 106 109 register_activation_hook( __FILE__, [ 'ShortPixelAI', 'activate' ] ); … … 112 115 ShortPixelAI::_(); 113 116 } ); 114 } 117 118 } -
shortpixel-adaptive-images/trunk/assets/css/admin.css
r3209129 r3340495 381 381 } 382 382 383 .blue_link { 383 .blue_link, 384 .survey-rating-btn, #survey-feedback-submit { 384 385 cursor : pointer; 385 386 color : #ffffff !important; … … 402 403 } 403 404 404 .dark_blue_link:hover, .blue_link:hover { 405 .dark_blue_link:hover,.blue_link:hover, 406 .survey-rating-btn:hover, #survey-feedback-submit { 405 407 color : #ffffff !important; 406 408 border : none !important; 407 opacity : 0. 9!important;409 opacity : 0.7 !important; 408 410 } 409 411 -
shortpixel-adaptive-images/trunk/assets/css/admin.min.css
r3209129 r3340495 1 .shortpixel-settings-wrap input,.shortpixel-settings-wrap textarea,.shortpixel-settings-wrap button{outline:unset!important}.plugins tr[data-slug=shortpixel-adaptive-images] td div p span{display:block;margin:5px 0;padding-left:25px}.shortpixel-on-boarding-wrap{background:#fff}.shortpixel-on-boarding-wrap .socials-block{width:100%;max-width:1e3px;margin-top:10px}.socials-block,.socials-block *{-webkit-box-sizing:border-box;box-sizing:border-box}.socials-block{position:relative;padding:20px;border-radius:15px;font-weight:600;margin-bottom:10px;background:#dfffff}.socials-block>.message-wrap{width:100%;color:#05869f;padding-right:200px}.socials-block:before{content:'';position:absolute;display:block;width:20px;height:20px;top:-8px;left:20px;background:url(../img/socials/share.svg)50%/contain no-repeat}.socials-block>.buttons-wrap{position:absolute;display:block;top:calc(50% - 20px);right:20px}.socials-block [data-social]:before{content:'';position:absolute;width:16px;height:16px;top:calc(50% - 8px);left:7px}.socials-block [data-social]:last-child{margin-right:0}.socials-block [data-social]{position:relative;display:block;float:left;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;line-height:20px;margin-right:5px;border-radius:10px;padding:10px 10px 10px 30px;text-decoration:unset;outline:none;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.socials-block [data-social=twitter]{background:#d9e9f9;color:#2c76ec}.socials-block [data-social=twitter]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(44,118,236,.2);box-shadow:inset 1px 2px 2px rgba(44,118,236,.2)}.socials-block [data-social=twitter]:before{background:url(../img/socials/twitter.svg)50%/contain no-repeat}.socials-block [data-social=facebook]{background:#d9e6ff;color:#2152b3}.socials-block [data-social=facebook]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(33,82,179,.2);box-shadow:inset 1px 2px 2px rgba(33,82,179,.2)}.socials-block [data-social=facebook]:before{background:url(../img/socials/facebook.svg)50%/contain no-repeat}.sp-obw__title-wrap img{height:64px;width:64px;float:left;margin:10px 20px 10px 10px}.sp-obw__title-wrap{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.sp-obw__title-wrap:after{position:absolute;bottom:0;left:0;clear:both;width:100%;height:1px;background:#ccc;content:'';display:block}.sp-obw__content-wrap{padding:20px}.sp-obw__content-wrap p{font-size:14px}.sp-obw__content-wrap span.sp-obw-step{line-height:36px}.sp-obw__content-wrap span.sp-obw-alert{font-weight:600;color:crimson}.sp-obw__content-wrap .step-message-wrap label{vertical-align:top;margin-right:10px}.sp-obw__content-wrap .step-message-wrap p button{margin:0 10px 0 0}.sp-obw__content-wrap .step-message-wrap p button:last-child{margin:0}.sp-obw__content-wrap .step-message-wrap button:disabled{color:#a0a5aa!important;border-color:#ddd!important;background:#f7f7f7!important;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3)!important;box-shadow:0 1px 1px rgba(171,170,170,.3)!important}.bordered_link{cursor:pointer;color:#1fbec9;font-size:14px;line-height:18px;padding:5px 10px;display:inline-block;background:#f5f5f5!important;border:1px solid #1fbec9!important;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3);box-shadow:0 1px 1px rgba(171,170,170,.3);border-radius:3px;text-decoration:none;margin-bottom:15px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.bordered_link:hover{color:#0f6b7e!important;background:0 0!important}.shortpixel-steps{max-width:670px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding-bottom:24px;margin:30px 0;position:relative}.shortpixel-steps:before{position:absolute;content:'';height:2px;background:#ccc;width:100%;left:0;top:18px;z-index:1}.shortpixel-steps:after{position:absolute;content:'';height:2px;background:#ec2c25;width:100%;left:0;top:18px;z-index:2;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.shortpixel-steps[data-step="0"]:after{width:39px}.shortpixel-steps[data-step="1"]:after{width:calc(((100% - 58px)/3) + 39px)}.shortpixel-steps[data-step="2"]:after{width:calc(((100% - 58px) * 2/3) + 39px)}.shortpixel-steps[data-step="3"]:after{width:100%}.shortpixel-steps .step:nth-child(1){padding-left:20px}.shortpixel-steps .step .number{position:relative;font-weight:700;font-size:20px;color:#ccc;line-height:32px;height:34px;width:34px;text-align:center;border:2px solid #ccc;border-radius:50%;background:#fff;z-index:3}.shortpixel-steps .step.active .number,.shortpixel-steps .step.passed .number{color:#1fbec9;border:2px solid #ec2c25}.shortpixel-steps .step .title{position:absolute;color:#555d66;width:80px;text-align:center;opacity:.4;text-transform:uppercase;left:-24px;font-size:14px;bottom:-30px}.shortpixel-steps .step.active .number .title{opacity:1}.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{margin-left:5px}div.spai-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background:#000;opacity:.4}div.spai-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100001;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-title{font-size:22px}div.spai-modal-body{margin-top:10px}div.spai-modal button.spai-close-upgrade-button{float:right;margin-top:0;background:0 0!important;border:none;font-size:22px;line-height:10px;cursor:pointer}.dark_blue_link{cursor:pointer;color:#fff;height:30px;line-height:30px;padding:0 20px;background:#116c7d!important;display:inline-block;-webkit-box-shadow:0 1px 1px #09343d!important;box-shadow:0 1px 1px #09343d!important;border:none!important;border-radius:3px;text-decoration:none;margin-right:10px;position:relative;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0;outline:none}.blue_link {cursor:pointer;color:#fff!important;height:30px;line-height:30px;padding:0 20px;background:#1fbec9!important;display:inline-block;-webkit-box-shadow:0 1px 1px #16858c;box-shadow:0 1px 1px #16858c;border-radius:3px;text-decoration:none;margin-right:10px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0!important;outline:none}.dark_blue_link:hover,.blue_link:hover{color:#fff!important;border:none!important;opacity:.9!important}.dark_blue_link:focus,.blue_link:focus,.dark_blue_link:active,.blue_link:active{color:#fff}.blue_link:disabled,.blue_link:disabled:hover,.dark_blue_link:disabled,.dark_blue_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#737373!important;background:#e2e2e2!important;-webkit-box-shadow:0 1px 1px #8a8a8a!important;box-shadow:0 1px 1px #8a8a8a!important}.bordered_link:disabled,.bordered_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#969696!important;background:#efefef!important;border-color:#ccc!important}.next_icon{padding-right:35px;position:relative}.next_icon:after{content:'';width:9px;height:11px;position:absolute;right:15px;top:10px;background:url(../img/next.svg)50%/cover no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.fast-forward_link{padding-right:40px;position:relative}.fast-forward_link:after{content:'';width:14px;height:13px;position:absolute;right:15px;top:9px;background:url(../img/fast-forward.svg)50%/contain no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.next_icon:hover:after,.fast-forward_link:hover:after{right:10px}@media(max-width:400px){.shortpixel-steps .step .title{text-transform:none}}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-position:50%;background-size:contain;background-repeat:no-repeat;background-image:url(../img/robo-happy.png)!important}.notice[data-plugin=short-pixel-ai]{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}.notice[data-plugin=short-pixel-ai] .body-wrap{position:relative;padding-left:75px}.notice[data-plugin=short-pixel-ai] .body-wrap .message-wrap span{font-weight:600;color:crimson}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap{padding-left:0}.notice[data-plugin=short-pixel-ai][data-icon] .body-wrap:before{content:'';position:absolute;left:0;width:64px;height:100%;background-position:50%;background-size:contain;background-repeat:no-repeat}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap:before{content:none;position:unset;left:0;width:0;height:0;background:0 0}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes.png)}.notice[data-plugin=short-pixel-ai] .buttons-wrap{margin:10px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin-right:5px}.dismissed-notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin:0 5px 5px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button:last-child{margin-right:0}div.spai-inline-help{float:right}div.spai-inline-help span{font-size:1.8em;color:#0bb5c1;cursor:pointer}div.spai-modal{background-color:#fefefe;padding:20px 16px 16px;border:1px solid #888;width:30%;max-width:610px;margin-left:-305px;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-spinner{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50%}.spai-loading{width:100%;min-height:200px;background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0}@media(max-width:610px){div.spai-modal{width:100%;margin-left:-50%;padding:20px 0 16px}}div.spai-modal .spai-close-help-button{position:absolute;top:5px;right:0;margin-top:0;background:0 0;border:none;font-size:22px;line-height:10px;cursor:pointer}div.spai-modal-title{font-size:22px}.spai-hide{display:none}.spai_settings_tab{display:none;background:#fff;border-right:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;padding:30px 20px}.spai_settings_tab.active{display:block}.shortpixel-settings-tabs{width:calc(100% - 370px);float:left}.shortpixel-settings-tabs .nav-tab-wrapper{position:relative}.shortpixel-settings-tabs .nav-tab:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.shortpixel-settings-tabs .nav-tab-active{background:#fff;border-bottom:1px solid #fff}.shortpixel-settings-tabs .form-table td label{display:inline-block}.children-wrap{display:block;visibility:visible;opacity:1;max-height:1e4px;margin:5px 0 5px 40px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.children-wrap.hidden{visibility:hidden;opacity:0;max-height:0}.children-wrap.hidden label{display:none}.children-wrap .shortpixel_radio_btns{margin-bottom:0}.children-wrap .bordered_link{margin-bottom:0}.spai_top_actions{cursor:pointer;float:right;border:1px solid #1fbec9;border-bottom:none;margin-left:.5em;padding:5px 10px;font-size:14px;line-height:1.71428571;font-weight:600;background:#1fbec9;color:#fff;text-decoration:none;white-space:nowrap;outline:none}.spai_top_actions:hover{background:#0fa9b4}.clearcss-icon{background:url(../img/clearcss-white.svg)no-repeat;background-size:auto;display:inline-block;height:20px;width:24px;margin-top:4px}#clear_css_cache{margin-bottom:0;padding:2px 5px;height:35px}.shortpixel_radio_btns input{display:none}.shortpixel_radio_btns{-webkit-box-shadow:0 1px 1px #b6b2b2;box-shadow:0 1px 1px #b6b2b2;border-radius:3px;height:32px;display:inline-block;overflow:hidden;font-size:0;vertical-align:middle;margin-right:0;margin-bottom:20px}.shortpixel_radio_btns label{background:#ccc;text-transform:uppercase;display:inline-block;color:#fff;line-height:32px;padding:0 29px;border-left:1px solid #b4b4b4;border-right:1px solid #b4b4b4;font-size:14px;font-weight:700;margin:0 -1px;-webkit-transition:all .2s ease-in;-o-transition:all .2s ease-in;transition:all .2s ease-in}.shortpixel_radio_btns input:checked+label{background:#1fbec9;-webkit-box-shadow:0 0 3px #2a6c78;box-shadow:0 0 3px #2a6c78;border-left:1px solid #1fbec9;border-right:1px solid #1fbec9;position:relative}.shortpixel_radio_btns label:hover{background:#bbb}.shortpixel_radio_btns input:checked+label:hover{background:#0fa9b4}.shortpixel-settings-tabs input[type=text],.shortpixel-settings-tabs textarea{border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input.error[type=text],.shortpixel-settings-tabs textarea.error,.shortpixel-settings-tabs input.error[type=text]:focus,.shortpixel-settings-tabs textarea.error:focus{border:1px solid crimson;-webkit-box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15);box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15)}.shortpixel-settings-tabs textarea{width:100%;max-width:100%;min-width:100%;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input[type=checkbox]:focus,.shortpixel-settings-tabs input[type=color]:focus,.shortpixel-settings-tabs input[type=date]:focus,.shortpixel-settings-tabs input[type=datetime-local]:focus,.shortpixel-settings-tabs input[type=datetime]:focus,.shortpixel-settings-tabs input[type=email]:focus,.shortpixel-settings-tabs input[type=month]:focus,.shortpixel-settings-tabs input[type=number]:focus,.shortpixel-settings-tabs input[type=password]:focus,.shortpixel-settings-tabs input[type=radio]:focus,.shortpixel-settings-tabs input[type=search]:focus,.shortpixel-settings-tabs input[type=tel]:focus,.shortpixel-settings-tabs input[type=text]:focus,.shortpixel-settings-tabs input[type=time]:focus,.shortpixel-settings-tabs input[type=url]:focus,.shortpixel-settings-tabs input[type=week]:focus,.shortpixel-settings-tabs select:focus,.shortpixel-settings-tabs textarea:focus{border-color:#1fbec9;-webkit-box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);outline:none;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs .exclusion-wrap{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap input{margin-right:10px}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content{position:relative;width:100%;padding:5px;margin-bottom:10px;min-height:100px;border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content *:not(.plus){z-index:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover{border:1px solid #aaa}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:after{visibility:visible;opacity:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{content:'';position:absolute;visibility:hidden;opacity:0;top:calc(50% - 1px);left:calc(50% - 10px);width:20px;height:2px;background:#ddd;-webkit-transition:opacity .15s ease-in;-o-transition:opacity .15s ease-in;transition:opacity .15s ease-in;z-index:0}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{top:calc(50% - 10px);left:calc(50% - 1px);width:2px;height:20px}.exclusion-wrap .exclusions-content>div[data-index]{position:relative;float:left;margin:2px;padding:5px 30px 5px 10px;background:#116c7d;color:#fff;border-radius:10px}.exclusion-wrap .exclusions-content span[data-action=delete]{cursor:pointer;position:absolute;top:calc(50% - 10px);right:5px;height:20px;width:20px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background:#1fbec9}.exclusion-wrap .exclusions-content span[data-action=delete]:before,.exclusion-wrap .exclusions-content span[data-action=delete]:after{content:'';position:absolute;display:block;width:60%;height:2px;top:calc(50% - 1px);right:20%;background:#fff;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.exclusion-wrap .exclusions-content span[data-action=delete]:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:after{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.shortpixel-settings-tabs .exclusion-wrap textarea{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{min-width:90px;vertical-align:unset}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap button{min-width:100px;margin-right:0}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 214px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:calc(100% - 111px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap .error-message{margin-bottom:10px}.support-and-preferences{display:block;margin:10px 0;font-size:16px}.support-and-preferences a{font-weight:400;margin-right:4px;font-size:18px;color:#176d84}.support-and-preferences a:last-child{margin-right:0}.spai_statusbox_wrap{border:1px solid #e5e5e5;width:350px;float:right;margin-left:20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:43px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.spai_statusbox_wrap .title_wrap{background:#fff;position:relative;border-bottom:1px solid #e1e1e1;font-size:16px;padding:20px 60px 20px 20px}.spai_statusbox_wrap .title_wrap .usage_msg{padding:10px 10px 0 0;font-size:13px}.spai_statusbox_wrap .success{color:#1fbec9;font-weight:600}.spai_statusbox_wrap .error{color:#e53935;font-weight:600}.spai_statusbox_wrap .title_wrap:before{content:'';position:absolute;right:10px;top:calc(50% - 21px);width:42px;height:42px;background-size:contain;background-position:50%;background-repeat:no-repeat}.spai_statusbox_wrap .chart-wrap{position:relative;width:100%}.spai_statusbox_wrap .chart-wrap .toggle{content:'';cursor:pointer;position:absolute;top:0;right:0;width:20px;height:20px;background:url(../img/full-screen.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded .toggle{top:20px;right:20px;background:url(../img/minimize.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded{display:block;position:fixed;background:#fff;width:80%;max-width:1e3px;padding:20px;top:calc(50% - 250px);left:calc(10% - 20px);z-index:10000;border-radius:10px;-webkit-box-shadow:0 0 10px 3px rgba(0,0,0,.2);box-shadow:0 0 10px 3px rgba(0,0,0,.2)}.spai_statusbox_wrap .chart-wrap.expanded canvas#chart{max-height:500px}.spai_statusbox_wrap .box_content canvas#chart{display:block;height:1px;max-height:350px}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared.png)}.spai_statusbox_wrap .box_content{padding:20px;background:#fff}.spai_statusbox_wrap .box_content .buttons-wrap{text-align:center}.spai_statusbox_wrap .login_btn{float:right;margin-top:-5px;margin-bottom:0}.btn_topup{color:#ed3833;float:right;margin-right:-40px;font-weight:700}.spai_statusbox_wrap img{max-width:100%}.spai_statusbox_wrap .full_width{width:calc(100% - 40px);text-align:center;margin:20px 0 0}.spai_statusbox_wrap .progress_wrap{margin-bottom:30px}.spai_statusbox_wrap .progress{height:5px;background:#1fbec9;position:relative;width:100%;clear:both}.spai_statusbox_wrap .progress_wrap .available{color:#1fbec9;float:right}.spai_statusbox_wrap .used{color:#ccc}.spai_statusbox_wrap .progress .used{height:5px;top:0;left:0;background:#ccc;position:absolute}.spai_statusbox_wrap .box_content .box_dropdown.first{margin:30px -20px -20px}.spai_statusbox_wrap .dismissed-notice-wrap{position:relative;border:1px dotted #116c7d;padding:10px;margin-bottom:10px}.spai_statusbox_wrap .dismissed-notice-wrap h4{padding-right:0;margin:5px 0;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap:hover h4{padding-right:100px}.spai_statusbox_wrap .dismissed-notice-wrap:hover:before{visibility:visible;opacity:1;top:0}.spai_statusbox_wrap .dismissed-notice-wrap:before{content:attr(data-key);position:absolute;visibility:hidden;opacity:0;top:-10px;right:0;padding:5px;max-width:100px;color:#909090;background:#eee;text-align:center;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap span{font-weight:600;color:crimson}.spai_statusbox_wrap .dismissed-notice-wrap .spai-modal span{color:#000}.shortpixel-offer-wso{width:100%;background-color:#dcfdff;display:flex;align-items:center;border:1px solid #ccc;margin-top:35px;margin-bottom:45px;position:relative}.shortpixel-offer-wso .red{color:red}.shortpixel-offer-wso span{text-align:center}.shortpixel-offer-wso .image{flex:1}.shortpixel-offer-wso .image img{width:45px;height:45px}.shortpixel-offer-wso .line{flex:3;padding:0 20px}.shortpixel-offer-wso .line h3{color:#00d0e5}.shortpixel-offer-wso .button-wrap{flex:2}.shortpixel-offer-wso .button-wrap .banner-button{background:red;padding:8px;font-weight:700;font-size:20px;margin:8px;color:#fff;text-transform:uppercase;height:auto;display:inline-block;text-decoration:none;white-space:nowrap;box-sizing:border-box;line-height:2.15384615;min-height:30px}.shortpixel-offer-wso .button-wrapper a{background-color:red;color:#fff;display:inline-block;padding:8px;text-decoration:none;font-weight:700;font-size:20px}.spai_statusbox_wrap .img-wrapper img{max-width:140px;max-height:140px}.box_dropdown{border-top:1px solid #e5e5e5;margin:20px -20px -20px}.box_dropdown .title{font-weight:600;font-size:16px;position:relative;padding:20px;cursor:pointer}.box_dropdown .title:before{content:"\f140";display:inline-block;font:20px/1 dashicons;position:absolute;right:15px}.box_dropdown.opened .title:before{content:"\f142"}.box_dropdown .dropdown_content{display:none;padding:10px 20px}.box_dropdown.opened .dropdown_content{display:block}.box_dropdown.spai_news .dropdown_content.loading{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0;min-height:200px}.shortpixel-settings-tabs input[type=submit]{padding:0 40px}.notification_popup{position:relative;background:rgba(0,0,0,2%);padding:15px 20px 20px;margin:20px 0 0;border:1px solid #1fbec9;border-radius:3px;-webkit-box-shadow:1px 1px 1px 0 rgba(31,190,201,.2);box-shadow:1px 1px 1px rgba(31,190,201,.2)}.notification_popup:before{background:#fafafa;border-left:1px solid #1fbec9;border-bottom:1px solid #1fbec9;width:14px;height:14px;display:block;position:absolute;top:-8px;left:22px;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);content:''}.notification_popup .text{margin:0 0 10px}.spai-modal .spai-modal-body{height:auto;min-height:400px;padding:0}.spai-modal.local{background-image:none}.spai-modal.local .spai-modal-body{min-height:auto}.deactivation-popup[data-type=wrapper],.deactivation-popup[data-type=wrapper] *{-webkit-box-sizing:border-box!important;box-sizing:border-box!important;-webkit-transition:all .2s ease-in-out!important;-o-transition:all .2s ease-in-out!important;transition:all .2s ease-in-out!important}.deactivation-popup[data-type=wrapper]{position:fixed;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;opacity:1;visibility:visible;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,.8);z-index:100000}.deactivation-popup[data-type=wrapper].hidden{opacity:0;visibility:hidden}.deactivation-popup[data-type=wrapper] .overlay{position:relative;padding:20px;background:#fff;overflow:auto;max-height:90%;max-width:90%;border-radius:10px;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar{width:6px}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar-thumb{border-radius:3px;background:#00c0ce}.deactivation-popup[data-type=wrapper] .body{position:relative;display:block;max-width:360px;background:#fff;border-radius:10px}.deactivation-popup[data-type=wrapper].hidden .overlay{-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}.deactivation-popup[data-type=wrapper] .overlay .close{cursor:pointer;position:absolute;top:6px;right:6px;width:30px;height:30px;background:rgba(0,192,206,.3);border-radius:10px;z-index:1}.deactivation-popup[data-type=wrapper] .overlay .close:hover{-webkit-box-shadow:inset 1px 2px 3px rgba(14,77,88,.3);box-shadow:inset 1px 2px 3px rgba(14,77,88,.3)}.deactivation-popup[data-type=wrapper] .overlay .close:before{content:'';display:block;width:100%;height:100%;background:url(../img/close.svg)50%/40% no-repeat}.deactivation-popup[data-type=wrapper] .body .title-wrap{position:relative;display:block;font-size:18px;font-weight:600;text-align:center;padding:23px 20px 23px 70px}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{content:'';position:absolute;top:0;left:0;display:block;width:64px;height:64px;background:url(../img/robo-happy.png)50%/contain no-repeat}.deactivation-popup[data-type=wrapper] .body button{float:right;margin:0}.deactivation-popup[data-type=wrapper] .body section{margin-bottom:15px}.deactivation-popup[data-type=wrapper] .body section:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .messages-wrap p{margin:5px 0}.deactivation-popup[data-type=wrapper] .body .options-wrap{padding:10px;border-radius:10px;background:#f3f3f3}.deactivation-popup[data-type=wrapper] .body .options-wrap *:not([type=radio]):not([type=checkbox]){width:100%}.deactivation-popup[data-type=wrapper] .body .options-wrap textarea{max-height:150px;min-height:50px}.deactivation-popup[data-type=wrapper] .options-wrap label{display:block;margin-bottom:5px}.deactivation-popup[data-type=wrapper] .options-wrap label:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .scroll-down{cursor:pointer;display:block;position:absolute;bottom:30px;left:calc(50% - 20px);width:40px;height:50px;background:rgba(178,236,240,.8);z-index:1;border-radius:10px;opacity:1;visibility:visible;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-transition:all .4s ease-in-out!important;-o-transition:all .4s ease-in-out!important;transition:all .4s ease-in-out!important;-webkit-animation:1.3s knock-bottom-small 3s ease-in-out;animation:1.3s knock-bottom-small 3s ease-in-out}.deactivation-popup[data-type=wrapper] .scroll-down.hidden{opacity:0;visibility:hidden;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-animation:unset;animation:unset}.deactivation-popup[data-type=wrapper] .scroll-down .mouse{position:absolute;width:26px;height:40px;top:calc(50% - 20px);left:calc(50% - 13px);border-radius:12px;border:2px solid #007cba}.deactivation-popup[data-type=wrapper] .scroll-down .wheel{position:absolute;top:5px;left:calc(50% - 5px);height:10px;width:10px;background:url(../img/down-arrow.svg)50%/contain no-repeat;border-radius:3px;-webkit-animation:wheel-scroll 2.2s infinite;animation:wheel-scroll 2.2s infinite}@-webkit-keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}@keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}div.shortpixel-settings-wrap .tgl{display:none}.tgl::-moz-selection,.tgl:after::-moz-selection,.tgl:before::-moz-selection,.tgl *::-moz-selection,.tgl *:after::-moz-selection,.tgl *:before::-moz-selection,.tgl+.tgl-btn::-moz-selection{background:0 0}.tgl::selection,.tgl:after::selection,.tgl:before::selection,.tgl *::selection,.tgl *:after::selection,.tgl *:before::selection,.tgl+.tgl-btn::selection{background:0 0}.tgl+.tgl-btn{line-height:28px}.tgl+.tgl-btn span{outline:0;display:block;width:35px;height:6px;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin:10px 10px 0 0}.tgl+.tgl-btn span:after,.tgl+.tgl-btn span:before{position:relative;display:block;content:"";width:18px;height:18px}.tgl+.tgl-btn span:after{left:-3px}.tgl+.tgl-btn span:before{display:none}.tgl:checked+.tgl-btn span:after{left:calc(100% - 15px)}.tgl+.tgl-btn span{background:#e2e2e2;border-radius:14px;padding:2px;-webkit-transition:all .4s ease;-o-transition:all .4s ease;transition:all .4s ease;float:left;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl+.tgl-btn span:after{border-radius:14px;background:#ccc;-webkit-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-o-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.31);box-shadow:0 1px 2px rgba(0,0,0,.31);top:-6px}.tgl:hover+.tgl-btn span:after{background:#bbb}.tgl+.tgl-btn span:hover:after{will-change:padding}.tgl+.tgl-btn span:active{-webkit-box-shadow:inset 0 0 0 2em #e8eae9;box-shadow:inset 0 0 0 2em #e8eae9}.tgl+.tgl-btn span:active:after{padding-right:.8em}.tgl:checked+.tgl-btn span{background:#92d4e2;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl:checked+.tgl-btn span:after{background:#1fbec9}.tgl:checked:hover+.tgl-btn span:after{background:#0fa9b4}.spai_top_actions .tgl:checked+.tgl-btn span:after{background:#72edf5}.tgl:checked+.tgl-btn span:active{-webkit-box-shadow:none;box-shadow:none}.tgl:checked+.tgl-btn span:active:after{margin-left:-.8em}.tgl:disabled+.tgl-btn span{background:#aaa}.tgl:disabled+.tgl-btn span:after{background:#909090}.tgl:checked:disabled+.tgl-btn span{background:#80bbc7}.tgl:checked:disabled+.tgl-btn span:after{background:#1a9ca5}.clearfix:after{content:''!important;display:block!important;clear:both!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu>.ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item{display:inline-block}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache .ab-item:before{background-image:url(../img/clearcss.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache .ab-item:before{background-image:url(../img/update.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache .ab-item:before{background-image:url(../img/robo-blurry.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_processing .ab-item:before{background-image:url(../img/spinner2.gif)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_success .ab-item:before{background-image:none!important;content:'\2713';display:inline-block;color:green;width:25px;font-size:20px;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_error .ab-item:before{background-image:none!important;content:'\203C';display:inline-block;color:red;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .shortpixel-ai-sniper .ab-item:before{background-image:url(../img/robo-sniper.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai-settings .ab-item:before{background-image:none!important;font-family:dashicons;content:"\f108";color:#93d7e5;width:25px;font-size:25px}@media(max-width:1400px){.spai_statusbox_wrap{}.shortpixel-settings-tabs{width:calc(100% - 370px)}}@media(min-width:1200px){.spai_statusbox_wrap .chart-wrap.expanded{left:calc(50% - 520px)}}@media(max-width:1200px){.spai_settings_tab th,.spai_settings_tab td{display:block}.spai_settings_tab th{padding:20px 0 10px}.spai_settings_tab td{padding:5px 0}}@media(max-width:850px){.spai_statusbox_wrap{width:100%;margin-left:0}.spai_statusbox_wrap .chart-wrap .toggle{display:none}.shortpixel-settings-tabs{width:100%}.spai_statusbox_wrap .title_wrap:after{content:'';display:block;position:absolute;opacity:1;visibility:visible;width:12px;height:12px;bottom:6px;left:calc(50% - 6px);background:url(../img/expand-button.svg)50%/contain no-repeat;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.spai_statusbox_wrap.expanded .title_wrap:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.spai_statusbox_wrap .box_content{display:none}.spai_statusbox_wrap .box_content.opened{position:relative;max-height:1e3px}}@media screen and (min-width:783px){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{left:0;padding:0;width:24px;height:100%}}@media screen and (max-width:782px){#wpadminbar li#wp-admin-bar-shortpixel-ai-on-boarding{display:block;position:static}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-size:70%}#export_settings,#import_settings_form{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:100%;display:inline-block;margin-right:0;margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 10px)}.deactivation-popup[data-type=wrapper] .options-wrap label{margin-bottom:10px}}@media(min-width:851px) and (max-width:1268px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.nav-tab{border-bottom:1px solid #c3c4c7}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}}@media(max-width:600px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}.socials-block .message-wrap{padding:0;margin-bottom:10px;text-align:center}.socials-block .buttons-wrap{position:unset;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto}}@media(max-width:450px){.sp-obw__content-wrap .step-message-wrap .dark_blue_link,.sp-obw__content-wrap .step-message-wrap .blue_link,.sp-obw__content-wrap .step-message-wrap .bordered_link,.sp-obw__content-wrap .step-message-wrap .action-wrap input,.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{width:100%;display:block;text-align:center;margin:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}.shortpixel-on-boarding-wrap .socials-block{margin-top:30px}}@media(max-width:400px){.shortpixel_radio_btns{width:100%;display:table}.shortpixel_radio_btns label{display:table-cell;text-align:center;padding:0 5px}}@media(-webkit-min-device-pixel-ratio:2),(-o-min-device-pixel-ratio:2/1),(min-resolution:192dpi){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item:before{background-image:url(../img/robo-happy@2x.png)!important}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes@2x.png)}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{background-image:url(../img/robo-happy@2x.png)}.shortpixel-ai-beacon:before{background-image:url(../img/notes@2x.png)}}@-webkit-keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}1 .shortpixel-settings-wrap input,.shortpixel-settings-wrap textarea,.shortpixel-settings-wrap button{outline:unset!important}.plugins tr[data-slug=shortpixel-adaptive-images] td div p span{display:block;margin:5px 0;padding-left:25px}.shortpixel-on-boarding-wrap{background:#fff}.shortpixel-on-boarding-wrap .socials-block{width:100%;max-width:1e3px;margin-top:10px}.socials-block,.socials-block *{-webkit-box-sizing:border-box;box-sizing:border-box}.socials-block{position:relative;padding:20px;border-radius:15px;font-weight:600;margin-bottom:10px;background:#dfffff}.socials-block>.message-wrap{width:100%;color:#05869f;padding-right:200px}.socials-block:before{content:'';position:absolute;display:block;width:20px;height:20px;top:-8px;left:20px;background:url(../img/socials/share.svg)50%/contain no-repeat}.socials-block>.buttons-wrap{position:absolute;display:block;top:calc(50% - 20px);right:20px}.socials-block [data-social]:before{content:'';position:absolute;width:16px;height:16px;top:calc(50% - 8px);left:7px}.socials-block [data-social]:last-child{margin-right:0}.socials-block [data-social]{position:relative;display:block;float:left;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;line-height:20px;margin-right:5px;border-radius:10px;padding:10px 10px 10px 30px;text-decoration:unset;outline:none;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.socials-block [data-social=twitter]{background:#d9e9f9;color:#2c76ec}.socials-block [data-social=twitter]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(44,118,236,.2);box-shadow:inset 1px 2px 2px rgba(44,118,236,.2)}.socials-block [data-social=twitter]:before{background:url(../img/socials/twitter.svg)50%/contain no-repeat}.socials-block [data-social=facebook]{background:#d9e6ff;color:#2152b3}.socials-block [data-social=facebook]:hover{-webkit-box-shadow:inset 1px 2px 2px rgba(33,82,179,.2);box-shadow:inset 1px 2px 2px rgba(33,82,179,.2)}.socials-block [data-social=facebook]:before{background:url(../img/socials/facebook.svg)50%/contain no-repeat}.sp-obw__title-wrap img{height:64px;width:64px;float:left;margin:10px 20px 10px 10px}.sp-obw__title-wrap{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.sp-obw__title-wrap:after{position:absolute;bottom:0;left:0;clear:both;width:100%;height:1px;background:#ccc;content:'';display:block}.sp-obw__content-wrap{padding:20px}.sp-obw__content-wrap p{font-size:14px}.sp-obw__content-wrap span.sp-obw-step{line-height:36px}.sp-obw__content-wrap span.sp-obw-alert{font-weight:600;color:crimson}.sp-obw__content-wrap .step-message-wrap label{vertical-align:top;margin-right:10px}.sp-obw__content-wrap .step-message-wrap p button{margin:0 10px 0 0}.sp-obw__content-wrap .step-message-wrap p button:last-child{margin:0}.sp-obw__content-wrap .step-message-wrap button:disabled{color:#a0a5aa!important;border-color:#ddd!important;background:#f7f7f7!important;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3)!important;box-shadow:0 1px 1px rgba(171,170,170,.3)!important}.bordered_link{cursor:pointer;color:#1fbec9;font-size:14px;line-height:18px;padding:5px 10px;display:inline-block;background:#f5f5f5!important;border:1px solid #1fbec9!important;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 1px rgba(171,170,170,.3);box-shadow:0 1px 1px rgba(171,170,170,.3);border-radius:3px;text-decoration:none;margin-bottom:15px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.bordered_link:hover{color:#0f6b7e!important;background:0 0!important}.shortpixel-steps{max-width:670px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding-bottom:24px;margin:30px 0;position:relative}.shortpixel-steps:before{position:absolute;content:'';height:2px;background:#ccc;width:100%;left:0;top:18px;z-index:1}.shortpixel-steps:after{position:absolute;content:'';height:2px;background:#ec2c25;width:100%;left:0;top:18px;z-index:2;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear}.shortpixel-steps[data-step="0"]:after{width:39px}.shortpixel-steps[data-step="1"]:after{width:calc(((100% - 58px)/3) + 39px)}.shortpixel-steps[data-step="2"]:after{width:calc(((100% - 58px) * 2/3) + 39px)}.shortpixel-steps[data-step="3"]:after{width:100%}.shortpixel-steps .step:nth-child(1){padding-left:20px}.shortpixel-steps .step .number{position:relative;font-weight:700;font-size:20px;color:#ccc;line-height:32px;height:34px;width:34px;text-align:center;border:2px solid #ccc;border-radius:50%;background:#fff;z-index:3}.shortpixel-steps .step.active .number,.shortpixel-steps .step.passed .number{color:#1fbec9;border:2px solid #ec2c25}.shortpixel-steps .step .title{position:absolute;color:#555d66;width:80px;text-align:center;opacity:.4;text-transform:uppercase;left:-24px;font-size:14px;bottom:-30px}.shortpixel-steps .step.active .number .title{opacity:1}.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{margin-left:5px}div.spai-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background:#000;opacity:.4}div.spai-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100001;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-title{font-size:22px}div.spai-modal-body{margin-top:10px}div.spai-modal button.spai-close-upgrade-button{float:right;margin-top:0;background:0 0!important;border:none;font-size:22px;line-height:10px;cursor:pointer}.dark_blue_link{cursor:pointer;color:#fff;height:30px;line-height:30px;padding:0 20px;background:#116c7d!important;display:inline-block;-webkit-box-shadow:0 1px 1px #09343d!important;box-shadow:0 1px 1px #09343d!important;border:none!important;border-radius:3px;text-decoration:none;margin-right:10px;position:relative;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0;outline:none}.blue_link,.survey-rating-btn,#survey-feedback-submit{cursor:pointer;color:#fff!important;height:30px;line-height:30px;padding:0 20px;background:#1fbec9!important;display:inline-block;-webkit-box-shadow:0 1px 1px #16858c;box-shadow:0 1px 1px #16858c;border-radius:3px;text-decoration:none;margin-right:10px;-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;margin-bottom:15px;border:0!important;outline:none}.dark_blue_link:hover,.blue_link:hover,.survey-rating-btn:hover,#survey-feedback-submit{color:#fff!important;border:none!important;opacity:.7!important}.dark_blue_link:focus,.blue_link:focus,.dark_blue_link:active,.blue_link:active{color:#fff}.blue_link:disabled,.blue_link:disabled:hover,.dark_blue_link:disabled,.dark_blue_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#737373!important;background:#e2e2e2!important;-webkit-box-shadow:0 1px 1px #8a8a8a!important;box-shadow:0 1px 1px #8a8a8a!important}.bordered_link:disabled,.bordered_link:disabled:hover{cursor:not-allowed!important;opacity:1!important;color:#969696!important;background:#efefef!important;border-color:#ccc!important}.next_icon{padding-right:35px;position:relative}.next_icon:after{content:'';width:9px;height:11px;position:absolute;right:15px;top:10px;background:url(../img/next.svg)50%/cover no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.fast-forward_link{padding-right:40px;position:relative}.fast-forward_link:after{content:'';width:14px;height:13px;position:absolute;right:15px;top:9px;background:url(../img/fast-forward.svg)50%/contain no-repeat;-webkit-transition:all .2s linear;-o-transition:all .2s linear;transition:all .2s linear}.next_icon:hover:after,.fast-forward_link:hover:after{right:10px}@media(max-width:400px){.shortpixel-steps .step .title{text-transform:none}}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-position:50%;background-size:contain;background-repeat:no-repeat;background-image:url(../img/robo-happy.png)!important}.notice[data-plugin=short-pixel-ai]{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}.notice[data-plugin=short-pixel-ai] .body-wrap{position:relative;padding-left:75px}.notice[data-plugin=short-pixel-ai] .body-wrap .message-wrap span{font-weight:600;color:crimson}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap{padding-left:0}.notice[data-plugin=short-pixel-ai][data-icon] .body-wrap:before{content:'';position:absolute;left:0;width:64px;height:100%;background-position:50%;background-size:contain;background-repeat:no-repeat}.notice[data-plugin=short-pixel-ai][data-icon=none] .body-wrap:before{content:none;position:unset;left:0;width:0;height:0;background:0 0}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes.png)}.notice[data-plugin=short-pixel-ai] .buttons-wrap{margin:10px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin-right:5px}.dismissed-notice[data-plugin=short-pixel-ai] .buttons-wrap .button{margin:0 5px 5px 0}.notice[data-plugin=short-pixel-ai] .buttons-wrap .button:last-child{margin-right:0}div.spai-inline-help{float:right}div.spai-inline-help span{font-size:1.8em;color:#0bb5c1;cursor:pointer}div.spai-modal{background-color:#fefefe;padding:20px 16px 16px;border:1px solid #888;width:30%;max-width:610px;margin-left:-305px;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.spai-modal-spinner{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50%}.spai-loading{width:100%;min-height:200px;background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0}@media(max-width:610px){div.spai-modal{width:100%;margin-left:-50%;padding:20px 0 16px}}div.spai-modal .spai-close-help-button{position:absolute;top:5px;right:0;margin-top:0;background:0 0;border:none;font-size:22px;line-height:10px;cursor:pointer}div.spai-modal-title{font-size:22px}.spai-hide{display:none}.spai_settings_tab{display:none;background:#fff;border-right:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;padding:30px 20px}.spai_settings_tab.active{display:block}.shortpixel-settings-tabs{width:calc(100% - 370px);float:left}.shortpixel-settings-tabs .nav-tab-wrapper{position:relative}.shortpixel-settings-tabs .nav-tab:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.shortpixel-settings-tabs .nav-tab-active{background:#fff;border-bottom:1px solid #fff}.shortpixel-settings-tabs .form-table td label{display:inline-block}.children-wrap{display:block;visibility:visible;opacity:1;max-height:1e4px;margin:5px 0 5px 40px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.children-wrap.hidden{visibility:hidden;opacity:0;max-height:0}.children-wrap.hidden label{display:none}.children-wrap .shortpixel_radio_btns{margin-bottom:0}.children-wrap .bordered_link{margin-bottom:0}.spai_top_actions{cursor:pointer;float:right;border:1px solid #1fbec9;border-bottom:none;margin-left:.5em;padding:5px 10px;font-size:14px;line-height:1.71428571;font-weight:600;background:#1fbec9;color:#fff;text-decoration:none;white-space:nowrap;outline:none}.spai_top_actions:hover{background:#0fa9b4}.clearcss-icon{background:url(../img/clearcss-white.svg)no-repeat;background-size:auto;display:inline-block;height:20px;width:24px;margin-top:4px}#clear_css_cache{margin-bottom:0;padding:2px 5px;height:35px}.shortpixel_radio_btns input{display:none}.shortpixel_radio_btns{-webkit-box-shadow:0 1px 1px #b6b2b2;box-shadow:0 1px 1px #b6b2b2;border-radius:3px;height:32px;display:inline-block;overflow:hidden;font-size:0;vertical-align:middle;margin-right:0;margin-bottom:20px}.shortpixel_radio_btns label{background:#ccc;text-transform:uppercase;display:inline-block;color:#fff;line-height:32px;padding:0 29px;border-left:1px solid #b4b4b4;border-right:1px solid #b4b4b4;font-size:14px;font-weight:700;margin:0 -1px;-webkit-transition:all .2s ease-in;-o-transition:all .2s ease-in;transition:all .2s ease-in}.shortpixel_radio_btns input:checked+label{background:#1fbec9;-webkit-box-shadow:0 0 3px #2a6c78;box-shadow:0 0 3px #2a6c78;border-left:1px solid #1fbec9;border-right:1px solid #1fbec9;position:relative}.shortpixel_radio_btns label:hover{background:#bbb}.shortpixel_radio_btns input:checked+label:hover{background:#0fa9b4}.shortpixel-settings-tabs input[type=text],.shortpixel-settings-tabs textarea{border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input.error[type=text],.shortpixel-settings-tabs textarea.error,.shortpixel-settings-tabs input.error[type=text]:focus,.shortpixel-settings-tabs textarea.error:focus{border:1px solid crimson;-webkit-box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15);box-shadow:0 0 2px 1px rgba(220,20,60,.15),inset 0 0 2px 1px rgba(220,20,60,.15)}.shortpixel-settings-tabs textarea{width:100%;max-width:100%;min-width:100%;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs input[type=checkbox]:focus,.shortpixel-settings-tabs input[type=color]:focus,.shortpixel-settings-tabs input[type=date]:focus,.shortpixel-settings-tabs input[type=datetime-local]:focus,.shortpixel-settings-tabs input[type=datetime]:focus,.shortpixel-settings-tabs input[type=email]:focus,.shortpixel-settings-tabs input[type=month]:focus,.shortpixel-settings-tabs input[type=number]:focus,.shortpixel-settings-tabs input[type=password]:focus,.shortpixel-settings-tabs input[type=radio]:focus,.shortpixel-settings-tabs input[type=search]:focus,.shortpixel-settings-tabs input[type=tel]:focus,.shortpixel-settings-tabs input[type=text]:focus,.shortpixel-settings-tabs input[type=time]:focus,.shortpixel-settings-tabs input[type=url]:focus,.shortpixel-settings-tabs input[type=week]:focus,.shortpixel-settings-tabs select:focus,.shortpixel-settings-tabs textarea:focus{border-color:#1fbec9;-webkit-box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);box-shadow:0 0 2px 1px rgba(31,190,201,.15),inset 0 0 2px 1px rgba(31,190,201,.15);outline:none;-webkit-transition:all .15s ease-in-out;-o-transition:all .15s ease-in-out;transition:all .15s ease-in-out}.shortpixel-settings-tabs .exclusion-wrap{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap input{margin-right:10px}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content{position:relative;width:100%;padding:5px;margin-bottom:10px;min-height:100px;border:1px solid #ddd;border-radius:2px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in;-webkit-box-sizing:border-box;box-sizing:border-box}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content *:not(.plus){z-index:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover{border:1px solid #aaa}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content:hover .plus:after{visibility:visible;opacity:1}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:before,.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{content:'';position:absolute;visibility:hidden;opacity:0;top:calc(50% - 1px);left:calc(50% - 10px);width:20px;height:2px;background:#ddd;-webkit-transition:opacity .15s ease-in;-o-transition:opacity .15s ease-in;transition:opacity .15s ease-in;z-index:0}.shortpixel-settings-tabs .exclusion-wrap .exclusions-content .plus:after{top:calc(50% - 10px);left:calc(50% - 1px);width:2px;height:20px}.exclusion-wrap .exclusions-content>div[data-index]{position:relative;float:left;margin:2px;padding:5px 30px 5px 10px;background:#116c7d;color:#fff;border-radius:10px}.exclusion-wrap .exclusions-content span[data-action=delete]{cursor:pointer;position:absolute;top:calc(50% - 10px);right:5px;height:20px;width:20px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background:#1fbec9}.exclusion-wrap .exclusions-content span[data-action=delete]:before,.exclusion-wrap .exclusions-content span[data-action=delete]:after{content:'';position:absolute;display:block;width:60%;height:2px;top:calc(50% - 1px);right:20%;background:#fff;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.exclusion-wrap .exclusions-content span[data-action=delete]:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:after{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.exclusion-wrap .exclusions-content span[data-action=delete]:hover:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.shortpixel-settings-tabs .exclusion-wrap textarea{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{min-width:90px;vertical-align:unset}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap button{min-width:100px;margin-right:0}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 214px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:calc(100% - 111px)}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap .error-message{margin-bottom:10px}.support-and-preferences{display:block;margin:10px 0;font-size:16px}.support-and-preferences a{font-weight:400;margin-right:4px;font-size:18px;color:#176d84}.support-and-preferences a:last-child{margin-right:0}.spai_statusbox_wrap{border:1px solid #e5e5e5;width:350px;float:right;margin-left:20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:43px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px}.spai_statusbox_wrap .title_wrap{background:#fff;position:relative;border-bottom:1px solid #e1e1e1;font-size:16px;padding:20px 60px 20px 20px}.spai_statusbox_wrap .title_wrap .usage_msg{padding:10px 10px 0 0;font-size:13px}.spai_statusbox_wrap .success{color:#1fbec9;font-weight:600}.spai_statusbox_wrap .error{color:#e53935;font-weight:600}.spai_statusbox_wrap .title_wrap:before{content:'';position:absolute;right:10px;top:calc(50% - 21px);width:42px;height:42px;background-size:contain;background-position:50%;background-repeat:no-repeat}.spai_statusbox_wrap .chart-wrap{position:relative;width:100%}.spai_statusbox_wrap .chart-wrap .toggle{content:'';cursor:pointer;position:absolute;top:0;right:0;width:20px;height:20px;background:url(../img/full-screen.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded .toggle{top:20px;right:20px;background:url(../img/minimize.svg)50%/80% no-repeat}.spai_statusbox_wrap .chart-wrap.expanded{display:block;position:fixed;background:#fff;width:80%;max-width:1e3px;padding:20px;top:calc(50% - 250px);left:calc(10% - 20px);z-index:10000;border-radius:10px;-webkit-box-shadow:0 0 10px 3px rgba(0,0,0,.2);box-shadow:0 0 10px 3px rgba(0,0,0,.2)}.spai_statusbox_wrap .chart-wrap.expanded canvas#chart{max-height:500px}.spai_statusbox_wrap .box_content canvas#chart{display:block;height:1px;max-height:350px}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared.png)}.spai_statusbox_wrap .box_content{padding:20px;background:#fff}.spai_statusbox_wrap .box_content .buttons-wrap{text-align:center}.spai_statusbox_wrap .login_btn{float:right;margin-top:-5px;margin-bottom:0}.btn_topup{color:#ed3833;float:right;margin-right:-40px;font-weight:700}.spai_statusbox_wrap img{max-width:100%}.spai_statusbox_wrap .full_width{width:calc(100% - 40px);text-align:center;margin:20px 0 0}.spai_statusbox_wrap .progress_wrap{margin-bottom:30px}.spai_statusbox_wrap .progress{height:5px;background:#1fbec9;position:relative;width:100%;clear:both}.spai_statusbox_wrap .progress_wrap .available{color:#1fbec9;float:right}.spai_statusbox_wrap .used{color:#ccc}.spai_statusbox_wrap .progress .used{height:5px;top:0;left:0;background:#ccc;position:absolute}.spai_statusbox_wrap .box_content .box_dropdown.first{margin:30px -20px -20px}.spai_statusbox_wrap .dismissed-notice-wrap{position:relative;border:1px dotted #116c7d;padding:10px;margin-bottom:10px}.spai_statusbox_wrap .dismissed-notice-wrap h4{padding-right:0;margin:5px 0;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap:hover h4{padding-right:100px}.spai_statusbox_wrap .dismissed-notice-wrap:hover:before{visibility:visible;opacity:1;top:0}.spai_statusbox_wrap .dismissed-notice-wrap:before{content:attr(data-key);position:absolute;visibility:hidden;opacity:0;top:-10px;right:0;padding:5px;max-width:100px;color:#909090;background:#eee;text-align:center;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-webkit-transition:all .15s ease-in;-o-transition:all .15s ease-in;transition:all .15s ease-in}.spai_statusbox_wrap .dismissed-notice-wrap span{font-weight:600;color:crimson}.spai_statusbox_wrap .dismissed-notice-wrap .spai-modal span{color:#000}.shortpixel-offer-wso{width:100%;background-color:#dcfdff;display:flex;align-items:center;border:1px solid #ccc;margin-top:35px;margin-bottom:45px;position:relative}.shortpixel-offer-wso .red{color:red}.shortpixel-offer-wso span{text-align:center}.shortpixel-offer-wso .image{flex:1}.shortpixel-offer-wso .image img{width:45px;height:45px}.shortpixel-offer-wso .line{flex:3;padding:0 20px}.shortpixel-offer-wso .line h3{color:#00d0e5}.shortpixel-offer-wso .button-wrap{flex:2}.shortpixel-offer-wso .button-wrap .banner-button{background:red;padding:8px;font-weight:700;font-size:20px;margin:8px;color:#fff;text-transform:uppercase;height:auto;display:inline-block;text-decoration:none;white-space:nowrap;box-sizing:border-box;line-height:2.15384615;min-height:30px}.shortpixel-offer-wso .button-wrapper a{background-color:red;color:#fff;display:inline-block;padding:8px;text-decoration:none;font-weight:700;font-size:20px}.spai_statusbox_wrap .img-wrapper img{max-width:140px;max-height:140px}.box_dropdown{border-top:1px solid #e5e5e5;margin:20px -20px -20px}.box_dropdown .title{font-weight:600;font-size:16px;position:relative;padding:20px;cursor:pointer}.box_dropdown .title:before{content:"\f140";display:inline-block;font:20px/1 dashicons;position:absolute;right:15px}.box_dropdown.opened .title:before{content:"\f142"}.box_dropdown .dropdown_content{display:none;padding:10px 20px}.box_dropdown.opened .dropdown_content{display:block}.box_dropdown.spai_news .dropdown_content.loading{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:50% 0;min-height:200px}.shortpixel-settings-tabs input[type=submit]{padding:0 40px}.notification_popup{position:relative;background:rgba(0,0,0,2%);padding:15px 20px 20px;margin:20px 0 0;border:1px solid #1fbec9;border-radius:3px;-webkit-box-shadow:1px 1px 1px 0 rgba(31,190,201,.2);box-shadow:1px 1px 1px rgba(31,190,201,.2)}.notification_popup:before{background:#fafafa;border-left:1px solid #1fbec9;border-bottom:1px solid #1fbec9;width:14px;height:14px;display:block;position:absolute;top:-8px;left:22px;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg);content:''}.notification_popup .text{margin:0 0 10px}.spai-modal .spai-modal-body{height:auto;min-height:400px;padding:0}.spai-modal.local{background-image:none}.spai-modal.local .spai-modal-body{min-height:auto}.deactivation-popup[data-type=wrapper],.deactivation-popup[data-type=wrapper] *{-webkit-box-sizing:border-box!important;box-sizing:border-box!important;-webkit-transition:all .2s ease-in-out!important;-o-transition:all .2s ease-in-out!important;transition:all .2s ease-in-out!important}.deactivation-popup[data-type=wrapper]{position:fixed;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;opacity:1;visibility:visible;width:100%;height:100%;top:0;left:0;background:rgba(0,0,0,.8);z-index:100000}.deactivation-popup[data-type=wrapper].hidden{opacity:0;visibility:hidden}.deactivation-popup[data-type=wrapper] .overlay{position:relative;padding:20px;background:#fff;overflow:auto;max-height:90%;max-width:90%;border-radius:10px;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar{width:6px}.deactivation-popup[data-type=wrapper] .overlay::-webkit-scrollbar-thumb{border-radius:3px;background:#00c0ce}.deactivation-popup[data-type=wrapper] .body{position:relative;display:block;max-width:360px;background:#fff;border-radius:10px}.deactivation-popup[data-type=wrapper].hidden .overlay{-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px)}.deactivation-popup[data-type=wrapper] .overlay .close{cursor:pointer;position:absolute;top:6px;right:6px;width:30px;height:30px;background:rgba(0,192,206,.3);border-radius:10px;z-index:1}.deactivation-popup[data-type=wrapper] .overlay .close:hover{-webkit-box-shadow:inset 1px 2px 3px rgba(14,77,88,.3);box-shadow:inset 1px 2px 3px rgba(14,77,88,.3)}.deactivation-popup[data-type=wrapper] .overlay .close:before{content:'';display:block;width:100%;height:100%;background:url(../img/close.svg)50%/40% no-repeat}.deactivation-popup[data-type=wrapper] .body .title-wrap{position:relative;display:block;font-size:18px;font-weight:600;text-align:center;padding:23px 20px 23px 70px}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{content:'';position:absolute;top:0;left:0;display:block;width:64px;height:64px;background:url(../img/robo-happy.png)50%/contain no-repeat}.deactivation-popup[data-type=wrapper] .body button{float:right;margin:0}.deactivation-popup[data-type=wrapper] .body section{margin-bottom:15px}.deactivation-popup[data-type=wrapper] .body section:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .messages-wrap p{margin:5px 0}.deactivation-popup[data-type=wrapper] .body .options-wrap{padding:10px;border-radius:10px;background:#f3f3f3}.deactivation-popup[data-type=wrapper] .body .options-wrap *:not([type=radio]):not([type=checkbox]){width:100%}.deactivation-popup[data-type=wrapper] .body .options-wrap textarea{max-height:150px;min-height:50px}.deactivation-popup[data-type=wrapper] .options-wrap label{display:block;margin-bottom:5px}.deactivation-popup[data-type=wrapper] .options-wrap label:last-child{margin-bottom:0}.deactivation-popup[data-type=wrapper] .scroll-down{cursor:pointer;display:block;position:absolute;bottom:30px;left:calc(50% - 20px);width:40px;height:50px;background:rgba(178,236,240,.8);z-index:1;border-radius:10px;opacity:1;visibility:visible;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-transition:all .4s ease-in-out!important;-o-transition:all .4s ease-in-out!important;transition:all .4s ease-in-out!important;-webkit-animation:1.3s knock-bottom-small 3s ease-in-out;animation:1.3s knock-bottom-small 3s ease-in-out}.deactivation-popup[data-type=wrapper] .scroll-down.hidden{opacity:0;visibility:hidden;-webkit-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-animation:unset;animation:unset}.deactivation-popup[data-type=wrapper] .scroll-down .mouse{position:absolute;width:26px;height:40px;top:calc(50% - 20px);left:calc(50% - 13px);border-radius:12px;border:2px solid #007cba}.deactivation-popup[data-type=wrapper] .scroll-down .wheel{position:absolute;top:5px;left:calc(50% - 5px);height:10px;width:10px;background:url(../img/down-arrow.svg)50%/contain no-repeat;border-radius:3px;-webkit-animation:wheel-scroll 2.2s infinite;animation:wheel-scroll 2.2s infinite}@-webkit-keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}@keyframes wheel-scroll{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}20%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}40%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}100%{opacity:0;-webkit-transform:translateY(18px);transform:translateY(18px)}}div.shortpixel-settings-wrap .tgl{display:none}.tgl::-moz-selection,.tgl:after::-moz-selection,.tgl:before::-moz-selection,.tgl *::-moz-selection,.tgl *:after::-moz-selection,.tgl *:before::-moz-selection,.tgl+.tgl-btn::-moz-selection{background:0 0}.tgl::selection,.tgl:after::selection,.tgl:before::selection,.tgl *::selection,.tgl *:after::selection,.tgl *:before::selection,.tgl+.tgl-btn::selection{background:0 0}.tgl+.tgl-btn{line-height:28px}.tgl+.tgl-btn span{outline:0;display:block;width:35px;height:6px;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin:10px 10px 0 0}.tgl+.tgl-btn span:after,.tgl+.tgl-btn span:before{position:relative;display:block;content:"";width:18px;height:18px}.tgl+.tgl-btn span:after{left:-3px}.tgl+.tgl-btn span:before{display:none}.tgl:checked+.tgl-btn span:after{left:calc(100% - 15px)}.tgl+.tgl-btn span{background:#e2e2e2;border-radius:14px;padding:2px;-webkit-transition:all .4s ease;-o-transition:all .4s ease;transition:all .4s ease;float:left;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl+.tgl-btn span:after{border-radius:14px;background:#ccc;-webkit-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-o-transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;transition:left .3s cubic-bezier(.175,.885,.32,1.275),padding .3s ease,margin .3s ease;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.31);box-shadow:0 1px 2px rgba(0,0,0,.31);top:-6px}.tgl:hover+.tgl-btn span:after{background:#bbb}.tgl+.tgl-btn span:hover:after{will-change:padding}.tgl+.tgl-btn span:active{-webkit-box-shadow:inset 0 0 0 2em #e8eae9;box-shadow:inset 0 0 0 2em #e8eae9}.tgl+.tgl-btn span:active:after{padding-right:.8em}.tgl:checked+.tgl-btn span{background:#92d4e2;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.25);box-shadow:inset 0 1px 1px rgba(0,0,0,.25)}.tgl:checked+.tgl-btn span:after{background:#1fbec9}.tgl:checked:hover+.tgl-btn span:after{background:#0fa9b4}.spai_top_actions .tgl:checked+.tgl-btn span:after{background:#72edf5}.tgl:checked+.tgl-btn span:active{-webkit-box-shadow:none;box-shadow:none}.tgl:checked+.tgl-btn span:active:after{margin-left:-.8em}.tgl:disabled+.tgl-btn span{background:#aaa}.tgl:disabled+.tgl-btn span:after{background:#909090}.tgl:checked:disabled+.tgl-btn span{background:#80bbc7}.tgl:checked:disabled+.tgl-btn span:after{background:#1a9ca5}.clearfix:after{content:''!important;display:block!important;clear:both!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu>.ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item{display:inline-block}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .ab-item:before{content:' ';width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-position:0;background-image:url(../img/robo.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache .ab-item:before{background-image:url(../img/clearcss.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache .ab-item:before{background-image:url(../img/update.svg)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache .ab-item:before{background-image:url(../img/robo-blurry.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_processing .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_processing .ab-item:before{background-image:url(../img/spinner2.gif)!important;height:20px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_success .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_success .ab-item:before{background-image:none!important;content:'\2713';display:inline-block;color:green;width:25px;font-size:20px;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_css_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_purge_cdn_cache.shortpixel_ai_error .ab-item:before,#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai_clear_lqip_cache.shortpixel_ai_error .ab-item:before{background-image:none!important;content:'\203C';display:inline-block;color:red;padding:0 -6px 0 6px}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .shortpixel-ai-sniper .ab-item:before{background-image:url(../img/robo-sniper.png)!important}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel_ai_topmenu .ab-submenu .spai-settings .ab-item:before{background-image:none!important;font-family:dashicons;content:"\f108";color:#93d7e5;width:25px;font-size:25px}@media(max-width:1400px){.spai_statusbox_wrap{}.shortpixel-settings-tabs{width:calc(100% - 370px)}}@media(min-width:1200px){.spai_statusbox_wrap .chart-wrap.expanded{left:calc(50% - 520px)}}@media(max-width:1200px){.spai_settings_tab th,.spai_settings_tab td{display:block}.spai_settings_tab th{padding:20px 0 10px}.spai_settings_tab td{padding:5px 0}}@media(max-width:850px){.spai_statusbox_wrap{width:100%;margin-left:0}.spai_statusbox_wrap .chart-wrap .toggle{display:none}.shortpixel-settings-tabs{width:100%}.spai_statusbox_wrap .title_wrap:after{content:'';display:block;position:absolute;opacity:1;visibility:visible;width:12px;height:12px;bottom:6px;left:calc(50% - 6px);background:url(../img/expand-button.svg)50%/contain no-repeat;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0);-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.spai_statusbox_wrap.expanded .title_wrap:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.spai_statusbox_wrap .box_content{display:none}.spai_statusbox_wrap .box_content.opened{position:relative;max-height:1e3px}}@media screen and (min-width:783px){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{left:0;padding:0;width:24px;height:100%}}@media screen and (max-width:782px){#wpadminbar li#wp-admin-bar-shortpixel-ai-on-boarding{display:block;position:static}#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item .ab-icon{background-size:70%}#export_settings,#import_settings_form{display:none}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap select{margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap .buttons-wrap input{width:100%;display:inline-block;margin-right:0;margin-bottom:10px}.shortpixel-settings-tabs .exclusion-wrap[data-type=urls] .buttons-wrap input{width:calc(100% - 10px)}.deactivation-popup[data-type=wrapper] .options-wrap label{margin-bottom:10px}}@media(min-width:851px) and (max-width:1268px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.nav-tab{border-bottom:1px solid #c3c4c7}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}}@media(max-width:600px){.spai_top_actions{margin:10px 10px 0 0}.spai_settings_tab{border-top:1px solid #e5e5e5}.shortpixel-settings-tabs .nav-tab-active{border-bottom:1px solid #ccc}.shortpixel-settings-tabs .nav-tab-wrapper{padding-bottom:10px!important}.socials-block .message-wrap{padding:0;margin-bottom:10px;text-align:center}.socials-block .buttons-wrap{position:unset;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;margin:0 auto}}@media(max-width:450px){.sp-obw__content-wrap .step-message-wrap .dark_blue_link,.sp-obw__content-wrap .step-message-wrap .blue_link,.sp-obw__content-wrap .step-message-wrap .bordered_link,.sp-obw__content-wrap .step-message-wrap .action-wrap input,.sp-obw__content-wrap .step-message-wrap .action-wrap [data-action]{width:100%;display:block;text-align:center;margin:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}.shortpixel-on-boarding-wrap .socials-block{margin-top:30px}}@media(max-width:400px){.shortpixel_radio_btns{width:100%;display:table}.shortpixel_radio_btns label{display:table-cell;text-align:center;padding:0 5px}}@media(-webkit-min-device-pixel-ratio:2),(-o-min-device-pixel-ratio:2/1),(min-resolution:192dpi){#wpadminbar #wp-toolbar li#wp-admin-bar-shortpixel-ai-on-boarding .ab-item:before{background-image:url(../img/robo-happy@2x.png)!important}.spai_statusbox_wrap .title_wrap[data-status=enough]:before{background-image:url(../img/robo-rtl-cool@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=few]:before{background-image:url(../img/robo-rtl-notes@2x.png)}.spai_statusbox_wrap .title_wrap[data-status=insufficiently]:before{background-image:url(../img/robo-rtl-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=scared] .body-wrap:before{background-image:url(../img/robo-scared@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=happy] .body-wrap:before{background-image:url(../img/robo-happy@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=wink] .body-wrap:before{background-image:url(../img/robo-wink@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=cool] .body-wrap:before{background-image:url(../img/robo-cool@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=magnifier] .body-wrap:before{background-image:url(../img/robo-magnifier@2x.png)}.notice[data-plugin=short-pixel-ai][data-icon=notes] .body-wrap:before{background-image:url(../img/robo-notes@2x.png)}.deactivation-popup[data-type=wrapper] .body .title-wrap:before{background-image:url(../img/robo-happy@2x.png)}.shortpixel-ai-beacon:before{background-image:url(../img/notes@2x.png)}}@-webkit-keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-right-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateX(5px);transform:translateX(5px)}50%{-webkit-transform:translateX(3px);transform:translateX(3px)}65%{-webkit-transform:translateX(5px);transform:translateX(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes knock-bottom-small{0%{-webkit-transform:translateX(0);transform:translateX(0)}35%{-webkit-transform:translateY(5px);transform:translateY(5px)}50%{-webkit-transform:translateY(3px);transform:translateY(3px)}65%{-webkit-transform:translateY(5px);transform:translateY(5px)}100%{-webkit-transform:translateX(0);transform:translateX(0)}} -
shortpixel-adaptive-images/trunk/assets/js/notice.js
r2900611 r3340495 94 94 } 95 95 } ); 96 // feedback survey handler 97 $document.on( 'click', '.notice[data-causer="recommend_survey"] .survey-rating-btn', function(e){ 98 e.preventDefault(); 99 var $btn = $( this ), 100 rating = $btn.data('rating'), 101 $notice = $btn.closest('.notice[data-causer="recommend_survey"]'); 102 103 $notice.find('.survey-rating-btn').removeClass('selected'); 104 $btn.addClass('selected'); 105 // send (only) rating first 106 $.post( ajaxurl, { 107 action: 'shortpixel_ai_send_rating', 108 data: { rating: rating } 109 }); 110 // for 9–10: show inline thank-you + review prompt for WP pagre 111 if ( rating >= 9 ) { 112 $notice.find('h3, .message-wrap > p').slideUp(); 113 114 var promptHtml = 115 '<p>Thank you for your high rating! ' + 116 'If you have a moment, the ShortPixel team would be very happy ' + 117 'if you could leave a short review for our plugin.</p>'; 118 119 var reviewLinkHtml = 120 '<p>' + 121 '<button id="survey-feedback-submit" class="button button-primary" '+ 122 'onclick="window.open(\'https://wordpress.org/support/plugin/shortpixel-adaptive-images/reviews/?filter=5\', \'_blank\')">' + 123 'Leave a review' + 124 '</button>' + 125 '</p>'; 126 127 $notice 128 .find('#survey-feedback-area') 129 .html( promptHtml + reviewLinkHtml ) 130 .slideDown(); 131 132 return; 133 } 134 // 1–8: close title + buttons & open feedback area 135 $notice.find('h3').slideUp(); 136 $notice.find('.survey-rating-btn').closest('p').slideUp(); 137 var prompt = rating <= 4 138 ? 'Thank you for your feedback! If you have encountered any issues with our plugin, we are more than eager to help solving them! Please give us more details:' 139 : 'Thank you for your feedback! Please let us know what we can improve:'; 140 141 $notice.find('#survey-feedback-prompt').text( prompt ); 142 $notice.find('#survey-feedback-area').slideDown(); 143 }); 144 145 // now, when click on submit button send 2nd ajax with feedback 146 $document.on( 'click', '.notice[data-causer="recommend_survey"] #survey-feedback-submit', function(e){ 147 e.preventDefault(); 148 var $notice = $( this ).closest( '.notice[data-causer="recommend_survey"]'), 149 rating = $notice.find('.survey-rating-btn.selected').data('rating'), 150 feedbackText = $notice.find('#survey-feedback').val() || ''; 151 152 $.post( ajaxurl, { 153 action: 'shortpixel_ai_send_feedback', 154 data: { 155 rating: rating, 156 feedback: feedbackText 157 } 158 }) 159 .done(function( resp ){ 160 var $msgWrap = $notice.find('.message-wrap'); 161 if ( resp.success ) { 162 $msgWrap.html('<p>Thank you for your feedback!</p>'); 163 $notice.find('#survey-feedback-area, .buttons-wrap').slideUp(); 164 } 165 else { 166 var error = resp.data || 'Something went wrong sending feedback!'; 167 $msgWrap.html('<p>' + error + '</p>'); 168 } 169 }); 170 }); 171 96 172 } ); 97 173 } )( jQuery, document, window ); -
shortpixel-adaptive-images/trunk/assets/js/notice.min.js
r2900611 r3340495 1 (function( t,i,e){t((function(){var a=t(this);var n=false;a.on("click",'.notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .notice[data-plugin="short-pixel-ai"] button.notice-dismiss, .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap button.notice-dismiss',(function(){var o=t(this),d=o.parents('.notice[data-plugin="short-pixel-ai"], .dismissed-notice[data-plugin="short-pixel-ai"]');o.prop("disabled",true);var r=d.attr("data-causer"),s=o.attr("data-type"),c=o.attr("data-action"),u=o.attr("data-additional");r=typeof r==="string"&&r!==""?r:undefined;c=typeof c==="string"&&c!==""?c:r!==undefined&&o.hasClass("notice-dismiss")?"dismiss":undefined;try{u=JSON.parse(u)}catch(t){u=undefined}if(r!==undefined){if(s==="js"){if(typeof jQuery[c]==="function"){jQuery[c](u)}}else if(!n){t.ajax({method:"post",url:typeof ajaxurl==="string"&&ajaxurl!==""?ajaxurl:"/wp-admin/admin-ajax.php",data:{action:"shortpixel_ai_handle_notice_action",causer:d.attr("data-causer"),data:{action:c,additional:u}},beforeSend:function(){n=true},success:function(n){d.slideUp("fast",(function(){if(typeof n.notice==="string"&&n.notice!==""){var i=t(n.notice).hide();d.after(i);a.trigger("wp-updates-notice-added");i.slideDown("fast",(function(){i.removeAttr("style")}))}d.remove()}));if(typeof n.redirect!=="undefined"&&!!n.redirect.allowed){if(typeof n.redirect.url==="string"&&n.redirect.url!==""){if(!!n.redirect.blank){e.open(n.redirect.url)}else{i.location.href=n.redirect.url}}}if(typeof n.reload!=="undefined"&&!!n.reload.allowed){i.location.reload()}},complete:function(){n=false}})}}}))}))})(jQuery,document,window);1 (function(e,t,a){e((function(){var i=e(this);var n=false;i.on("click",'.notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .notice[data-plugin="short-pixel-ai"] button.notice-dismiss, .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap [data-action], .dismissed-notice[data-plugin="short-pixel-ai"] .buttons-wrap button.notice-dismiss',(function(){var r=e(this),o=r.parents('.notice[data-plugin="short-pixel-ai"], .dismissed-notice[data-plugin="short-pixel-ai"]');r.prop("disabled",true);var s=o.attr("data-causer"),d=r.attr("data-type"),u=r.attr("data-action"),c=r.attr("data-additional");s=typeof s==="string"&&s!==""?s:undefined;u=typeof u==="string"&&u!==""?u:s!==undefined&&r.hasClass("notice-dismiss")?"dismiss":undefined;try{c=JSON.parse(c)}catch(e){c=undefined}if(s!==undefined){if(d==="js"){if(typeof jQuery[u]==="function"){jQuery[u](c)}}else if(!n){e.ajax({method:"post",url:typeof ajaxurl==="string"&&ajaxurl!==""?ajaxurl:"/wp-admin/admin-ajax.php",data:{action:"shortpixel_ai_handle_notice_action",causer:o.attr("data-causer"),data:{action:u,additional:c}},beforeSend:function(){n=true},success:function(n){o.slideUp("fast",(function(){if(typeof n.notice==="string"&&n.notice!==""){var t=e(n.notice).hide();o.after(t);i.trigger("wp-updates-notice-added");t.slideDown("fast",(function(){t.removeAttr("style")}))}o.remove()}));if(typeof n.redirect!=="undefined"&&!!n.redirect.allowed){if(typeof n.redirect.url==="string"&&n.redirect.url!==""){if(!!n.redirect.blank){a.open(n.redirect.url)}else{t.location.href=n.redirect.url}}}if(typeof n.reload!=="undefined"&&!!n.reload.allowed){t.location.reload()}},complete:function(){n=false}})}}}));i.on("click",'.notice[data-causer="recommend_survey"] .survey-rating-btn',(function(t){t.preventDefault();var a=e(this),i=a.data("rating"),n=a.closest('.notice[data-causer="recommend_survey"]');n.find(".survey-rating-btn").removeClass("selected");a.addClass("selected");e.post(ajaxurl,{action:"shortpixel_ai_send_rating",data:{rating:i}});if(i>=9){n.find("h3, .message-wrap > p").slideUp();var r="<p>Thank you for your high rating! "+"If you have a moment, the ShortPixel team would be very happy "+"if you could leave a short review for our plugin.</p>";var o="<p>"+'<button id="survey-feedback-submit" class="button button-primary" '+"onclick=\"window.open('https://wordpress.org/support/plugin/shortpixel-adaptive-images/reviews/?filter=5', '_blank')\">"+"Leave a review"+"</button>"+"</p>";n.find("#survey-feedback-area").html(r+o).slideDown();return}n.find("h3").slideUp();n.find(".survey-rating-btn").closest("p").slideUp();var s=i<=4?"Thank you for your feedback! If you have encountered any issues with our plugin, we are more than eager to help solving them! Please give us more details:":"Thank you for your feedback! Please let us know what we can improve:";n.find("#survey-feedback-prompt").text(s);n.find("#survey-feedback-area").slideDown()}));i.on("click",'.notice[data-causer="recommend_survey"] #survey-feedback-submit',(function(t){t.preventDefault();var a=e(this).closest('.notice[data-causer="recommend_survey"]'),i=a.find(".survey-rating-btn.selected").data("rating"),n=a.find("#survey-feedback").val()||"";e.post(ajaxurl,{action:"shortpixel_ai_send_feedback",data:{rating:i,feedback:n}}).done((function(e){var t=a.find(".message-wrap");if(e.success){t.html("<p>Thank you for your feedback!</p>");a.find("#survey-feedback-area, .buttons-wrap").slideUp()}else{var i=e.data||"Something went wrong sending feedback!";t.html("<p>"+i+"</p>")}}))}))}))})(jQuery,document,window); -
shortpixel-adaptive-images/trunk/changelog.txt
r2614181 r3340495 1 = 2.3.3 = 2 Release date: June 30th, 2021 3 * Fix: issue with validating API key 4 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 5 6 = 2.3.2 = 7 Release date: June 29th, 2021 8 * Temporarily deactivate AVIF pending codec bug fix (https://github.com/xiph/rav1e/issues/2757); 9 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 10 11 = 2.3.1 = 12 Release date: June 28th, 2021 13 * New: Version the javascript in the file name in order to get around more stubborn caches; 14 * Fix: do not parse AJAX responses to uploads; 15 * Fix: nested element that has a different background - was taking the background of the parent element; 16 * Fix: notice in logs sometimes when domain info from server; 17 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 18 19 = 2.3.0 = 20 Release date: June 17th, 2021 21 * New: images (including the ones from CSS files) are now served automatically in the new AVIF format to supporting browsers; 22 * New: moved the JS detection mechanism for WebP/AVIF support directly to the CDN level, so no JS is required anymore for this; 23 * Language: 0 new strings added, 6 updated, 0 fuzzed, and 0 obsoleted. 24 25 = 2.2.4 = 26 Release date: June 14th, 2021 27 * Compat: added a constant - `SPAI_ELEMENTOR_WORKAROUND` - to deactivate the parsing of Elementor modules that are resulting in critical errors; 28 * Compat: workaround for WP Rocket that calls in certain circumstances the filter `rocket_css_content` with only one parameter; 29 * Fix: some warnings when lqip queue is not array were showing up in some cases; 30 * Fix: wrong array key when the no background calculation can't determine crop size and returns just width and height; 31 * Fix: iPhone issues with parsing stylesheets while also improving page responsiveness while parsing them (async); 32 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 33 34 = 2.2.3 = 35 Release date: May 18th, 2021 36 * New: also parse inside `<script type="text/template">` blocks; 37 * Fix: the background crop resize wasn't working in several cases, which is now fixed; 38 * Fix: update the notification text about the next generation images served by SPIO; 39 * Fix: cases when a mutation has backgrounds from an existing CSS block are now properly handled; 40 * Fix: the special crop feature now handles correctly the situations when the width parameter isn't the first one; 41 * Fix: the inline background selector will handle situations with no space before the CSS class definition; 42 * Fix: remove the default values for JS parameters in order to support IE11; 43 * Fix: the images from `li` elements added with `data-thumb` are now replaced; 44 * Fix: the URL exclusions are checked when replacing inside JS blocks too; 45 * Language: 0 new strings added, 2 updated, 0 fuzzed, and 0 obsoleted. 46 47 = 2.2.2 = 48 Release date: April 29th, 2021 49 * Fix: the minified version of the plugin CSS files was bigger than the not minified one; 50 * Fix: find local file when URL contains a path element before wp-content, that is not present on disk; 51 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 52 53 = 2.2.1 = 54 Release date: April 26th, 2021 55 * Compat: added integration with Real3D Flipbook; 56 * Fix: there was a "Class not found" error in some cases when purging LiteSpeed cache from our plugin; 57 * Fix: in some cases, the size of background images wasn't properly set; 58 * Fix: protection added for very large number of product variations; the plugin will now work properly in these cases; 59 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted. 60 61 = 2.2.0 = 62 Release date: April 20th, 2021 63 * New: added filter `shortpixel/ai/customRules` for custom replacement rules; 64 * New: added proper lazy loading for background images; 65 * New: take into account the `background-*` CSS styles: size, position, etc.; 66 * New: lazy load the images in the CSS blocks; 67 * New: handle correctly multiple URLs in the same `background-image:` declaration; 68 * New: when running out of credits you can now have an option to top-up directly from the plugin settings; 69 * Compat: added an integration with the Uncode theme and its iLightBox component; 70 * Compat: added integration with WPC Variations Table; 71 * Compat: added integration with Soliloquy Slider Plugin; 72 * Compat: also integrate properly with Divi child themes; 73 * Compat: improved the integration with Elementor, all images should now be properly replaced; 74 * Fix: WooCommerce product variations were broken if srcset was present, but false; 75 * Fix: in certain cases, background images with important CSS priority weren't properly handled; 76 * Fix: also remove the sizes attribute if we remove the srcset; 77 * Fix: replacement error when html attribute contains "<style>.." data; 78 * Fix: various small fixes to settings, fonts, debug messages, ShortPixel account login and lazy loading; 79 * Language: 7 new strings added, 2 updated, 0 fuzzed, and 3 obsoleted. 80 1 81 = 2.1.6 = 2 82 Release date: March 19th, 2021 -
shortpixel-adaptive-images/trunk/includes/actions/notice.actions.class.php
r3209129 r3340495 50 50 die; 51 51 } 52 53 private static function handleRecommendSurvey( $data ) { 54 if ( ( $data['action'] ?? '' ) === 'dismiss' ) { 55 return [ 56 'success' => Notice::dismiss( 'recommend_survey' ), 57 ]; 58 } 59 return null; 60 } 52 61 53 62 private static function handleRemoteInfoNotice ($data){ -
shortpixel-adaptive-images/trunk/includes/actions/page.actions.class.php
r3337681 r3340495 60 60 } 61 61 62 if (isset($options->behaviour->storage_url)) { 63 $options->behaviour->storage_url = sanitize_text_field(trim($options->behaviour->storage_url)); 64 } 65 66 if (isset($options->behaviour->host_removal)) { 67 $options->behaviour->host_removal = sanitize_text_field(trim($options->behaviour->host_removal)); 68 } 69 70 62 71 63 72 //translate simple meta options 64 73 $options = ShortPixelAI::translateSimpleOptions( $options ); 65 66 74 $current_options = Options::_()->settings; 75 76 // if user just disabled the LQIP option, delete the LQIP state from DB 77 if (($options->behaviour->lqip ?? null) === false && ($current_options->behaviour->lqip ?? null) === true) { 78 delete_option('shortpixel_ai_lqip_state'); 79 } 67 80 68 81 $success = true; … … 176 189 $cdnMessage = ''; 177 190 $cdnErrorMessage = ''; 178 $messageData = $api_response['message'][' Message'] ?? [];191 $messageData = $api_response['message']['Details'] ?? []; 179 192 //getting the array of messages 180 193 if (!empty($messageData['0']['Message']) || !empty($messageData['CDN']['Message']) || !empty($messageData['CDN']['Error']) ) { … … 252 265 else if ( $action === 'clear lqip cache' ) { 253 266 $success = LQIP::clearCache(); 254 //var_dump('HERE:', $success, $response);exit('this is only for admin button');255 267 $response[ 'success' ] = $success; 256 268 $response[ 'notice' ] = Notice::get( null, [ -
shortpixel-adaptive-images/trunk/includes/controllers/feedback.class.php
r2627986 r3340495 15 15 */ 16 16 protected $controller; 17 18 private $logger; 17 19 18 20 /** … … 301 303 self::$instance = $this; 302 304 } 303 305 $this->logger = \ShortPixelAILogger::instance(); 304 306 $this->controller = $controller; 305 307 306 308 add_action( 'admin_footer-plugins.php', [ $this, 'generatePopUp' ] ); 307 309 add_action( 'wp_ajax_shortpixel_ai_handle_feedback_action', [ 'ShortPixel\AI\Feedback\Actions', 'handle' ] ); 308 } 309 } 310 311 add_action( 'wp_ajax_shortpixel_ai_send_rating', [ $this, 'handleSurveyAjax' ] ); 312 add_action( 'wp_ajax_shortpixel_ai_send_feedback', [ $this, 'handleSurveyAjax' ] ); 313 } 314 315 public function handleSurveyAjax() { 316 317 318 $rating = isset($_POST['data']['rating']) ? intval($_POST['data']['rating']) : 0; 319 $feedback = isset($_POST['data']['feedback']) ? sanitize_text_field($_POST['data']['feedback']) : ''; 320 321 if ( ! $rating || $rating < 1 || $rating > 10 ) { 322 wp_send_json_error(__('Invalid rating', 'shortpixel-adaptive-images')); 323 } 324 $response = self::sendSurvey( $rating, $feedback ); 325 326 if ( is_wp_error($response) ) { 327 wp_send_json_error(__('Feedback could not be sent.', 'shortpixel-adaptive-images')); 328 } 329 330 Notice::dismiss( 'recommend_survey' ); 331 wp_send_json_success(); 332 333 } 334 335 336 public function sendSurvey( $rating, $feedback, $anonymous = false ) { 337 338 if ( ! is_int( $rating ) || $rating < 1 || $rating > 10 ) { 339 return false; 340 } 341 $wordpress = self::collectWordpressData( ShortPixelAI::is_beta() ); 342 $wordpress['deactivated_plugin']['uninstall_reason'] = 'rating'; 343 $wordpress['deactivated_plugin']['uninstall_details'] = 'Rating: ' . $rating 344 . ( $feedback ? ' – Feedback: ' . $feedback : '' ); 345 346 $body = [ 347 'user' => self::collectUserData( $anonymous ), 348 'wordpress' => $wordpress, 349 ]; 350 $spai_key = Options::_()->settings_general_apiKey; 351 if ( $spai_key && ! $anonymous ) { 352 $body['key'] = $spai_key; 353 } 354 355 return Request::post( 'https://api.shortpixel.com/v2/feedback.php', true, [ 'body' => $body ] ); 356 } 357 } -
shortpixel-adaptive-images/trunk/includes/controllers/lqip.class.php
r3209129 r3340495 120 120 private $ctrl; 121 121 122 private function normalizeLqipItem(array $item): array { 123 if (!isset($item['source']) || !isset($item['url'])) { 124 return $item; 125 } 126 127 if ($item['source'] === $item['url']) { 128 $item['lqipUrl'] = $item['url']; 129 unset($item['source'], $item['url']); 130 } else {// log to catch them and see if it's really useful to keep both sourcce & url 131 $this->log('LQIP normalize: source ≠ url', [ 132 'source' => $item['source'], 133 'url' => $item['url'], 134 'referer' => $item['referer'] ?? null 135 ]); 136 137 $item['source'] = null; 138 $item['lqipUrl'] = $item['url']; 139 unset($item['url']); 140 } 141 return $item; 142 } 143 144 145 private function provideTimestamp(array $collection): array { 146 $now = time(); 147 foreach ($collection as &$item) { 148 if (!isset($item['timestamp'])) { 149 $item['timestamp'] = $now; 150 } 151 } 152 unset($item); 153 return $collection; 154 } 155 156 private function removeOldItemsFromCollection(array $collection, int $maxAgeSeconds = 86400): array { 157 $threshold = time() - $maxAgeSeconds; 158 return array_filter($collection, function($item) use ($threshold) { 159 return !isset($item['timestamp']) || $item['timestamp'] >= $threshold; 160 }); 161 } 162 163 private function getLqipState() { 164 $state = get_option('shortpixel_ai_lqip_state', null); 165 166 if ($state === null) { 167 // get previous data from old options 168 $state = [ 169 'collection' => Options::_()->get('collection', self::OPTIONS_CATEGORY, []), 170 'processed' => Options::_()->get('processed', self::OPTIONS_CATEGORY, []), 171 ]; 172 $state['collection'] = $this->provideTimestamp($state['collection']); 173 174 update_option('shortpixel_ai_lqip_state', $state); 175 Options::_()->delete('collection', self::OPTIONS_CATEGORY); 176 Options::_()->delete('processed', self::OPTIONS_CATEGORY); 177 } 178 179 if (!is_array($state)) { 180 $state = [ 'collection' => [], 'processed' => [] ]; 181 } 182 183 if (!isset($state['collection']) || !is_array($state['collection'])) $state['collection'] = []; 184 if (!isset($state['processed']) || !is_array($state['processed'])) $state['processed'] = []; 185 186 return $state; 187 } 188 189 private function saveLqipState($state) { 190 update_option('shortpixel_ai_lqip_state', $state); 191 } 192 193 194 122 195 /** 123 196 * Single ton implementation … … 179 252 $valid = !$this->exists( $name ) || $this->expired( $name ); 180 253 if(!$valid) { 181 $this->log("Dropping URL: " . $item. ' name: ' . $name);254 $this->log("Dropping URL: " . json_encode($item) . ' name: ' . $name); 182 255 } 183 256 … … 251 324 */ 252 325 public function eventHandler() { 253 $collection = Options::_()->get( 'collection', self::OPTIONS_CATEGORY, [] ); 254 if(!is_array($collection)) $collection = []; 255 $this->log('LQIP EVT HANLER: COLLECTION: ', $collection); 256 257 if ( empty( $collection ) ) { 258 return; 259 } 260 261 $processed = Options::_()->get( 'processed', self::OPTIONS_CATEGORY, [] ); 262 $this->log('LQIP EVT HANLER: PROCESSED REQUESTS: ', $processed); 326 $state = $this->getLqipState(); 327 $collection = $state['collection']; 328 $processed = $state['processed']; 329 330 $this->log('LQIP EVT HANDLER: PROCESSED REQUESTS: ', $processed); 263 331 264 332 265 333 $collection = $this->filterWithProcessed( $collection, $processed ); 266 267 334 $bundle = array_splice( $collection, 0, self::BUNDLE_CAPACITY ); 268 335 269 $this->log('LQIP EVT HANLER: SETTING COLLECTION: ', $collection); 270 Options::_()->set( $collection, 'collection', self::OPTIONS_CATEGORY ); 271 272 $this->log('LQIP EVT HANLER: GENERATE BUNDLE: ', $bundle); 336 $this->log('LQIP EVT HANDLER: GENERATE BUNDLE: ', $bundle); 337 $state['collection'] = $collection; 338 $this->saveLqipState($state); 273 339 $this->generate( $bundle ); 274 340 … … 291 357 private function schedule( $collection ) { 292 358 if ( !empty( $collection ) && is_array( $collection ) ) { 293 $scheduled_collection = Options::_()->get( 'collection', self::OPTIONS_CATEGORY, [] ); 294 if(!is_array($scheduled_collection)) $scheduled_collection = []; 295 359 $state = $this->getLqipState(); 360 $scheduled_collection = $state['collection']; 296 361 $collection = array_merge( $scheduled_collection, $collection ); 362 $collection = $this->provideTimestamp($collection); 363 $collection = $this->removeOldItemsFromCollection($collection); 297 364 $collection = $this->replaceWithParent( $collection ); 298 365 $collection = $this->filterCollection( $collection ); 299 366 367 $collection = array_map(function($item) { 368 return $this->normalizeLqipItem($item); 369 }, $collection); 370 300 371 $collection = array_filter( $collection, function( $item ) { 301 $name = $this->getFileName( $item[ 'source' ]);372 $name = $this->getFileName( $item[ 'source' ] ?? $item['lqipUrl'] ?? '' ); 302 373 303 374 return !$this->exists( $name ) || $this->expired( $name ); 304 375 } ); 305 376 306 $this->log('SETTING LQIP COLLECTION: ', $collection); 307 308 $ option_set = Options::_()->set( $collection, 'collection', self::OPTIONS_CATEGORY);377 378 $state['collection'] = $collection; 379 $this->saveLqipState($state); 309 380 310 381 if ( empty( $collection ) ) { … … 316 387 $this->reschedule( 'quick' ); 317 388 318 return ['processed' => !!$option_set, 'message' => (!!$option_set ? '' : 'Could not set lqip option.')];389 return ['processed' => true]; 319 390 } 320 391 } … … 337 408 if ( !empty( $collection ) && is_array( $collection ) ) { 338 409 339 $processed = Options::_()->get( 'processed', self::OPTIONS_CATEGORY, [] ); 410 $state = $this->getLqipState(); 411 $processed = $state['processed']; 340 412 $this->log( 'LQIP REQUESTS START. ALREADY PROCESSED: ', $processed ); 341 413 … … 411 483 $return = $this->countAttempts( $return, $processed ); 412 484 $processed = $this->filterCollection( array_merge( $processed, $return ) ); 413 Options::_()->set( $processed, 'processed', self::OPTIONS_CATEGORY ); 485 $state['processed'] = $processed; 486 $this->saveLqipState($state); 414 487 415 488 return $return; … … 435 508 */ 436 509 private function isPlaceholder( $content ) { 437 return empty( $content ) ? false : $this->isSvg( $content ) && strpos( $content, 'feGaussianBlur' ) !== false; 510 return empty( $content ) ? false : $this->isSvg( $content ) && (strpos( $content, 'feGaussianBlur' ) !== false || 511 strpos( $content, 'filter="blur' ) !== false); 438 512 } 439 513 … … 959 1033 if ( !!$this->ctrl->options->settings_behaviour_lqip && $this->ctrl->options->settings_behaviour_processWay === LQIP::USE_INSTANT) 960 1034 { 1035 961 1036 wp_register_script( 'spai-lqip', $this->ctrl->plugin_url . $file, $this->ctrl->options->settings_behaviour_nojquery <= 0 ? [ 'spai-scripts' ] : [], $version, true ); 962 1037 wp_localize_script( 'spai-lqip', 'lqipConstants', [ -
shortpixel-adaptive-images/trunk/includes/controllers/notice.class.php
r3258698 r3340495 373 373 } 374 374 375 if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] === 'shortpixel-ai-settings') { 376 $installed = get_option( 'shortpixel_ai_installed_time' ); 377 if ( ! $installed ) { 378 update_option( 'shortpixel_ai_installed_time', time() ); 379 } 380 elseif ( time() - $installed >= 30 * DAY_IN_SECONDS ) { 381 $dismissed = self::getDismissed(); 382 if ( !isset( $dismissed->recommend_survey ) ) { 383 Notice::render('recommend_survey', [ 384 'notice' => [ 385 'type' => 'info', 386 'icon' => 'notes', 387 'dismissible' => true, 388 ], 389 'message' => [ 390 'title' => __('How likely are you to recommend ShortPixel AI to a friend or colleague?', 'shortpixel-adaptive-images'), 391 'body' => [ 392 '<p><span style="margin-right:1em;">' . __('Not likely', 'shortpixel-adaptive-images') . '</span>' 393 . implode('', array_map(function ($i) { 394 return '<button class="button survey-rating-btn" ' 395 . 'data-rating="'. $i .'" ' 396 . 'style="margin:0 3px; min-width:2.5em; text-align:center; line-height:1.6;">' 397 . $i 398 . '</button>'; 399 }, range(1, 10))) 400 . '<span style="margin-left:1em;">' . __('Very likely', 'shortpixel-adaptive-images') . '</span></p>', 401 '<div id="survey-feedback-area" style="display:none;margin-top:10px;">' 402 . '<p><strong id="survey-feedback-prompt">' . __('Give us your feedback:', 'shortpixel-adaptive-images') . '</strong></p>' 403 . '<textarea id="survey-feedback" rows="3" style="width:100%;"></textarea><br><br>' 404 . '<button id="survey-feedback-submit" class="button button-primary">' 405 . __('Submit', 'shortpixel-adaptive-images') 406 . '</button>' 407 . '</div>', 408 ], 409 ], 410 ]); 411 } 412 } 413 } 414 375 415 if ( !isset( $dismissed->wp_rocket_defer_js ) && $integrations->has( 'wp-rocket', 'defer-all-js' ) ) { 376 416 self::render( 'wp rocket defer js', [ -
shortpixel-adaptive-images/trunk/includes/controllers/page.class.php
r3074757 r3340495 244 244 header('Content-Type: application/json'); 245 245 header('Content-Disposition: attachment; filename=SPAI-settings.json'); 246 echo(json_encode($this->ctrl->options->get()->settings , JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));246 echo(json_encode($this->ctrl->options->get()->settings->exportRecursive(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); 247 247 die(); 248 248 } ); -
shortpixel-adaptive-images/trunk/includes/controllers/regex-parser.class.php
r3209129 r3340495 26 26 private $forceEager = false; 27 27 private $isTemplate = false; 28 private $content; 28 29 29 30 … … 42 43 ]; 43 44 45 46 protected function markTotalExclude(string $tagHtml, string $origUrl): string 47 { 48 $attrs = ' data-spai-target="src"'; 49 $attrs .= ' data-spai-orig="' . esc_attr($origUrl) . '"'; 50 $attrs .= ' data-spai-exclude="nocdn"'; 51 return preg_replace( 52 '/<img\b([^>]*)>/i', 53 '<img$1' . $attrs . '>', 54 $tagHtml, 55 1 56 ); 57 } 44 58 45 59 public function __construct(ShortPixelAI $ctrl) … … 160 174 //In some cases the regex fails with this limit reached (default is 1000000) so make it larger (HS#75940) 161 175 ini_set('pcre.backtrack_limit', 2000000); 176 177 $this->content = $content; 162 178 163 179 foreach (\ShortPixel\AI\TagRules::_()->items() as $tagRule) { … … 670 686 if( !ShortPixelUrlTools::isValid($url) 671 687 && (!$this->isTemplate || strpos($url, '{{:') === false)) {$this->logger->log('NOT VALID');return $text;} 672 if($this->ctrl->urlIsExcluded($url)) {$this->logger->log('EXCLUDED');return $text;} 688 if ($this->ctrl->urlIsExcluded($url)) { 689 $this->logger->log('EXCLUDED TOTALLY: ' . $url); 690 return $this->markTotalExclude($text, $url); 691 } 673 692 674 693 //custom exclusion for SliderRevolution TODO unhack … … 699 718 } 700 719 701 $eager = $this->isEager || $this->ctrl->tagIs('eager', $text) ;720 $eager = $this->isEager || $this->ctrl->tagIs('eager', $text) || $this->ctrl->urlIsEager($url);; 702 721 703 722 SHORTPIXEL_AI_DEBUG && $this->logger->log("Including: " . $url . ($eager ? ' EAGER' : ' LAZY')); … … 776 795 777 796 if($eager) { 778 //we set any CSS or JS to ret_wait because of the many CORS issues we've seen with these.779 $wait = $ext == 'css' || $ext == 'js';797 //we set any CSS or JS or FONTS to ret_wait because of the many CORS issues we've seen with these. 798 $wait = in_array($ext, ShortPixelUrlTools::$EAGER_WAIT); 780 799 $cacheVer = $wait ? $this->ctrl->cssCacheVer : false; 781 800 if($this->isTemplate && strpos($url, '{{:') === 0) { … … 783 802 . '/' . $url; 784 803 } else { 785 $inlinePlaceholder = $this->ctrl->get_api_url( $absoluteUrl, false, false, $this->ctrl->get_extension( $url ), $this->tagRule->getCustomCompression(), $wait, $cacheVer); 804 $separator = strpos($this->content, $absoluteUrl) > 0 && $this->tagRule->attrValFilter == "preload" ? "," : ShortPixelAI::SEP; 805 $inlinePlaceholder = $this->ctrl->get_api_url($absoluteUrl, false, false, $this->ctrl->get_extension($url), $this->tagRule->getCustomCompression(), $wait, $cacheVer, $separator); 786 806 } 787 807 $spaiMarker = ' data-spai-egr=' . $qm . '1' . $qm; … … 1030 1050 $aiSrcsetItems = array(); 1031 1051 $aiUrl = $this->ctrl->get_api_url(false, false); 1032 $aiUrlBase = $this->ctrl->settings->behaviour->api_url; 1052 $aiUrlBase = $this->ctrl->settings->behaviour->api_url; //ex: https://cdn.shortpixel.ai/spai 1053 $aiUrlBaseAmazon = $this->ctrl->settings->behaviour->storage_url; //ex: https://cdn.shortpixel.ai/x9 1033 1054 $srcsetItems = explode(',', $srcset); 1034 1055 foreach($srcsetItems as $srcsetItem) { … … 1040 1061 return $srcset; 1041 1062 } 1042 if(strpos($srcsetItem, $aiUrlBase) !== false || strpos($srcsetItem, 'data:image/') === 0) {1063 if(strpos($srcsetItem, $aiUrlBase) !== false || strpos($srcsetItem, $aiUrlBaseAmazon) !== false || strpos($srcsetItem, 'data:image/') === 0) { 1043 1064 SHORTPIXEL_AI_DEBUG && $this->logger->log("REPLACE SRCSET abort - AI url: " . $srcsetItem); 1044 1065 return $srcset; //already parsed by the hook. -
shortpixel-adaptive-images/trunk/includes/controllers/short-pixel-ai.class.php
r3310531 r3340495 470 470 if ( is_null( $this->options->get( 'api_url', [ 'settings', 'behaviour' ], null ) ) ) { 471 471 $this->options->settings_behaviour_apiUrl = ShortPixelAI::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 472 $this->options->settings_behaviour_amazonS3 = false; 472 473 $this->options->settings_behaviour_replaceMethod = 'src'; 473 474 $this->options->settings_behaviour_fadein = true; … … 1133 1134 $result['message'] = __('Invalid selector has been provided.', 'shortpixel-adaptive-images' ); 1134 1135 } 1135 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_ selectors'))) {1136 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_paths', 'eager_selectors'))) { 1136 1137 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1137 1138 } … … 1141 1142 $selectors_now = $this->options->$wp_option_name; 1142 1143 $result['status'] = 'ok'; 1143 if($which === 'excluded_paths' ) {1144 if($which === 'excluded_paths' || $which === 'eager_paths' ) { 1144 1145 $name = 'URL'; 1145 1146 $delimiter = "\n"; … … 1214 1215 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1215 1216 } 1216 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_selectors' ))) {1217 else if(empty($which) || !is_string($which) || !in_array($which, array('noresize_selectors', 'excluded_selectors', 'excluded_paths', 'eager_selectors', 'eager_paths'))) { 1217 1218 $result['message'] = __('Invalid list has been provided.', 'shortpixel-adaptive-images' ); 1218 1219 } … … 1303 1304 $options->settings_behaviour_replaceMethod = $replace_method == 1 ? 'src' : ( $replace_method == 3 ? 'both' : 'srcset' ); 1304 1305 $options->settings_behaviour_apiUrl = get_option( 'spai_settings_api_url' ); 1305 $options->settings_behaviour_hoverHandling = !!get_option( 'spai_settings_hover_handling' );1306 $options->settings_behaviour_hoverHandling = !!get_option( 'spai_settings_hover_handling' ); 1306 1307 $options->settings_behaviour_nativeLazy = !!get_option( 'spai_settings_native_lazy' ); 1307 1308 … … 1503 1504 if (function_exists('is_plugin_active') && is_plugin_active('sg-cachepress/sg-cachepress.php')) { 1504 1505 $speedoptimizer = get_option('siteground_optimizer_combine_javascript', false); 1505 //var_dump($speedoptimizer);1506 1506 if ($speedoptimizer === '1') { 1507 1507 $this->conflict = 'speedoptimizer'; … … 1551 1551 } 1552 1552 1553 public function get_api_url( $url = false, $width = '%WIDTH%', $height = '%HEIGHT%', $type = false, $compression = false, $retAuto = false, $cacheVer = false) { 1553 1554 /** 1555 * This function checks whether the CDN returned by get_cdn_url() is different 1556 * from the default "https://cdn.shortpixel.ai/spai". 1557 * 1558 * If it is different, we consider it a "custom CDN". 1559 */ 1560 private function is_custom_cdn() 1561 { 1562 $cdn = $this->get_cdn_url(); 1563 if (!$cdn) { 1564 $cdn = self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 1565 } 1566 $cdn = rtrim($cdn, '/'); 1567 $defaultCdn = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1568 $isBasicCustom = ($cdn !== $defaultCdn); 1569 1570 return $isBasicCustom; 1571 } 1572 1573 private function is_amazon_cdn(){ 1574 $amazonGet = $this->settings->behaviour->amazon_s3; 1575 $amazonEnabled = !empty($amazonGet); 1576 $amazonStorageGet = $this->settings->behaviour->storage_url; // tha's the user input 1577 $amazonStorage = !empty($amazonStorageGet); 1578 // only if user has a storage_url (and amazon_s3 is enabled), we consider that is 'custom as well. 1579 $isAmazonCustom = ($amazonEnabled && $amazonStorage); 1580 1581 return $isAmazonCustom; 1582 } 1583 1584 /** 1585 * chooses the appropriate API base URL based on CDN settings. 1586 * 1587 * @param string|false $url The original URL. 1588 * @return string The selected base URL. 1589 */ 1590 public function choose_api_base() 1591 { 1592 $isAmazonCdn = $this->is_amazon_cdn(); 1593 1594 if ($isAmazonCdn) { 1595 return rtrim($this->settings->behaviour->storage_url, '/'); 1596 } else { 1597 $cdnUrl = rtrim($this->get_cdn_url(), '/'); 1598 if (!$cdnUrl) { 1599 $cdnUrl = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1600 } 1601 return $cdnUrl; 1602 } 1603 } 1604 1605 private function do_host_removal(){ 1606 $hostRemovalGet = $this->settings->behaviour->host_removal; 1607 $isHostRemoval = !empty($hostRemovalGet); 1608 return$isHostRemoval; 1609 } 1610 1611 /** 1612 * Applies host removal to the API URL if conditions are met. 1613 * 1614 * @param string $api_url The constructed API URL. 1615 * @param string|false $url The original URL. 1616 * @return string The final URL after host removal (if applied). 1617 */ 1618 private function host_removal_logic($api_url, $url) 1619 { 1620 if (!$url) { 1621 return $api_url; 1622 } 1623 1624 $doHostRemoval = $this->do_host_removal(); 1625 $hostRemoval = $this->settings->behaviour->host_removal; 1626 1627 if ($doHostRemoval && $url){ 1628 $parsedUrl = parse_url($url); 1629 $host = $parsedUrl['host'] ?? ''; 1630 1631 if (strpos($host, $hostRemoval) !== false) { 1632 $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; 1633 $query = isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : ''; 1634 $frag = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : ''; 1635 $final = rtrim($api_url, '/') . $path . $query . $frag; 1636 return $final; 1637 } 1638 } 1639 1640 return $api_url; 1641 } 1642 1643 1644 1645 1646 /** 1647 * This helper method builds the final URL by appending ShortPixel parameters 1648 * (w_, q_, ex_, to_, etc.) to the base URL using self::SEP. 1649 * 1650 * @param string $baseUrl e.g. "https://cdn.shortpixel.ai/spai" 1651 * @param array $args e.g. [ ['w' => 300], ['q' => 'lossy'], ['ex' => '1'] ] 1652 * @return string e.g. "https://cdn.shortpixel.ai/spai/w_300+q_lossy+ex_1" 1653 */ 1654 private function build_spai_url($baseUrl, array $args, $separator = self::SEP){ 1655 $api_url = trailingslashit($baseUrl); 1656 foreach ($args as $arg) { 1657 foreach ($arg as $k => $v) { 1658 $api_url .= $k . '_' . $v . $separator; 1659 } 1660 } 1661 return rtrim($api_url, $separator); 1662 1663 } 1664 public function get_api_url( $url = false, $width = '%WIDTH%', $height = '%HEIGHT%', $type = false, $compression = false, $retAuto = false, $cacheVer = false, $separator = self::SEP) { 1665 1666 if ($url && $this->urlIsExcluded($url)) { 1667 $this->logger->log("DEBUG get_api_url: URL completly excluded. Returning original URL: " . $url); 1668 return $url; 1669 } 1554 1670 $args = array(); 1555 1671 $http = $url === false ? !is_ssl() : !self::is_ssl($url); 1556 1672 1557 if ($compression == 'orig' && defined('SHORTPIXEL_AI_ORIG_NO_CDN')) {1673 if ($compression == 'orig' && defined('SHORTPIXEL_AI_ORIG_NO_CDN')) { 1558 1674 return ''; 1559 1675 } … … 1590 1706 } 1591 1707 1592 $api_url = $this->get_cdn_url(); 1593 1594 if ( !$api_url ) { 1595 $api_url = self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH; 1596 } 1597 1598 $api_url = trailingslashit($api_url); 1599 1600 /* 1601 Make args to be in desired format 1602 */ 1603 foreach ($args as $arg) { 1604 foreach ($arg as $k => $v) { 1605 $api_url .= $k . '_' . $v . self::SEP; 1606 } 1607 } 1608 $api_url = rtrim($api_url, self::SEP); 1609 //$api_url = trailingslashit( $api_url ); 1610 return $api_url . ($url ? '/' . self::rem_proto($url) : ''); 1611 } 1708 1709 $isAmazonCdn = $this->is_amazon_cdn(); //verify if it is amazon CDN 1710 1711 // detect bucket name presence in host 1712 $hostFound = false; 1713 if ($isAmazonCdn) { 1714 $hostRemovalGet = $this->settings->behaviour->host_removal ?? null; 1715 1716 if ($hostRemovalGet && $url) { 1717 $parsed = parse_url($url); 1718 $host = $parsed['host'] ?? ''; 1719 if (strpos($host, $hostRemovalGet) !== false) { 1720 $hostFound = true; 1721 } 1722 } 1723 } 1724 if ($hostFound){ 1725 // case 1: amazon CDN active and URL contains host_removal, will apply amazon cdn + host removal 1726 $amazonStorageGet = $this->settings->behaviour->storage_url; 1727 $base = rtrim($amazonStorageGet, '/'); // Amazon base 1728 $api_url = $this->build_spai_url($base, $args, $separator); 1729 $this->logger->log("BUILT Amazon api_url => ", $api_url); 1730 1731 $final_url = $this->host_removal_logic($api_url, $url); 1732 if ($final_url !== $api_url) { 1733 return $final_url; 1734 } 1735 if (!$url) { 1736 return $api_url; 1737 } 1738 1739 $ret = $api_url . '/' . self::rem_proto($url); 1740 return $ret; 1741 } else { 1742 // case 2: Amazon CDN active but URL does't match host_removal will not put amazon cdn and not remove host 1743 // case 3: Amazon CDN disabled ... get as usual with normal cdn 1744 $base = rtrim($this->get_cdn_url(), '/'); 1745 if (!$base) { 1746 $base = rtrim(self::DEFAULT_API_AI . self::DEFAULT_API_AI_PATH, '/'); 1747 } 1748 $api_url = $this->build_spai_url($base, $args, $separator); 1749 1750 if (!$url) { 1751 return $api_url; 1752 } 1753 1754 $final = $api_url . '/' . self::rem_proto($url); 1755 return $final; 1756 } 1757 } 1612 1758 1613 1759 public function maybe_replace_images_src($content) … … 1753 1899 'noresize_selectors' => $this->splitSelectors( @$ex->noresize_selectors, ',' ), 1754 1900 'excluded_paths' => $this->splitSelectors( @$ex->excluded_paths, "\n" ), 1901 'eager_paths' => $this->splitSelectors( @$ex->eager_paths, "\n" ), 1755 1902 'excluded_pages' => $this->splitSelectors( @$ex->excluded_pages, "\n" ), 1756 1903 ]; … … 1811 1958 } 1812 1959 1813 public function urlIsExcluded($url) { 1814 1815 //exclude generated images like JetPack's admin bar hours stats 1816 if(strpos($url, '?page=')) { 1817 $admin = parse_url(admin_url()); 1818 if(isset($admin['path']) && strpos($url, $admin['path'])) { 1819 return true; 1820 } 1821 } 1822 1823 if( strlen($this->settings->exclusions->excluded_paths)) { 1824 return $this->isExcluded($url, $this->settings->exclusions->excluded_paths); 1825 } else { 1826 return false; 1827 } 1828 1829 } 1830 1960 1961 /** 1962 * 1963 * This function parses the given URL and removes any resolution suffix (e.g., "-1024x576") 1964 * that is automatically appended by some WordPress themes for images. * 1965 * 1966 * useful when comparing image URLs against exclusion rules, insuring that any 1967 * appended resolution suffix does not prevent a match with the base URL. 1968 * 1969 * @param string $url - original image URL. 1970 * @return string - normalized image URL without the resolution suffix, or the original URL if parsing fails. 1971 */ 1972 public function normalizeUrlForExcluded($url) { 1973 $parsed = parse_url($url); 1974 $this->logger->log("DEBUG: parsed " . json_encode($parsed, JSON_PRETTY_PRINT)); //var_export($parsed) //print_r($parsed) 1975 if (!isset($parsed['path'])) { 1976 return $url; 1977 } 1978 $normalizedPath = preg_replace( 1979 '/-\d+x\d+(?=\.\w+$)/', 1980 '', 1981 $parsed['path'] 1982 ); 1983 $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : (is_ssl() ? 'https' : 'http'); 1984 $siteUrl = home_url(); 1985 $siteHost = parse_url($siteUrl, PHP_URL_HOST); 1986 return $scheme . '://' . $siteHost . $normalizedPath; 1987 } 1988 1989 /** 1990 * Core URL-matching method to test either total or eager exclusion. 1991 * 1992 * @param string $mode Either 'excluded' (full exclusion) or 'eager' (skip lazy only) 1993 * @param string $url The image URL (may include CDN, Amazon, any host or size suffix) 1994 * @return bool True for matching either one mode’s rules 1995 */ 1996 public function urlIs($mode, $url) 1997 { 1998 //revert CDN url to original 1999 if ($this->urlIsApi($url)) { 2000 $stripped = self::rem_proto($url); 2001 $scheme = self::is_ssl($url) ? 'https://' : 'http://'; 2002 $url = $scheme . $stripped; 2003 $this->logger->log("DEBUG urlIs: Reverted CDN URL to original: $url"); 2004 } 2005 //exclude generated images like JetPack's admin bar hours stats 2006 if (strpos($url, '?page=')) { 2007 $admin = parse_url(admin_url()); 2008 if (strpos($url, $admin['path'])) { 2009 return true; 2010 } 2011 } 2012 //normalize any resolution suffix... 2013 $normalizedUrl = $this->normalizeUrlForExcluded($url); 2014 $this->logger->log("DEBUG urlIsExcluded: Normalized URL: " . $normalizedUrl); 2015 //2 posibilities URL -> total exclusion('excluded') or eager exclusion('eager') 2016 $list = ($mode === 'excluded') 2017 ? $this->settings->exclusions->excluded_paths 2018 : $this->settings->exclusions->eager_paths; 2019 if (strlen($list)) { 2020 if ($this->isExcluded($url, $list) || $this->isExcluded($normalizedUrl, $list)) { 2021 return true; 2022 } 2023 } 2024 2025 return false; 2026 2027 } 2028 2029 /** 2030 * FULL-EXCLUSION wrapper: 2031 * Returns true if this URL must skip CDN entirely (no lazy, no CDN). 2032 * 2033 * @param string $url 2034 * @return bool 2035 */ 2036 public function urlIsExcluded(string $url): bool 2037 { 2038 return $this->urlIs('excluded', $url); 2039 } 2040 2041 /** 2042 * EAGER-ONLY wrapper: 2043 * Returns true if this URL should load eagerly (CDN OK but no lazy loading). 2044 * 2045 * @param string $url 2046 * @return bool 2047 */ 2048 public function urlIsEager(string $url): bool 2049 { 2050 return $this->urlIs('eager', $url); 2051 } 1831 2052 1832 2053 /** … … 1876 2097 case 'http': //being so kind to accept urls as they are. :) 1877 2098 case 'https': 1878 if(!isset($urlParsed['host'])) {1879 $valueParsed = parse_url($value);1880 if(isset($valueParsed['host'])) {1881 $url = ShortPixelUrlTools::absoluteUrl($url);1882 }1883 }1884 2099 if(strpos($url, $value) !== false) { 1885 2100 $this->logger->log("EXCLUDED by $type $value RULE:", $rule); 1886 2101 return true; 1887 2102 } 2103 2104 if (isset($urlParsed['path'])) { 2105 $ruleParsed = parse_url($value); 2106 if (!empty($ruleParsed['path'])) { 2107 $rulePathNorm = preg_replace('/-\d+x\d+(?=\.\w+$)/', '', $ruleParsed['path']); 2108 $urlPathNorm = preg_replace('/-\d+x\d+(?=\.\w+$)/', '', $urlParsed['path']); 2109 if ($rulePathNorm === $urlPathNorm) { 2110 $this->logger->log("EXCLUDED by HOST-INSENSITIVE PATH MATCH: $rulePathNorm"); 2111 return true; 2112 } 2113 } 2114 } 1888 2115 if(isset($urlParsed['path'])) { 1889 2116 preg_match(self::THUMBNAIL_REGEX, $urlParsed['path'], $matches); … … 2059 2286 'exclusions' => [ 2060 2287 'excluded_paths' => self::GRAVATAR_REGEX, 2061 'eager_selectors' => '', 2288 'eager_paths' => '', 2289 'eager_selectors' => '', 2062 2290 'noresize_selectors' => '', 2063 2291 'excluded_selectors' => '', -
shortpixel-adaptive-images/trunk/includes/front/jquery-js-loader.class.php
r3209129 r3340495 70 70 //the excluded_paths can contain URLs so we base64 encode them in order to pass our own JS parser :) 71 71 'excluded_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->excluded_paths, PHP_EOL ) ), 72 'eager_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL ) ), 72 73 ] ); 73 74 -
shortpixel-adaptive-images/trunk/includes/front/vanilla-js-loader.class.php
r3337681 r3340495 17 17 add_action( 'wp_head', function() { 18 18 $apiUrlParts = explode('/', rtrim($this->ctrl->get_cdn_url(), '/')); 19 $customApiUrlParts = explode('/', rtrim($this->ctrl->choose_api_base(), '/')); 20 $customKeys = []; 21 if ($this->settings->behaviour->amazon_s3) { 22 $hostRemoval = $this->settings->behaviour->host_removal; 23 $customKey = end($customApiUrlParts); 24 if ($hostRemoval && $customKey) { 25 $customKeys[$hostRemoval] = $customKey; 26 } 27 } 28 19 29 $convert = 'none'; 20 30 if(!!$this->settings->compression->webp || !!$this->settings->compression->avif) { … … 47 57 version: "<?= esc_js(SHORTPIXEL_AI_VERSION) ?>", 48 58 key: "<?= esc_js(end($apiUrlParts)) ?>", 59 customKeys: <?= wp_json_encode($customKeys) ?>, 49 60 quality: "<?= esc_js($this->settings->compression->level) ?>", 50 61 convert: "<?= esc_js($convert) ?>", … … 91 102 'noresize_selectors' => $this->ctrl->splitSelectors( $this->settings->exclusions->noresize_selectors, ',' ), 92 103 'excluded_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->excluded_paths, PHP_EOL ) ), 104 'eager_paths' => array_map( 'base64_encode', $this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL ) ), 93 105 ]); 94 106 wp_enqueue_script( 'spai-snip-action' ); … … 273 285 ['lazy' => 0, 'cdn' => 0, 'resize' => 0, 'crop' => -1]); 274 286 } 287 288 foreach($this->ctrl->splitSelectors( $this->settings->exclusions->eager_paths, PHP_EOL) as $eagerPath) { 289 $this->alterExclusion($exclusions, 'urls', $eagerPath, ['lazy' => 0]); 290 } 291 275 292 foreach($this->ctrl->splitSelectors( $this->settings->exclusions->excluded_selectors, ',') as $excludedSel) { 276 293 $this->alterExclusion($exclusions, 'selectors', $excludedSel, -
shortpixel-adaptive-images/trunk/includes/helpers/url-tools.class.php
r3160580 r3340495 17 17 'eot', 'woff', 'woff2', 'ttf', 'otf' ]; 18 18 public static $ONLY_STORE = [ 'svg', 'js', 'eot', 'webp', 'avif', 'woff', 'woff2', 'ttf', 'otf' ]; 19 public static $EAGER_WAIT = [ 'css', 'js', 'woff2', 'woff', 'otf', 'ttf', 'eot' ]; 19 20 private static $SIZE_CACHE = []; 20 21 -
shortpixel-adaptive-images/trunk/includes/models/options.category.class.php
r3125365 r3340495 15 15 public function getData() { 16 16 return $this->__dyna; 17 } 18 19 /** 20 * exports the internal data structure of the Category object 21 * - traverses internal proteected __dyna object, and for each property, 22 * it checks if the value is another Category, Option, stdClass. 23 * @return array fully expanded data structure. 24 */ 25 public function exportRecursive() { 26 $result = []; 27 28 foreach ((array) $this->getData() as $key => $value) { 29 if ($value instanceof \ShortPixel\AI\Options\Category) { 30 $result[$key] = $value->getData(); 31 } elseif ($value instanceof \ShortPixel\AI\Options\Option) { 32 $result[$key] = $value->getData(); 33 } elseif ($value instanceof \stdClass) { 34 $result[$key] = json_decode(json_encode($value), true); 35 } else { 36 $result[$key] = $value; 37 } 38 } 39 return $result; 17 40 } 18 41 -
shortpixel-adaptive-images/trunk/includes/views/settings.tpl.php
r3209129 r3340495 706 706 </td> 707 707 </tr> 708 709 710 <tr> 711 <th scope="row"> 712 <?= __( 'Amazon S3', 'shortpixel-adaptive-images' ); ?> 713 </th> 714 <td> 715 <div class="spai-inline-help"> 716 <span class="dashicons dashicons-editor-help" 717 title="Inline help" 718 data-link="https://shortpixel.com/knowledge-base/article/using-shortpixel-adaptive-images-with-images-on-amazon-s3/"></span> 719 </div> 720 <input 721 id="amazon_s3" 722 type="checkbox" 723 name="amazon_s3" 724 class="tgl" 725 data-type="bool" 726 value="1" 727 <?php checked( 1, $options->settings_behaviour_amazonS3, true ); ?> 728 /> 729 730 <label for="amazon_s3" class="tgl-btn"> 731 <span></span> 732 <?= __( 'Deliver the images stored on Amazon S3 using ShortPixel CDN', 'shortpixel-adaptive-images' ); ?> 733 </label> 734 <p class="description"> 735 <?= __( 'Enable this option if you are offloading the images to an Amazon S3 bucket and you want to deliver them via our CDN to reduce costs. Read the configuration guide in <a href="https://shortpixel.com/knowledge-base/article/using-shortpixel-adaptive-images-with-images-on-amazon-s3/" target="_blank">our knowledge base</a>', 'shortpixel-adaptive-images' ); ?> 736 </p> 737 <div class="amazon-s3-fields-wrapper"> 738 <p> 739 <label for="storage_url" style="display: inline-block; width: 140px;"> 740 <strong><?= __( 'Base URL', 'shortpixel-adaptive-images' ); ?></strong> 741 </label> 742 <input 743 id="storage_url" 744 type="text" 745 data-type="string" 746 name="storage_url" 747 size="40" 748 placeholder="<?= __( 'Paste Base URL from ShortPixel Dashboard', 'shortpixel-adaptive-images' ); ?>" 749 value="<?= esc_attr( $options->settings_behaviour_storageUrl ); ?>" 750 <?php disabled(!$options->settings_behaviour_amazonS3, true); ?> 751 /> 752 753 754 </p> 755 <p> 756 <label for="host_removal" style="display: inline-block; width: 140px;"> 757 <strong><?= __( 'S3 Bucket URL', 'shortpixel-adaptive-images' ); ?></strong> 758 </label> 759 <input 760 id="host_removal" 761 type="text" 762 data-type="string" 763 name="host_removal" 764 size="40" 765 placeholder="<?= __( 'Get it from your Amazon S3 bucket details', 'shortpixel-adaptive-images' ); ?>" 766 value="<?= esc_attr( $options->settings_behaviour_hostRemoval ); ?>" 767 <?php disabled(!$options->settings_behaviour_amazonS3, true); ?> 768 /> 769 </p> 770 </div> 771 <script> 772 jQuery(document).ready(function($){ 773 $('#amazon_s3').on('change', function() { 774 var isChecked = $(this).is(':checked'); 775 $('#storage_url, #host_removal').prop('disabled', !isChecked); 776 }).trigger('change'); 777 }); 778 </script> 779 </td> 780 </tr> 781 782 708 783 <tr> 709 784 <th scope="row"> … … 1366 1441 $no_resize_selectors = $options->settings_exclusions_noresizeSelectors; 1367 1442 $excluded_selectors = $options->settings_exclusions_excludedSelectors; 1443 $eager_paths = $options->settings_exclusions_eagerPaths; 1368 1444 $excluded_paths = $options->settings_exclusions_excludedPaths; 1369 1445 $excluded_pages = $options->settings_exclusions_excludedPages; … … 1373 1449 'no_resize_selectors' => $controller->splitSelectors( $no_resize_selectors, ',' ), 1374 1450 'excluded_selectors' => $controller->splitSelectors( $excluded_selectors, ',' ), 1451 'eager_paths' => $controller->splitSelectors( $eager_paths, PHP_EOL ), 1375 1452 'excluded_paths' => $controller->splitSelectors( $excluded_paths, PHP_EOL ), 1376 1453 ]; … … 1382 1459 1383 1460 $excluded_selectors_qty = count( $split_selectors[ 'eager_selectors' ] ) + count( $split_selectors[ 'no_resize_selectors' ] ) + count( $split_selectors[ 'excluded_selectors' ] ); 1384 $excluded_paths_qty = count( $split_selectors[ 'excluded_paths' ] ) ;1461 $excluded_paths_qty = count( $split_selectors[ 'excluded_paths' ] ) + count( $split_selectors[ 'eager_paths' ] ); 1385 1462 ?> 1386 1463 <table class="form-table"> … … 1448 1525 <?= str_replace( '{{QTY}}', $excluded_paths_qty, __( 'You already have <span>{{QTY}}</span> URL exclusions active. Please keep the number of exclusion selectors low for best performance.', 'shortpixel-adaptive-images' ) ); ?> 1449 1526 </p> 1450 <div> 1527 1528 <div><label for="eager_paths"><?= __( 'Don\'t lazy-load Url\'s:', 'shortpixel-adaptive-images' ); ?></label><br> 1529 <textarea 1530 id="eager_paths" 1531 name="eager_paths" 1532 rows="5" 1533 data-type="string" 1534 data-exclusion-type="urls" 1535 data-setting="exclusion" 1536 data-separator="<?= PHP_EOL; ?>" 1537 ><?= $eager_paths; ?></textarea> 1538 </div> 1539 <div><label for="excluded_paths"><?= __( 'Leave out completely Url\'s:', 'shortpixel-adaptive-images' ); ?></label><br> 1451 1540 <textarea 1452 1541 id="excluded_paths" -
shortpixel-adaptive-images/trunk/readme.txt
r3337681 r3340495 5 5 Tested up to: 6.8 6 6 Requires PHP: 5.6.40 7 Stable tag: 3.1 0.57 Stable tag: 3.11.0 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 249 249 250 250 == Changelog == 251 252 = 3.11.0 = 253 254 🌩️ The S3 & Speed Boost Update 255 256 Release Date: August 6, 2025 257 258 ✨ New Features 259 260 * Amazon S3 Integration: Images stored on Amazon S3 can now be seamlessly served through the ShortPixel CDN — faster delivery, no matter where your files live. 261 * Lazy-Load Exclusions by URL: You can now exclude specific images from lazy-loading by their URL for greater control over your image loading strategy. 262 263 ⚙️ Improvements 264 265 * Smarter LQIP Handling: Optimized the way Low-Quality Image Placeholders (LQIPs) are processed to boost performance on sites with lots of images. 266 267 🛠️ Fixes 268 269 * Settings Export Restored: Exporting your plugin settings now works reliably in all scenarios. 270 * LQIP Fixes: Addressed several minor issues to ensure LQIPs behave correctly across different setups. 271 * Security Enhancements: Added extra security checks to strengthen protection and prevent potential vulnerabilities. 272 273 Update now to enjoy smarter performance, better control, and enhanced flexibility with your image delivery! 🚀 251 274 252 275 = 3.10.5 = … … 691 714 * Language: 18 new strings added, 51 updated, 0 fuzzed, and 12 obsoleted. 692 715 693 = 2.3.3 =694 Release date: June 30th, 2021695 * Fix: issue with validating API key696 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.697 698 = 2.3.2 =699 Release date: June 29th, 2021700 * Temporarily deactivate AVIF pending codec bug fix (https://github.com/xiph/rav1e/issues/2757);701 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.702 703 = 2.3.1 =704 Release date: June 28th, 2021705 * New: Version the javascript in the file name in order to get around more stubborn caches;706 * Fix: do not parse AJAX responses to uploads;707 * Fix: nested element that has a different background - was taking the background of the parent element;708 * Fix: notice in logs sometimes when domain info from server;709 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.710 711 = 2.3.0 =712 Release date: June 17th, 2021713 * New: images (including the ones from CSS files) are now served automatically in the new AVIF format to supporting browsers;714 * New: moved the JS detection mechanism for WebP/AVIF support directly to the CDN level, so no JS is required anymore for this;715 * Language: 0 new strings added, 6 updated, 0 fuzzed, and 0 obsoleted.716 717 = 2.2.4 =718 Release date: June 14th, 2021719 * Compat: added a constant - `SPAI_ELEMENTOR_WORKAROUND` - to deactivate the parsing of Elementor modules that are resulting in critical errors;720 * Compat: workaround for WP Rocket that calls in certain circumstances the filter `rocket_css_content` with only one parameter;721 * Fix: some warnings when lqip queue is not array were showing up in some cases;722 * Fix: wrong array key when the no background calculation can't determine crop size and returns just width and height;723 * Fix: iPhone issues with parsing stylesheets while also improving page responsiveness while parsing them (async);724 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.725 726 = 2.2.3 =727 Release date: May 18th, 2021728 * New: also parse inside `<script type="text/template">` blocks;729 * Fix: the background crop resize wasn't working in several cases, which is now fixed;730 * Fix: update the notification text about the next generation images served by SPIO;731 * Fix: cases when a mutation has backgrounds from an existing CSS block are now properly handled;732 * Fix: the special crop feature now handles correctly the situations when the width parameter isn't the first one;733 * Fix: the inline background selector will handle situations with no space before the CSS class definition;734 * Fix: remove the default values for JS parameters in order to support IE11;735 * Fix: the images from `li` elements added with `data-thumb` are now replaced;736 * Fix: the URL exclusions are checked when replacing inside JS blocks too;737 * Language: 0 new strings added, 2 updated, 0 fuzzed, and 0 obsoleted.738 739 = 2.2.2 =740 Release date: April 29th, 2021741 * Fix: the minified version of the plugin CSS files was bigger than the not minified one;742 * Fix: find local file when URL contains a path element before wp-content, that is not present on disk;743 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.744 745 = 2.2.1 =746 Release date: April 26th, 2021747 * Compat: added integration with Real3D Flipbook;748 * Fix: there was a "Class not found" error in some cases when purging LiteSpeed cache from our plugin;749 * Fix: in some cases, the size of background images wasn't properly set;750 * Fix: protection added for very large number of product variations; the plugin will now work properly in these cases;751 * Language: 0 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.752 753 = 2.2.0 =754 Release date: April 20th, 2021755 * New: added filter `shortpixel/ai/customRules` for custom replacement rules;756 * New: added proper lazy loading for background images;757 * New: take into account the `background-*` CSS styles: size, position, etc.;758 * New: lazy load the images in the CSS blocks;759 * New: handle correctly multiple URLs in the same `background-image:` declaration;760 * New: when running out of credits you can now have an option to top-up directly from the plugin settings;761 * Compat: added an integration with the Uncode theme and its iLightBox component;762 * Compat: added integration with WPC Variations Table;763 * Compat: added integration with Soliloquy Slider Plugin;764 * Compat: also integrate properly with Divi child themes;765 * Compat: improved the integration with Elementor, all images should now be properly replaced;766 * Fix: WooCommerce product variations were broken if srcset was present, but false;767 * Fix: in certain cases, background images with important CSS priority weren't properly handled;768 * Fix: also remove the sizes attribute if we remove the srcset;769 * Fix: replacement error when html attribute contains "<style>.." data;770 * Fix: various small fixes to settings, fonts, debug messages, ShortPixel account login and lazy loading;771 * Language: 7 new strings added, 2 updated, 0 fuzzed, and 3 obsoleted.772 716 773 717 = EARLIER VERSIONS = -
shortpixel-adaptive-images/trunk/short-pixel-ai.php
r3337681 r3340495 4 4 * Plugin URI: https://shortpixel.com/ 5 5 * Description: Display properly sized, smart cropped and optimized images on your website. Images are processed on the fly and served from our CDN. 6 * Version: 3.1 0.56 * Version: 3.11.0 7 7 * Author: ShortPixel 8 8 * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-adaptive-images … … 16 16 17 17 if ( !class_exists( 'ShortPixelAI' ) ) { 18 define( 'SHORTPIXEL_AI_VERSION', '3.1 0.5' );18 define( 'SHORTPIXEL_AI_VERSION', '3.11.0' ); 19 19 define( 'SPAI_SNIP_VERSION', '3.1.0' ); 20 20 define( 'SHORTPIXEL_AI_VANILLAJS_VER', '1.1' ); … … 103 103 $old_error_handler = set_error_handler( [ 'ShortPixelAILogger', 'errorHandler' ] ); 104 104 } 105 function activatedTimeCollect(){ 106 update_option('shortpixel_ai_installed_time', time()); 107 } 105 108 106 109 register_activation_hook( __FILE__, [ 'ShortPixelAI', 'activate' ] ); … … 112 115 ShortPixelAI::_(); 113 116 } ); 114 } 117 118 }
Note: See TracChangeset
for help on using the changeset viewer.