.svgWrapper { background: #81b441; border-radius: 3px; display: inline-block; padding: 6px 7px; } .svgEnvatoLogo { position: relative; top: 2px; width: 14px; height: 14px; } import { store as coreDataStore } from '@wordpress/core-data'; import { dispatch, useSelect } from '@wordpress/data'; const useStorage = () => { const save = async ( data ) => { try { return await dispatch( coreDataStore ).saveEntityRecord( 'root', 'site', data ); } catch ( error ) { console.error( 'Storage save error:', error ); return Promise.resolve(); } }; // Fetch site data with useSelect and check resolution status const get = useSelect( ( select ) => { try { const coreDataSelect = select( coreDataStore ); if ( ! coreDataSelect ) { return { data: { image_optimizer_review_data: {} }, hasFinishedResolution: true, }; } return { data: coreDataSelect.getEntityRecord( 'root', 'site' ) || { image_optimizer_review_data: {} }, hasFinishedResolution: coreDataSelect.hasFinishedResolution( 'getEntityRecord', [ 'root', 'site' ] ), }; } catch ( error ) { console.error( 'Storage get error:', error ); return { data: { image_optimizer_review_data: {} }, hasFinishedResolution: true, }; } }, [], ); return { save, get, }; }; export default useStorage; .base-modal__header[data-v-330ecf55]{margin-bottom:8px;margin-top:-4px;position:relative}.base-modal__title-container[data-v-330ecf55]{align-items:center;display:flex;justify-content:flex-start}.base-modal__title-container--centered[data-v-330ecf55]{justify-content:center}.base-modal__title[data-v-330ecf55]{color:var(--neutral--700);font-size:20px;font-weight:700;margin:0}.base-modal__subtitle[data-v-330ecf55]{color:var(--neutral--500);font-size:14px;margin-bottom:24px;margin-top:4px}.base-modal__subtitle--centered[data-v-330ecf55]{text-align:center}.confirm-disconnect-modal[data-v-8166ef46]{margin-top:24px}.confirm-disconnect-modal__icon[data-v-8166ef46]{margin-right:12px}.confirm-disconnect-modal__content[data-v-8166ef46]{align-items:center;display:flex;flex-direction:column;gap:20px;margin-bottom:24px}.confirm-disconnect-modal__footer[data-v-8166ef46]{display:flex;gap:8px;justify-content:flex-end}@media(max-width:640px){.confirm-disconnect-modal__footer[data-v-8166ef46]{flex-direction:column-reverse;gap:12px}.confirm-disconnect-modal__footer[data-v-8166ef46] .h-button{width:100%}}/** * Floating element positioning - smart sticky placement for toolbar + action bar * * Exposes: SFE.PositionManager * { positionFloatingElements, debouncedPosition, schedulePosition } */ (function() { 'use strict'; window.MWP = window.MWP || {}; window.MWP.SFE = window.MWP.SFE || {}; const SFE = window.MWP.SFE; SFE.ManagerData = SFE.ManagerData || {}; /** * Reusable smart positioning logic */ function positionFloatingElements(element, toolbar, actions, skipTransitionControl = false) { const actionsEl = (actions && actions._isDocked) ? null : actions; const toolbarEl = toolbar; if (!toolbarEl && !actionsEl) return; const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const PADDING = 8; const GAP = 8; // Gap between element and bars const rect = element.getBoundingClientRect(); // Safety check: If the element is currently "invisible" or 0,0 during replacement if (rect.top === 0 && rect.left === 0 && rect.width === 0) { return; // Don't move the bars to 0,0 } // Disable position transitions during scroll (keep size transitions). // Skip if the element has a live state-change transition in progress - // the _markTransitioning() guard in ActionBar sets this flag. if (!skipTransitionControl) { if (toolbarEl && !toolbarEl._isStateTransitioning) toolbarEl.classList.add('mwp-sfe-no-position-transition'); if (actionsEl && !actionsEl._isStateTransitioning) actionsEl.classList.add('mwp-sfe-no-position-transition'); } function applyPos(el, isToolbar) { if (!el) return { top: 0, height: 0 }; // Don't override a docked action bar's fixed position. if (el._isDocked) return { top: 0, height: 0 }; // Ensure element is visible for measurement const originalDisplay = el.style.display; const isHidden = getComputedStyle(el).display === 'none'; if (isHidden) { el.style.display = 'flex'; el.style.visibility = 'hidden'; } // Measurement reset el.style.position = 'absolute'; if (isToolbar) { el.style.top = '0'; // Reset top so it doesn't affect scroll height el.style.left = '0'; // Move to far left to give it maximum "runway" } el.style.right = ''; el.style.width = ''; // Calculate current available viewport room const maxAvailableWidth = viewportWidth - (PADDING * 2); el.style.maxWidth = maxAvailableWidth + 'px'; el.style.boxSizing = 'border-box'; // Force reflow to commit any pending class changes (e.g. removal of // mwp-sfe-no-position-transition) before the final top/left are written. void el.offsetHeight; const elWidth = el.offsetWidth; const elHeight = el.offsetHeight; // Ideal Left (Left-aligned with element) const elementLeft = rect.left + scrollLeft; const elementRight = rect.right + scrollLeft; const viewportRightEdge = scrollLeft + viewportWidth - PADDING; const minLeft = scrollLeft + PADDING; const maxLeft = viewportRightEdge - elWidth; let elLeft = elementLeft; // 1. Try left-aligning with the element // 2. If it overflows the right viewport edge, try right-aligning with the element if (elLeft > maxLeft) { elLeft = elementRight - elWidth; } // 3. Clamp to the left edge of the viewport if we've pushed too far left if (elLeft < minLeft) { elLeft = minLeft; } // 4. FINAL SAFETY CLAMP: Ensure the right side NEVER exceeds the viewport edge. // This handles cases where the element is very wide or the zoom is high. if (elLeft > maxLeft) { elLeft = maxLeft; } el.style.left = elLeft + 'px'; // Calculate vertical position with sticky behavior let elTop; if (isToolbar) { // Toolbar: default position is above the element const defaultTop = rect.top + scrollTop - elHeight - GAP; const elementTopInViewport = rect.top; const elementBottomInViewport = rect.bottom; const toolbarTopInViewport = elementTopInViewport - elHeight - GAP; // Check if toolbar would be above viewport if (toolbarTopInViewport >= PADDING) { // Toolbar fits above element - use default position elTop = defaultTop; } else if (elementBottomInViewport > elHeight + PADDING + GAP) { // Element top is above viewport but bottom is still visible // And there's room for toolbar in viewport // Stick to top of viewport elTop = scrollTop + PADDING; } else { // Element is mostly or completely above viewport - anchor to bottom of element. // Using defaultTop (element top) here puts the toolbar far above the visible // area when rect.top is deeply negative. Anchoring to rect.bottom instead // keeps the toolbar just above the element's last visible edge, mirroring // how the action bar anchors to rect.top when the element is below viewport. elTop = rect.bottom + scrollTop - elHeight - GAP; } } else { // Action bar: default position is below the element const defaultTop = rect.bottom + scrollTop + GAP; const elementBottomInViewport = rect.bottom; const elementTopInViewport = rect.top; const actionBarBottomInViewport = elementBottomInViewport + GAP + elHeight; // Check if action bar bottom would be below viewport if (actionBarBottomInViewport <= viewportHeight - PADDING) { // Action bar fits below element - use default position elTop = defaultTop; } else if (elementTopInViewport < viewportHeight - elHeight - PADDING - GAP) { // Element bottom is below viewport but top is still visible // And there's room for action bar in viewport // Stick to bottom of viewport elTop = scrollTop + viewportHeight - elHeight - PADDING; } else { // Element is mostly or completely below viewport - move with element elTop = rect.top + scrollTop + PADDING; } } el.style.top = elTop + 'px'; // Restore visibility/display if (isHidden) { el.style.display = originalDisplay; el.style.visibility = ''; } return { top: elTop, height: elHeight }; } // Apply positions and get their calculated positions const toolbarPos = applyPos(toolbarEl, true); const actionsPos = applyPos(actionsEl, false); // Collision detection - prevent toolbar and action bar from overlapping if (toolbarEl && actionsEl) { const toolbarBottom = toolbarPos.top + toolbarPos.height; const actionsTop = actionsPos.top; const collision = toolbarBottom + GAP > actionsTop; if (collision) { // They're colliding - determine which one moves const elementTopInViewport = rect.top; const elementBottomInViewport = rect.bottom; const elementCenterInViewport = (elementTopInViewport + elementBottomInViewport) / 2; const viewportCenter = viewportHeight / 2; // If element center is in lower half of viewport, move action bar down with toolbar // If element center is in upper half, move toolbar up with action bar if (elementCenterInViewport > viewportCenter) { // Move action bar down to be below toolbar const newActionsTop = toolbarBottom + GAP; actionsEl.style.top = newActionsTop + 'px'; } else { // Move toolbar up to be above action bar const newToolbarTop = actionsTop - toolbarPos.height - GAP; toolbarEl.style.top = newToolbarTop + 'px'; } } } } /** * rAF-scheduled position updater (1 per frame) */ function createRafScheduler(fn) { let rafId = null; const queue = []; return function scheduledPosition(...args) { queue.push(args); if (rafId) return; rafId = requestAnimationFrame(() => { rafId = null; const batch = queue.splice(0, queue.length); batch.forEach(callArgs => fn(...callArgs)); }); }; } const schedulePosition = createRafScheduler(positionFloatingElements); const debouncedPosition = schedulePosition; SFE.PositionManager = { positionFloatingElements, debouncedPosition, schedulePosition }; })(); Page not found – Deshwal Foundation

Join our Donating Program — For a social cause that brings lasting change. 🤍 Become a supporter today.

Join our Donating Program — For a social cause that brings lasting change. 🤍 Become a supporter today.

404

That page can't be found

Sorry, the page you’re looking for isn’t here. It may have been removed, had its name changed, or is temporarily unavailable. Please double-check the URL, try searching again, or head back to the homepage. We’ll do our best to guide you where you need to go.

Your cart is empty!

No items in your cart. Let’s fill it with something amazing!