/*! elementor-pro - v3.30.0 - 22-07-2025 */ (()=>{var e={40:(e,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.replaceUtmPlaceholders=r.htmlDecodeTextContent=r.arrayToClassName=void 0;r.arrayToClassName=(e,r)=>e.filter((e=>"object"==typeof e?Object.entries(e)[0][1]:e)).map((e=>{const n="object"==typeof e?Object.entries(e)[0][0]:e;return r?r(n):n})).join(" ");r.htmlDecodeTextContent=e=>(new DOMParser).parseFromString(e,"text/html").documentElement.textContent;r.replaceUtmPlaceholders=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e&&r?(Object.keys(r).forEach((n=>{const o=new RegExp(`%%${n}%%`,"g");e=e.replace(o,r[n])})),e):e}},3842:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956),u=i(n(7971));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const App=e=>{const[r,n]=(0,a.useState)(!0);(0,a.useEffect)((()=>{if(!r){const r=setTimeout((()=>{e.onClose()}),500);return()=>clearTimeout(r)}}),[r]);return a.default.createElement(s.DirectionProvider,{rtl:e.isRTL},a.default.createElement(s.LocalizationProvider,null,a.default.createElement(s.ThemeProvider,{colorScheme:e.colorScheme},a.default.createElement(s.Dialog,{open:r,fullWidth:!0,maxWidth:"lg",TransitionComponent:s.Fade,transitionDuration:{enter:500,exit:500},sx:{"& .MuiDialog-paper":{height:"calc(100vh - 4rem)",maxHeight:775}}},a.default.createElement(u.default,{getControlValue:e.getControlValue,setControlValue:e.setControlValue,fetchData:e.fetchData,onClose:()=>{n(!1)},conditionsConfig:e.conditionsConfig,setCacheNoticeStatus:e.setCacheNoticeStatus})))))};App.propTypes={colorScheme:o.oneOf(["auto","light","dark"]),isRTL:o.bool,getControlValue:o.func.isRequired,setControlValue:o.func.isRequired,fetchData:o.func.isRequired,onClose:o.func.isRequired,conditionsConfig:o.object.isRequired,setCacheNoticeStatus:o.func.isRequired};r.default=App},19:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=i(n(3842));class DisplayConditionsBehavior extends Marionette.Behavior{ui(){const e=".eicon-flow.e-control-display-conditions";return{displayConditionsButton:e,displayConditionsPromoButton:`${e}-promo`}}events(){return{"click @ui.displayConditionsButton":"onClickControlButtonDisplayConditions","mouseenter @ui.displayConditionsPromoButton":"onHoverControlButtonDisplayConditions"}}onClickControlButtonDisplayConditions(e){e.stopPropagation(),this.mount()}onHoverControlButtonDisplayConditions(e){e.stopPropagation(),elementor.promotion.showDialog({title:o("Display Conditions","elementor-pro"),content:o("Upgrade to Elementor Pro Advanced to get the Display Conditions feature as well as additional professional and ecommerce widgets","elementor-pro"),targetElement:this.el,actionButton:{url:"https://go.elementor.com/go-pro-advanced-display-conditions/",text:o("Upgrade Now","elementor-pro"),classes:["elementor-button","go-pro"]}})}getRootElement(){let e=window.parent.document.getElementById("elementor-conditions__modal");return e||(e=document.createElement("div"),e.setAttribute("id","elementor-conditions__modal"),e)}mount(){const e=elementor?.getPreferences?.("ui_theme")||"auto",r=elementorCommon.config.isRTL,n=this.getRootElement();window.parent.document.body.appendChild(n),ReactDOM.render(a.default.createElement(s.default,{colorScheme:e,isRTL:r,getControlValue:this.getOption("getControlValue"),setControlValue:this.getOption("setControlValue"),fetchData:this.getOption("fetchData"),onClose:()=>this.unmount(n),conditionsConfig:this.getOption("conditionsConfig"),setCacheNoticeStatus:this.getOption("setCacheNoticeStatus")}),n)}unmount(e){ReactDOM.unmountComponentAtNode(e),e.remove()}}r.default=DisplayConditionsBehavior},5305:(e,r,n)=>{"use strict";var o=n(2688);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),a=n(2470),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const CacheNotice=e=>{let{setCacheNoticeStatus:r}=e;const[n,o]=(0,i.useState)(!0);return i.default.createElement(s.Box,null,i.default.createElement(s.Collapse,{in:n,sx:{px:3}},i.default.createElement(s.Alert,{color:"info",severity:"error",variant:"standard",onClose:async()=>{await r()&&o(!1)},sx:{mt:3}},(0,a.__)("Keep in mind: Certain cache plugins can conflict with your display conditions. ","elementor-pro"),i.default.createElement(s.Link,{href:"https://go.elementor.com/app-display-conditions-cache-notice/",underline:"hover",color:"info.main",target:"_blank",sx:{"&:hover":{color:e=>e.palette.info.main}}},(0,a.__)("Learn more","elementor-pro")))))};CacheNotice.propTypes={setCacheNoticeStatus:o.func.isRequired};r.default=CacheNotice},7946:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=_interopRequireWildcard(n(2688)),s=o(n(7976)),u=n(6956),c=o(n(7459)),f=o(n(6794)),p=o(n(678)),g=o(n(248)),C=n(3726),v=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const ConditionsRepeaterRow=e=>{let{andConditionIndex:r,orConditionIndex:n}=e;const{selectedConditions:o,conditionsConfig:a,dispatch:_}=(0,s.default)(),{conditions:b,flattenedConditionOptions:x}=a,E=o[n][r],R=E?.condition,w=b[R]?.controls||{},P=Object.keys(w).length;return i.createElement(u.Container,{maxWidth:"md",sx:{display:"flex",gap:.5,mb:1,position:"relative"},className:`and-condition-repeater-row and-condition-${r}`},i.createElement(f.default,{id:"condition-select",value:E.condition||"",onChange:e=>(e=>{const o=e.target.value,i={condition:o,...(0,C.getConditionInitialState)(b,o)};_({type:v.ACTION_TYPES.CHANGE_CONDITION_TYPE,orConditionIndex:n,andConditionIndex:r,conditionToChange:i})})(e),controlCount:P},x.map((e=>{let{key:r,label:n,isGroup:o}=e;return o?i.createElement(u.ListSubheader,{key:r},i.createElement(p.default,{variant:"caption",controlCount:P},n)):i.createElement(u.MenuItem,{key:r,value:r},i.createElement(p.default,{controlCount:P},n))}))),Object.keys(w).map((e=>i.createElement(c.default,{key:e,controlKey:e,andConditionIndex:r,orConditionIndex:n,controlCount:P}))),i.createElement(g.default,{orConditionIndex:n,andConditionIndex:r}))};ConditionsRepeaterRow.propTypes={andConditionIndex:a.number.isRequired,orConditionIndex:a.number.isRequired};r.default=ConditionsRepeaterRow},5213:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=i(n(7976)),u=n(6956),c=i(n(7946));const ConditionsSelectors=e=>{let{orConditionIndex:r}=e;const{selectedConditions:n}=(0,s.default)(),o=n[r];return a.default.createElement(u.Box,{sx:{my:2,gap:1},className:`or-condition-repeater or-condition-${r}`},o.map(((e,n)=>a.default.createElement(c.default,{key:"or-condition-row-"+n,andConditionIndex:n,orConditionIndex:r}))))};ConditionsSelectors.propTypes={orConditionIndex:o.number.isRequired};r.default=ConditionsSelectors},2822:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956),u=i(n(7432)),c=i(n(174));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}r.default=e=>a.createElement(s.Box,{display:"flex",justifyContent:"center",alignItems:"flex-start",sx:{flex:1,overflow:"auto"}},a.createElement(s.Stack,{maxWidth:"md",width:"100%",justifyContent:"center",textAlign:"center",sx:{pt:5,pb:10,px:6}},a.createElement(u.default,{fontSize:"large",sx:{mb:1,mx:"auto"}}),a.createElement(s.Typography,{component:"h6",variant:"h6",color:"text.primary"},o("Set one or more conditions for this element","elementor-pro")),a.createElement(s.Typography,{variant:"body2",color:"text.tertiary",sx:{mb:4}},o("It will only appear on your website when all the conditions are met.","elementor-pro")," ",a.createElement(s.Link,{href:"https://go.elementor.com/app-display-conditions/",target:"_blank",rel:"noreferrer",color:"info.main",underline:"hover",sx:{"&:hover":{color:e=>e.palette.info.main}}},o("Learn more","elementor-pro"))),a.createElement(c.default,e)))},7971:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(4372),u=n(9148),c=n(6956),f=n(3726),p=i(n(1677)),g=i(n(799)),C=i(n(2822)),v=i(n(5305)),_=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Content=e=>{let{getControlValue:r,setControlValue:n,conditionsConfig:o,onClose:i,fetchData:b,setCacheNoticeStatus:x}=e;const E=r(),R={conditionsConfig:o,selectedConditions:E||[],fetchData:b},[w,P]=a.default.useState(!0),[j,T]=(0,a.useReducer)(s.conditionsReducer,R),[I,W]=(0,a.useState)(!1),{selectedConditions:q}=j;(0,a.useEffect)((()=>{I||W(!0)}),[q]),(0,a.useEffect)((()=>{W(!1)}),[]);const handleEmptyFieldsPerConditionSet=(e,r)=>{let n=!1,o=null;return e.forEach(((e,i)=>{const{condition:a}=e,s=getRequiredControlKeys(a);handleInvalidRequiredKeysPerCondition({requiredKeys:s,andCondition:e,orConditionIndex:r,andConditionIndex:i})&&!n&&(o=i,n=!0)})),{hasFoundInvalidConditionInConditionSet:n,invalidAndConditionIndex:o}},handleInvalidRequiredKeysPerCondition=e=>{let{requiredKeys:r,andCondition:n,orConditionIndex:i,andConditionIndex:a}=e;const{condition:s}=n;let u=!1;return r.forEach((e=>{const r=n[e],{type:c,variant:p=null}=o.conditions[s].controls[e];r?.length||(0,f.shouldEmptyValuePassValidation)(n.condition,n.comparator)||(u||(u=!0),T({type:_.ACTION_TYPES.SET_ERRORS,andConditionIndex:a,orConditionIndex:i,errors:{[e]:(0,f.getInvalidInputFeedback)(c,p,r,!0)}}))})),u},handleSave=()=>{const{hasFoundInvalidCondition:e,invalidOrConditionIndex:r,invalidAndConditionIndex:o}=(()=>{let e=!1,r=null,n=null;return q.forEach(((o,i)=>{const{hasFoundInvalidConditionInConditionSet:a,invalidAndConditionIndex:s}=handleEmptyFieldsPerConditionSet(o,i);a&&!e&&(e=!0,n=s,r=i)})),{hasFoundInvalidCondition:e,invalidOrConditionIndex:r,invalidAndConditionIndex:n}})();if(e){const e=`.or-condition-repeater.or-condition-${r} .and-condition-repeater-row.and-condition-${o}`,n=document.querySelector(e);setTimeout((()=>n?.scrollIntoView({behavior:"smooth"})),100)}else n([JSON.stringify(getSanitizedConditions())]),i()},getRequiredControlKeys=e=>{const{controls:r}=o.conditions[e];return Object.keys(r).filter((e=>r[e].required))},getSanitizedConditions=()=>q.map((e=>e.map((e=>{const r={...e};return delete r.errors,r}))));return a.default.createElement(a.default.Fragment,null,a.default.createElement(p.default,{onClose:i}),a.default.createElement(c.Divider,{orientation:"horizontal"}),o.show_cache_notice&&a.default.createElement(v.default,{setCacheNoticeStatus:x}),a.default.createElement(u.ConditionsContext.Provider,{value:{dispatch:T,...j}},a.default.createElement(C.default,{showConditions:w,setShowConditions:P})),a.default.createElement(c.Divider,{orientation:"horizontal"}),a.default.createElement(g.default,{onClickSaveButton:()=>handleSave(),showConditions:w,setShowConditions:P,isButtonDisabled:I}))};Content.propTypes={getControlValue:o.func.isRequired,setControlValue:o.func.isRequired,fetchData:o.func.isRequired,onClose:o.func.isRequired,conditionsConfig:o.object.isRequired,setCacheNoticeStatus:o.func.isRequired};r.default=Content},7459:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=_interopRequireWildcard(n(2688)),s=o(n(7976)),u=o(n(4565)),c=o(n(6373)),f=o(n(6929)),p=o(n(5523)),g=o(n(6936)),C=o(n(6987)),v=n(4934),_=n(3726);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const ControlRenderer=e=>{let{controlKey:r,andConditionIndex:n,orConditionIndex:o,controlCount:a}=e;const{conditionsConfig:b,selectedConditions:x,dispatch:E}=(0,s.default)(),{conditions:R}=b,w=x[o][n],P=w.condition,{controls:j={}}=R[P],T=({}=j[r]),{options:I={}}=T;if("__settings"===r)return null;const extractControlPropsFromGlobals=e=>{const o=getControlValueRelatedProps(e),i=getControlInvalidInputRelatedProps(),s={controlKey:r,control:T,conditionIndex:n,condition:w,conditions:R,options:I,onChangeOption:handleChangeOption,controlCount:a};return(0,_.shouldDisableControl)(r,s.condition.comparator)&&(s.disabled=!0),{...o,...i,...s}},getControlValueRelatedProps=e=>{e=(0,_.getControlValue)(e,v.DEFAULT_CONTROL_VALUES[T.type]);const n=(0,_.getControlValue)(T?.default,Object.keys(I)[0]||e);return{defaultValue:n,value:(0,_.getControlValue)(w[r],n),placeholder:T?.placeholder||"",isMultiple:T?.multiple||!1}},getControlInvalidInputRelatedProps=()=>{const e=(w.errors||{})[r]||{},n=e.shouldShow&&e.message||"";return{errorMessage:n,shouldShowError:Boolean(n)}},handleChangeOption=e=>{const{type:i,variant:a}=j[r],s=(0,_.getInvalidInputFeedback)(i,a,e);E({type:v.ACTION_TYPES.CHANGE_CONTROL_VALUE,orConditionIndex:o,andConditionIndex:n,controlKey:r,value:e}),E({type:v.ACTION_TYPES.SET_ERRORS,andConditionIndex:n,orConditionIndex:o,errors:{[r]:s}})};switch(T.type){case v.CONTROL_TYPES.SELECT:return i.createElement(u.default,extractControlPropsFromGlobals());case v.CONTROL_TYPES.MULTIPLE_SELECT:return i.createElement(c.default,extractControlPropsFromGlobals());case v.CONTROL_TYPES.DATE_TIME:return(e=>{switch(e){case"date":return i.createElement(g.default,extractControlPropsFromGlobals());case"time":return i.createElement(C.default,extractControlPropsFromGlobals())}})(T?.variant);case v.CONTROL_TYPES.QUERY:return i.createElement(f.default,extractControlPropsFromGlobals())}return i.createElement(p.default,extractControlPropsFromGlobals())};ControlRenderer.propTypes={controlKey:a.string.isRequired,andConditionIndex:a.number.isRequired,orConditionIndex:a.number.isRequired,controlCount:a.number.isRequired};r.default=ControlRenderer},6373:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=_interopRequireWildcard(n(1594)),s=a,u=_interopRequireWildcard(n(2688)),c=n(6956),f=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const formatValue=e=>Array.isArray(e)?e:[e],AutocompleteControl=e=>{let{conditions:r,condition:n,controlKey:o,onChangeOption:u,options:p,value:g,shouldShowError:C,errorMessage:v,isMultiple:_,controlCount:b}=e;const[x,E]=(0,a.useState)(formatValue(g)),R=x?.length?"":r[n.condition].label||"";(0,a.useEffect)((()=>{E(formatValue(g))}),[n]);return s.createElement(c.Autocomplete,{multiple:_,id:`select-${o}`,value:x,options:Object.keys(p),getOptionLabel:e=>p[e],sx:{flex:1},ChipProps:{sx:{"&.MuiAutocomplete-tag":{maxWidth:"100px"}}},renderInput:e=>s.createElement(c.TextField,(0,i.default)({error:C,helperText:v},e,{placeholder:R,color:"secondary"})),ListboxProps:{sx:{maxHeight:280}},size:"small",onChange:(e,r)=>{return n=formatValue(r),u(n),void E(n);var n},renderOption:(e,r)=>s.createElement(c.Typography,(0,i.default)({component:"li"},e),s.createElement(f.default,{component:"span",variant:"inherit",noWrap:!0,controlCount:b},p[r])),forcePopupIcon:!Object.keys(p).length<=1})};AutocompleteControl.propTypes={conditions:u.object.isRequired,condition:u.object.isRequired,controlKey:u.string.isRequired,onChangeOption:u.func.isRequired,value:u.array.isRequired,options:u.object.isRequired,errorMessage:u.string.isRequired,shouldShowError:u.bool.isRequired,isMultiple:u.bool.isRequired,optionsStyles:u.object.isRequired,menuStyles:u.object.isRequired,controlCount:u.number.isRequired};r.default=AutocompleteControl},6936:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(5285));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const f="MM-DD-YYYY",formattedValue=e=>(0,c.default)(e,f,!0).isValid()?(0,c.default)(e,f):null,DatePickerControl=e=>{let{condition:r,onChangeOption:n,controlKey:o,value:s,shouldShowError:p,errorMessage:g}=e;const[C,v]=(0,i.useState)(formattedValue(s));(0,i.useEffect)((()=>{v(formattedValue(s))}),[r]);return a.createElement(u.DatePicker,{value:C,sx:{flex:1},id:`select-${o}`,slotProps:{openPickerButton:{size:"small"},textField:{size:"small",color:"secondary",error:p,helperText:g}},onChange:e=>(e=>{(0,c.default)(e,f,!0).isValid()?(n(e.format(f)),v(formattedValue(e))):n("")})(e)})};DatePickerControl.propTypes={condition:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,value:s.string,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired};r.default=DatePickerControl},6929:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=o(n(8304)),s=_interopRequireWildcard(n(2688)),u=n(2470),c=n(9148),f=n(6956),p=n(40),g=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const formatValue=e=>Array.isArray(e)?e:[e],QueryControl=e=>{let{conditions:r,condition:n,control:o,controlKey:s,onChangeOption:C,value:v,shouldShowError:_,errorMessage:b,isMultiple:x,controlCount:E}=e;const{fetchData:R}=(0,i.useContext)(c.ConditionsContext),[w,P]=(0,i.useState)(formatValue(v)),[j,T]=(0,i.useState)([]),[I,W]=(0,i.useState)(!1),q=w?.length?"":r[n.condition].label||"";(0,i.useEffect)((()=>{P(formatValue(v))}),[n]);return i.default.createElement(f.Autocomplete,{multiple:x,id:`select-${s}`,value:w,options:j,getOptionLabel:e=>e?e.text:"",isOptionEqualToValue:(e,r)=>e.id===r.id,filterOptions:e=>e,noOptionsText:(0,u.__)("No results","elementor-pro"),loading:I,loadingText:(0,u.__)("Searching...","elementor-pro"),size:"small",sx:{flex:1},ChipProps:{sx:{"&.MuiAutocomplete-tag":{maxWidth:"100px"}}},renderInput:e=>i.default.createElement(f.TextField,(0,a.default)({},e,{placeholder:q,color:"secondary",error:_,helperText:b,InputProps:{...e.InputProps,endAdornment:i.default.createElement(i.default.Fragment,null,I?i.default.createElement(f.CircularProgress,{color:"inherit",size:20}):null,e.InputProps.endAdornment)}})),ListboxProps:{sx:{maxHeight:280}},onChange:(e,r)=>{return C(n=r),void P(n);var n},onInputChange:(e,r)=>(async(e,r,n)=>{if(""===r)return void T([]);W(!0);const i=(await R(r,o)).filter((e=>(e.text=(0,p.htmlDecodeTextContent)(e.text),!n.some((r=>r?.id===e?.id)))));T(i),W(!1)})(0,r,w),renderOption:(e,r)=>i.default.createElement(f.Typography,(0,a.default)({component:"li"},e),i.default.createElement(g.default,{component:"span",variant:"inherit",noWrap:!0,controlCount:E},r.text))})};QueryControl.propTypes={conditions:s.object.isRequired,condition:s.object.isRequired,onChangeOption:s.func.isRequired,controlKey:s.string.isRequired,control:s.object.isRequired,value:s.array.isRequired,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired,isMultiple:s.bool.isRequired,controlCount:s.number.isRequired};r.default=QueryControl},4565:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(6794)),f=o(n(678));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const SelectControl=e=>{let{condition:r,control:n,controlKey:o,onChangeOption:s,options:p,value:g,controlCount:C}=e;const[v,_]=(0,i.useState)(g);(0,i.useEffect)((()=>{_(g)}),[r]);return a.createElement(c.default,{id:`select-${o}`,value:v,onChange:e=>{return r=e.target.value,s(r),void _(r);var r},disabled:Object.keys(p).length<=1,controlCount:C},Object.entries(p).map((e=>{let[r,o]=e;if(!o)return null;if("group"===o.type)return a.createElement(u.ListSubheader,{key:r},a.createElement(f.default,{controlCount:C},o.label));const i=n?.disabled_options?.includes(r);return a.createElement(u.MenuItem,{key:r,value:r,disabled:i,className:i&&"hidden"===n?.disabled_type?"elementor-hidden":""},a.createElement(f.default,{controlCount:C},o))})))};SelectControl.propTypes={condition:s.object.isRequired,control:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,options:s.object.isRequired,value:s.string.isRequired,controlCount:s.number.isRequired};r.default=SelectControl},5523:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=_interopRequireWildcard(n(1594)),s=a,u=_interopRequireWildcard(n(2688)),c=n(6956),f=n(3726);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const TextFieldControl=e=>{let{condition:r,controlKey:n,control:o,onChangeOption:u,value:p,errorMessage:g,shouldShowError:C,placeholder:v,disabled:_}=e;const[b,x]=(0,a.useState)(p),{step:E=1,min:R=0,variant:w=null}=o,P="number"===w?{type:"number",inputProps:{step:E,min:R}}:{};(0,a.useEffect)((()=>{x(p)}),[r]);return s.createElement(c.TextField,(0,i.default)({},P,{sx:{flex:1},error:C,helperText:g,value:b,id:`text-${n}`,variant:"outlined",onChange:e=>((e,r)=>{let n=null;"number"===r&&(0,f.hasDecimalSeparator)(e)&&(n=Math.floor(parseFloat(e))),u(n??e.trim()),x(n??e)})(e.target.value,w),size:"small",color:"secondary",placeholder:v,disabled:_??!1}))};TextFieldControl.propTypes={condition:u.object.isRequired,controlKey:u.string.isRequired,control:u.object.isRequired,onChangeOption:u.func.isRequired,value:u.oneOfType([u.string,u.number]).isRequired,errorMessage:u.string.isRequired,shouldShowError:u.bool.isRequired,placeholder:u.string.isRequired,disabled:u.bool};r.default=TextFieldControl},6987:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=_interopRequireWildcard(n(1594)),a=i,s=_interopRequireWildcard(n(2688)),u=n(6956),c=o(n(5285));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}const f="HH:mm",p="MM-DD-YYYY "+f,TimePickerControl=e=>{let{condition:r,controlKey:n,onChangeOption:o,value:s,shouldShowError:g,errorMessage:C}=e;const v=(0,i.useRef)((x=s,(0,c.default)(x,f,!0).isValid()?(0,c.default)(x,f):null)),[_,b]=(0,i.useState)(v.current);var x;(0,i.useEffect)((()=>{b(v.current)}),[r]);return a.createElement(u.TimePicker,{sx:{flex:1},id:`select-${n}`,value:_,slotProps:{textField:{size:"small",error:g,helperText:C}},onChange:e=>(e=>{const r=(0,c.default)(e,p,!0).isValid()?e.format(p):"";o(r),v.current=e,b(e)})(e)})};TimePickerControl.propTypes={condition:s.object.isRequired,control:s.object.isRequired,controlKey:s.string.isRequired,onChangeOption:s.func.isRequired,value:s.string,errorMessage:s.string.isRequired,shouldShowError:s.bool.isRequired};r.default=TimePickerControl},6794:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=o(n(8304)),s=n(6956),u=n(3726),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const ConditionSelect=e=>{let{controlCount:r,...n}=e;return i.default.createElement(s.Select,(0,a.default)({},n,{size:"small",sx:{flex:1,textAlign:"start",alignSelf:"flex-start",".MuiSelect-select .MuiTypography-root":{maxWidth:(0,u.getControlValueMaxWidth)(r)}},color:"secondary",MenuProps:{PaperProps:{sx:{maxHeight:280,"& .MuiListSubheader-root":{position:"initial"}}},classes:{paper:"e-conditions-select-menu"}}}))};ConditionSelect.propTypes={controlCount:c.number.isRequired};r.default=ConditionSelect},678:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=o(n(8304)),s=n(6956),u=n(3726),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const ConditionSelectOption=e=>{let{controlCount:r,sx:n={},...o}=e;return i.default.createElement(s.Typography,(0,a.default)({noWrap:!0},o,{variant:o.variant||"inherit",sx:{maxWidth:(0,u.getSelectOptionMaxWidth)(r),...n}}))};ConditionSelectOption.propTypes={sx:c.object,isDropdownItem:c.bool,variant:c.string,controlCount:c.number.isRequired};r.default=ConditionSelectOption},799:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(2688);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Footer=e=>{let{onClickSaveButton:r,isButtonDisabled:n}=e;return a.createElement(s.Stack,{direction:"row",justifyContent:"flex-end",sx:{py:1,px:3}},a.createElement(s.Button,{variant:"contained",className:"save-and-close-button",disabled:!n,onClick:r},o("Save & Close","elementor-pro")))};Footer.propTypes={onClickSaveButton:i.func,isButtonDisabled:i.bool.isRequired};r.default=Footer},1677:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(1594)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(2688)),s=n(2470),u=n(6956),c=o(n(4448)),f=n(4048);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const Header=e=>{let{onClose:r}=e;return i.default.createElement(u.AppBar,{sx:{fontWeight:"normal"},color:"transparent",position:"relative"},i.default.createElement(u.Toolbar,{variant:"dense"},i.default.createElement(c.default,{sx:{mr:1}}),i.default.createElement(u.Typography,{component:"span",variant:"subtitle2",sx:{fontWeight:"bold",textTransform:"uppercase"}},(0,s.__)("Display Conditions","elementor-pro")),i.default.createElement(u.Stack,{direction:"row",spacing:1,alignItems:"center",sx:{ml:"auto"}},i.default.createElement(u.IconButton,{size:"small","aria-label":(0,s.__)("Close","elementor-pro"),onClick:r,sx:{"&.MuiButtonBase-root":{mr:-1}}},i.default.createElement(f.XIcon,null)))))};Header.propTypes={onClose:a.func.isRequired};r.default=Header},4448:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}r.default=e=>a.createElement(s.SvgIcon,(0,i.default)({viewBox:"0 0 32 32"},e),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.69648 24.8891C0.938383 22.2579 0 19.1645 0 16C0 11.7566 1.68571 7.68687 4.68629 4.68629C7.68687 1.68571 11.7566 0 16 0C19.1645 0 22.2579 0.938383 24.8891 2.69648C27.5203 4.45459 29.5711 6.95344 30.7821 9.87706C31.9931 12.8007 32.3099 16.0177 31.6926 19.1214C31.0752 22.2251 29.5514 25.0761 27.3137 27.3137C25.0761 29.5514 22.2251 31.0752 19.1214 31.6926C16.0177 32.3099 12.8007 31.9931 9.87706 30.7821C6.95344 29.5711 4.45459 27.5203 2.69648 24.8891ZM12.0006 9.33281H9.33437V22.6665H12.0006V9.33281ZM22.6657 9.33281H14.6669V11.9991H22.6657V9.33281ZM22.6657 14.6654H14.6669V17.3316H22.6657V14.6654ZM22.6657 20.0003H14.6669V22.6665H22.6657V20.0003Z"}))},7432:(e,r,n)=>{"use strict";var o=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=o(n(8304)),a=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),s=n(6956);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const u=a.forwardRef(((e,r)=>a.createElement(s.SvgIcon,(0,i.default)({viewBox:"0 0 24 24"},e,{ref:r}),a.createElement("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M11 3.75C10.3096 3.75 9.75 4.30964 9.75 5V7C9.75 7.69036 10.3096 8.25 11 8.25H13C13.6904 8.25 14.25 7.69036 14.25 7V5C14.25 4.30964 13.6904 3.75 13 3.75H11ZM12.75 9.75H13C14.5188 9.75 15.75 8.51878 15.75 7V5C15.75 3.48122 14.5188 2.25 13 2.25H11C9.48122 2.25 8.25 3.48122 8.25 5V7C8.25 8.51878 9.48122 9.75 11 9.75H11.25V11.25H8C7.27065 11.25 6.57118 11.5397 6.05546 12.0555C5.53973 12.5712 5.25 13.2707 5.25 14V14.25H5C3.48122 14.25 2.25 15.4812 2.25 17V19C2.25 20.5188 3.48122 21.75 5 21.75H7C8.51878 21.75 9.75 20.5188 9.75 19V17C9.75 15.4812 8.51878 14.25 7 14.25H6.75V14C6.75 13.6685 6.8817 13.3505 7.11612 13.1161C7.35054 12.8817 7.66848 12.75 8 12.75H16C16.3315 12.75 16.6495 12.8817 16.8839 13.1161C17.1183 13.3505 17.25 13.6685 17.25 14V14.25H17C15.4812 14.25 14.25 15.4812 14.25 17V19C14.25 20.5188 15.4812 21.75 17 21.75H19C20.5188 21.75 21.75 20.5188 21.75 19V17C21.75 15.4812 20.5188 14.25 19 14.25H18.75V14C18.75 13.2707 18.4603 12.5712 17.9445 12.0555C17.4288 11.5397 16.7293 11.25 16 11.25H12.75V9.75ZM17 15.75C16.3096 15.75 15.75 16.3096 15.75 17V19C15.75 19.6904 16.3096 20.25 17 20.25H19C19.6904 20.25 20.25 19.6904 20.25 19V17C20.25 16.3096 19.6904 15.75 19 15.75H17ZM5 15.75C4.30964 15.75 3.75 16.3096 3.75 17V19C3.75 19.6904 4.30964 20.25 5 20.25H7C7.69036 20.25 8.25 19.6904 8.25 19V17C8.25 16.3096 7.69036 15.75 7 15.75H5Z"})))),c=(0,s.styled)(u)((e=>{let{theme:r}=e;return{"& path":{fill:r.palette.text.primary}}}));r.default=c},174:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(2688),a=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var s=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),u=n(6956),c=n(4048),f=a(n(5213)),p=a(n(7976)),g=n(3726),C=a(n(5513)),v=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const OrRowGroup=e=>{let{showConditions:r,setShowConditions:n}=e;const{selectedConditions:i,conditionsConfig:a,dispatch:_}=(0,p.default)(),{conditions:b,conditionsByGroup:x}=a,E=i.length?o("Add condition group","elementor-pro"):o("Add Condition","elementor-pro");return s.default.createElement(u.Box,null,r&&i.map(((e,r)=>s.default.createElement(s.Fragment,{key:r},r>0&&s.default.createElement(C.default,null),s.default.createElement(f.default,{orConditionIndex:r})))),s.default.createElement(u.Button,{variant:"contained",className:"add-or-condition-button",color:"secondary",startIcon:s.default.createElement(c.PlusIcon,null),sx:{mt:1,mb:5},onClick:()=>(()=>{const e=(0,g.getDefaultActiveCondition)(x),r={condition:e,...(0,g.getConditionInitialState)(b,e)};_({type:v.ACTION_TYPES.ADD_OR_CONDITION,andCondition:r}),n(!0)})()},E))};OrRowGroup.propTypes={showConditions:i.bool.isRequired,setShowConditions:i.func.isRequired};r.default=OrRowGroup},5513:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=i(n(1594)),s=n(6956);r.default=()=>a.default.createElement(s.Divider,{sx:{px:3}},o("OR","elementor-pro"))},248:(e,r,n)=>{"use strict";var o=n(2688),i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var a=n(6956),s=n(2470),u=n(4048),c=function _interopRequireWildcard(e,r){if(!r&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=_getRequireWildcardCache(r);if(n&&n.has(e))return n.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&{}.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(o,a,s):o[a]=e[a]}return o.default=e,n&&n.set(e,o),o}(n(1594)),f=n(3726),p=i(n(7976)),g=n(4934);function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var r=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:r})(e)}const RowControls=e=>{let{orConditionIndex:r,andConditionIndex:n}=e;const{conditionsConfig:o,dispatch:i}=(0,p.default)(),{conditions:C,conditionsByGroup:v}=o;return c.createElement(a.Stack,{direction:"row",alignItems:"center",sx:{left:"100%",gap:.5,ml:-1,mt:"2.5px",position:"absolute"}},c.createElement(a.Button,{color:"secondary",variant:"outlined",sx:{px:1,minWidth:"unset"},className:"add-single-condition-button",onClick:()=>{const e=(0,f.getDefaultActiveCondition)(v),o={condition:e,...(0,f.getConditionInitialState)(C,e)};i({type:g.ACTION_TYPES.ADD_AND_CONDITION,andCondition:o,andConditionIndex:n,orConditionIndex:r})}},(0,s.__)("AND","elementor-pro")),c.createElement(a.IconButton,{color:"secondary","aria-label":(0,s.__)("Delete","elementor-pro"),className:"remove-single-condition-button",onClick:()=>{i({type:g.ACTION_TYPES.REMOVE_AND_CONDITION,andConditionIndex:n,orConditionIndex:r})}},c.createElement(u.XIcon,{fontSize:"small"})))};RowControls.propTypes={andConditionIndex:o.number.isRequired,orConditionIndex:o.number.isRequired};r.default=RowControls},9148:(e,r,n)=>{"use strict";var o=n(1594);Object.defineProperty(r,"__esModule",{value:!0}),r.ConditionsContext=void 0;r.ConditionsContext=o.createContext()},7976:(e,r,n)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var o=n(1594),i=n(9148);r.default=function useConditions(){return(0,o.useContext)(i.ConditionsContext)}},9097:(e,r,n)=>{"use strict";var o=n(2470).__,i=n(6784);Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0,n(6281),n(5724);var a=i(n(19));class Module extends elementorModules.editor.utils.Module{pasteAction="paste";clearAction="clear";getDefaultSettings(){return{selectors:{icon:".eicon-flow.e-control-display-conditions"},controls:{displayConditions:"e_display_conditions",trigger:"e_display_conditions_trigger"}}}onElementorInit(){elementor.hooks.addFilter("controls/base/behaviors",this.registerControlBehavior),elementor.channels.editor.on("section:activated",this.highlightIconIfFilled),elementor.on("navigator:init",this.onNavigatorInit.bind(this));["widget","section","column","container"].forEach((e=>{elementor.hooks.addFilter(`elements/${e}/contextMenuGroups`,this.registerContextMenuGroups.bind(this))}))}onElementorInitComponents(){$e.commands.register("document/elements","paste-display-conditions",(e=>{this.tryContextMenuActions(e,this.pasteAction)})),$e.commands.register("document/elements","clear-display-conditions",(e=>{this.tryContextMenuActions(e,this.clearAction)}))}registerContextMenuGroups(e,r){const n=e.find((e=>"clipboard"===e.name));if(!n)return e;const i=n.actions.findIndex((e=>"pasteStyle"===e.name));return-1!==i&&n.actions.splice(i+1,0,{name:"pasteDisplayConditions",isEnabled:()=>this.isPasteDisplayConditionsEnabled(r),isVisible:()=>this.isPasteDisplayConditionsEnabled(r),title:o("Paste display conditions","elementor-pro"),callback:()=>$e.run("document/elements/paste-display-conditions",elementor.selection.getElements(r.getContainer()))}),n.actions.push({name:"clearDisplayConditions",isEnabled:()=>this.isClearDisplayConditionsEnabled(r),isVisible:()=>this.isClearDisplayConditionsEnabled(r),title:o("Clear display conditions","elementor-pro"),callback:()=>$e.run("document/elements/clear-display-conditions",elementor.selection.getElements(r.getContainer()))}),e}isPasteDisplayConditionsEnabled(e){const r=this.getSelectedElementDisplayCondition(e),n=!!JSON.parse(this.getDisplayConditionsFromClipboard()).length;return!r.length&&!elementor.selection.isMultiple()&&n}isClearDisplayConditionsEnabled(e){return this.getSelectedElementDisplayCondition(e).length&&!elementor.selection.isMultiple()}getSelectedElementDisplayCondition(e){return JSON.parse(e?.model?.getSetting(this.getSettings("controls").displayConditions)||"[]")}getDisplayConditionsFromClipboard(){const e=elementorCommon.storage.get("clipboard"),r=e?.elements||[];return 1!==r.length?"[]":r[0]?.settings?.e_display_conditions||"[]"}tryContextMenuActions(e,r){const n=e?.[0]||null,o=this.pasteAction===r?this.getDisplayConditionsFromClipboard():"";if(n){$e.run("document/elements/settings",{container:n,settings:{e_display_conditions:o}}),n.panel.refresh();try{const e=n.panel.getControlView(this.getSettings("controls").displayConditions),r=this.getEditorControlView(this.getSettings("controls").trigger).$el.find(this.getSettings("selectors").icon);this.highlightIcon(r,e)}catch(e){return!1}}}registerControlBehavior=(e,r)=>{if(this.getSettings("controls").trigger!==r.options.model.get("name"))return e;e||(e={});const n=this._getGroupedConditionKeys(elementor.config.displayConditions||{}),o=this._getFlattenedConditionOptions(n);return e.displayConditions={behaviorClass:a.default,getControlValue:()=>{const e=this.getEditorControlView(this.getSettings("controls").displayConditions);return e?this._getStructuredConditions(JSON.parse(e.getControlValue()||"[]")):[]},setControlValue:e=>{const r=this.getEditorControlView(this.getSettings("controls").displayConditions),n=this.getEditorControlView(this.getSettings("controls").trigger);if(r&&(e=e?.length&&"[]"!==e[0]?e:"",r.setValue(e),r.applySavedValue()),n.$el){const e=n.$el.find(this.getSettings("selectors").icon);this.highlightIcon(e,r)}},fetchData:async(e,r)=>{const n=await this.doAjaxRequest("pro_panel_posts_control_filter_autocomplete",{autocomplete:r.autocomplete,q:e});return n?.results??[]},setCacheNoticeStatus:async()=>{const e=await this.doAjaxRequest("display_conditions_set_cache_notice_status");return e&&(elementor.config.displayConditions.show_cache_notice=!1),e},conditionsConfig:{...elementor.config.displayConditions,conditionsByGroup:n,flattenedConditionOptions:o}},e};highlightIconIfFilled=(e,r)=>{if(!["section_advanced","_section_style","section_layout"].includes(e))return;const n=this.getEditorControlView(this.getSettings("controls").displayConditions);if(!n)return;const o=r.$childViewContainer.find(this.getSettings("selectors").icon);this.highlightIcon(o,n)};onNavigatorInit(){elementor.navigator.indicators.displayConditions={icon:"flow",title:o("Display Conditions","elementor-pro"),settingKeys:["e_display_conditions"],section:"e_display_conditions_trigger"}}highlightIcon=(e,r)=>{if(!e[0])return;const n=r.getControlValue()||"[]";("[]"!==n?this._getStructuredConditions(JSON.parse(n)):[]).length?e[0]?.classList?.add("filled"):e[0]?.classList?.remove("filled")};doAjaxRequest=(e,r)=>{try{return new Promise(((n,o)=>{elementorCommon.ajax.addRequest(e,{data:r,error:()=>o(),success:e=>{n(e)}})}))}catch(e){return!1}};_getStructuredConditions=e=>this._shouldConvertConditionsStructure(e)?[e]:e;_shouldConvertConditionsStructure=e=>e.length&&!Array.isArray(e[0]);_getGroupedConditionKeys=e=>Object.keys(e?.groups||{}).reduce(((r,n)=>{const o=this._getConditionKeyByGroup(e.conditions,n);return o.length&&(r[n]=o),r}),{});_getConditionKeyByGroup=(e,r)=>Object.keys(e).filter((n=>r===e[n].group));_getFlattenedConditionOptions=e=>{const{conditions:r={},groups:n={}}=elementor.config.displayConditions||{};return Object.entries(e).reduce(((e,o)=>{let[i,a]=o;const s=a.map((e=>({key:e,label:r[e].label,isGroup:!1})));return e.push({key:i,label:n[i].label,isGroup:!0},...s),e}),[])}}r.default=Module},4372:(e,r,n)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.conditionsReducer=void 0,n(5724);var o=n(4934);r.conditionsReducer=(e,r)=>{switch(r.type){case o.ACTION_TYPES.CHANGE_CONDITION_TYPE:return{...e,selectedConditions:_changeConditionType({...e,...r})};case o.ACTION_TYPES.CHANGE_CONTROL_VALUE:return{...e,selectedConditions:_changeControlValue({...e,...r})};case o.ACTION_TYPES.ADD_AND_CONDITION:return{...e,selectedConditions:_addAndCondition({...e,...r})};case o.ACTION_TYPES.ADD_OR_CONDITION:return{...e,selectedConditions:[...e.selectedConditions,[r.andCondition]]};case o.ACTION_TYPES.REMOVE_AND_CONDITION:return{...e,selectedConditions:_removeAndCondition({...e,...r})};case o.ACTION_TYPES.REMOVE_OR_CONDITION:return{...e,selectedConditions:e.selectedConditions.filter(((e,n)=>n!==r.orConditionIndex))};case o.ACTION_TYPES.SET_ERRORS:return{...e,selectedConditions:_setErrors({...e,...r})};default:return e}};const _changeConditionType=e=>{let{selectedConditions:r,conditionToChange:n,orConditionIndex:o,andConditionIndex:i}=e;const a=r[o].map(((e,r)=>r===i?n:{...e}));return r.map(((e,r)=>r===o?a:[...e]))},_changeControlValue=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,controlKey:i,value:a}=e;const s=[...r[n]],u={...{...s[o]},[i]:a},c=s.map(((e,r)=>r===o?u:{...e}));return r.map(((e,r)=>r===n?c:[...e]))},_addAndCondition=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,andCondition:i}=e;const a=r[n],s=a.reduce(((e,r,n)=>(e.push({...r}),(n===o||a.length===o&&a.length-1===n)&&e.push(i),e)),[]);return r.map(((e,r)=>r===n?s:[...e]))},_removeAndCondition=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o}=e;const i=r[n].reduce(((e,r,n)=>(n!==o&&e.push({...r}),e)),[]);return r.reduce(((e,r,o)=>(o===n&&i.length&&e.push(i),o!==n&&e.push([...r]),e)),[])},_setErrors=e=>{let{selectedConditions:r,orConditionIndex:n,andConditionIndex:o,errors:i}=e;const a=[...r[n]],s={...a[o]};return s.errors={...s.errors,...i},a[o]=s,r.map(((e,r)=>r===n?[...a]:[...e]))}},4934:(e,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.DISABLED_CONTROL_CONFIG=r.DEFAULT_CONTROL_VALUES=r.CONTROL_TYPES=r.ACTION_TYPES=void 0;r.CONTROL_TYPES={MULTIPLE_SELECT:"select2",SELECT:"select",QUERY:"query",DATE_TIME:"date_time",TEXT_FIELD:"text"},r.DEFAULT_CONTROL_VALUES={select2:[],query:[],select:"",text:"",date_time:null},r.ACTION_TYPES={CHANGE_CONTROL_VALUE:"CHANGE_CONTROL_VALUE",SET_ERRORS:"SET_ERRORS",ADD_OR_CONDITION:"ADD_OR_CONDITION",CHANGE_CONDITION_TYPE:"CHANGE_CONDITION_TYPE",ADD_AND_CONDITION:"ADD_AND_CONDITION",REMOVE_AND_CONDITION:"REMOVE_AND_CONDITION",REMOVE_OR_CONDITION:"REMOVE_OR_CONDITION"},r.DISABLED_CONTROL_CONFIG={CONDITION_NAME:"dynamic_tags",CONTROL_NAME:"dynamic_tag_value",COMPARATORS:["is_empty","is_not_empty"]}},3726:(e,r,n)=>{"use strict";var o=n(2470).__;Object.defineProperty(r,"__esModule",{value:!0}),r.getControlDefaults=r.getConditionInitialState=void 0,r.getControlValue=function getControlValue(e,r){return void 0!==e?e:r},r.getControlValueMaxWidth=function getControlValueMaxWidth(e){return 3===e?190:135},r.getDefaultActiveCondition=function getDefaultActiveCondition(e){return Object.values(e)[0][0]},r.getInvalidInputFeedback=getInvalidInputFeedback,r.getSelectOptionMaxWidth=function getSelectOptionMaxWidth(e){return 3===e?200:150},r.hasDecimalSeparator=function hasDecimalSeparator(e){if(isNaN(parseFloat(e)))return!1;if(-1!==e.toString().indexOf("."))return!0;if(-1!==e.toString().indexOf(","))return!0},r.shouldCastToArray=shouldCastToArray,r.shouldDisableControl=function shouldDisableControl(e,r){return i.DISABLED_CONTROL_CONFIG.CONTROL_NAME===e&&i.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(r)},r.shouldEmptyValuePassValidation=function shouldEmptyValuePassValidation(e,r){return i.DISABLED_CONTROL_CONFIG.CONDITION_NAME===e&&i.DISABLED_CONTROL_CONFIG.COMPARATORS.includes(r)},n(6281);var i=n(4934);function shouldCastToArray(e){return i.CONTROL_TYPES.MULTIPLE_SELECT===e||i.CONTROL_TYPES.QUERY===e}function getInvalidInputFeedback(e,r,n){let o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];return n?.length?{}:{message:_getErrorMessage(e,r),shouldShow:o}}const getControlDefaults=(e,r)=>{const{type:n,variant:o=null,options:a}=r,s=r?.default||(a&&i.CONTROL_TYPES.MULTIPLE_SELECT!==n?Object.keys(a)[0]:i.DEFAULT_CONTROL_VALUES[n]),u=shouldCastToArray(n)&&!Array.isArray(s)?[s]:s;return{defaultValue:u,error:getInvalidInputFeedback(n,o,u)}};r.getControlDefaults=getControlDefaults;function _getErrorMessage(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return shouldCastToArray(e)?o("Select an option","elementor-pro"):i.CONTROL_TYPES.DATE_TIME===e?o("time"===r?"Select a time":"Select a date","elementor-pro"):o("Enter a value","elementor-pro")}r.getConditionInitialState=(e,r)=>{const{controls:n={}}=e?.[r]||{};return Object.keys(n).reduce(((e,r)=>{if("__settings"===r)return e;const{defaultValue:o,error:i}=getControlDefaults(0,n[r]);return e[r]=o,e.errors[r]=i,e}),{errors:{}})}},5285:function(e){e.exports=function(){"use strict";var e=1e3,r=6e4,n=36e5,o="millisecond",i="second",a="minute",s="hour",u="day",c="week",f="month",p="quarter",g="year",C="date",v="Invalid Date",_=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,b=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,x={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(e){var r=["th","st","nd","rd"],n=e%100;return"["+e+(r[(n-20)%10]||r[n]||r[0])+"]"}},m=function(e,r,n){var o=String(e);return!o||o.length>=r?e:""+Array(r+1-o.length).join(n)+e},E={s:m,z:function(e){var r=-e.utcOffset(),n=Math.abs(r),o=Math.floor(n/60),i=n%60;return(r<=0?"+":"-")+m(o,2,"0")+":"+m(i,2,"0")},m:function t(e,r){if(e.date()1)return t(a[0])}else{var s=e.name;w[s]=e,o=s}return!n&&o&&(R=o),o||!n&&R},O=function(e,r){if(S(e))return e.clone();var n="object"==typeof r?r:{};return n.date=e,n.args=arguments,new I(n)},T=E;T.l=j,T.i=S,T.w=function(e,r){return O(e,{locale:r.$L,utc:r.$u,x:r.$x,$offset:r.$offset})};var I=function(){function M(e){this.$L=j(e.locale,null,!0),this.parse(e),this.$x=this.$x||e.x||{},this[P]=!0}var x=M.prototype;return x.parse=function(e){this.$d=function(e){var r=e.date,n=e.utc;if(null===r)return new Date(NaN);if(T.u(r))return new Date;if(r instanceof Date)return new Date(r);if("string"==typeof r&&!/Z$/i.test(r)){var o=r.match(_);if(o){var i=o[2]-1||0,a=(o[7]||"0").substring(0,3);return n?new Date(Date.UTC(o[1],i,o[3]||1,o[4]||0,o[5]||0,o[6]||0,a)):new Date(o[1],i,o[3]||1,o[4]||0,o[5]||0,o[6]||0,a)}}return new Date(r)}(e),this.init()},x.init=function(){var e=this.$d;this.$y=e.getFullYear(),this.$M=e.getMonth(),this.$D=e.getDate(),this.$W=e.getDay(),this.$H=e.getHours(),this.$m=e.getMinutes(),this.$s=e.getSeconds(),this.$ms=e.getMilliseconds()},x.$utils=function(){return T},x.isValid=function(){return!(this.$d.toString()===v)},x.isSame=function(e,r){var n=O(e);return this.startOf(r)<=n&&n<=this.endOf(r)},x.isAfter=function(e,r){return O(e){"use strict";var o=n(6441);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,e.exports=function(){function shim(e,r,n,i,a,s){if(s!==o){var u=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function getShim(){return shim}shim.isRequired=shim;var e={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return e.PropTypes=e,e}},2688:(e,r,n)=>{e.exports=n(362)()},6441:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},1594:e=>{"use strict";e.exports=React},4048:e=>{"use strict";e.exports=elementorV2.icons},6956:e=>{"use strict";e.exports=elementorV2.ui},2470:e=>{"use strict";e.exports=wp.i18n},8304:e=>{function _extends(){return e.exports=_extends=Object.assign?Object.assign.bind():function(e){for(var r=1;r{e.exports=function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports},8120:(e,r,n)=>{"use strict";var o=n(1483),i=n(8761),a=TypeError;e.exports=function(e){if(o(e))return e;throw new a(i(e)+" is not a function")}},7095:(e,r,n)=>{"use strict";var o=n(1),i=n(5290),a=n(5835).f,s=o("unscopables"),u=Array.prototype;void 0===u[s]&&a(u,s,{configurable:!0,value:i(null)}),e.exports=function(e){u[s][e]=!0}},2293:(e,r,n)=>{"use strict";var o=n(1704),i=String,a=TypeError;e.exports=function(e){if(o(e))return e;throw new a(i(e)+" is not an object")}},6651:(e,r,n)=>{"use strict";var o=n(5599),i=n(3392),a=n(6960),createMethod=function(e){return function(r,n,s){var u=o(r),c=a(u);if(0===c)return!e&&-1;var f,p=i(s,c);if(e&&n!=n){for(;c>p;)if((f=u[p++])!=f)return!0}else for(;c>p;p++)if((e||p in u)&&u[p]===n)return e||p||0;return!e&&-1}};e.exports={includes:createMethod(!0),indexOf:createMethod(!1)}},9273:(e,r,n)=>{"use strict";var o=n(382),i=n(4914),a=TypeError,s=Object.getOwnPropertyDescriptor,u=o&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=u?function(e,r){if(i(e)&&!s(e,"length").writable)throw new a("Cannot set read only .length");return e.length=r}:function(e,r){return e.length=r}},1278:(e,r,n)=>{"use strict";var o=n(4762),i=o({}.toString),a=o("".slice);e.exports=function(e){return a(i(e),8,-1)}},6726:(e,r,n)=>{"use strict";var o=n(5755),i=n(9497),a=n(4961),s=n(5835);e.exports=function(e,r,n){for(var u=i(r),c=s.f,f=a.f,p=0;p{"use strict";var o=n(382),i=n(5835),a=n(7738);e.exports=o?function(e,r,n){return i.f(e,r,a(1,n))}:function(e,r,n){return e[r]=n,e}},7738:e=>{"use strict";e.exports=function(e,r){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:r}}},7914:(e,r,n)=>{"use strict";var o=n(1483),i=n(5835),a=n(169),s=n(2095);e.exports=function(e,r,n,u){u||(u={});var c=u.enumerable,f=void 0!==u.name?u.name:r;if(o(n)&&a(n,f,u),u.global)c?e[r]=n:s(r,n);else{try{u.unsafe?e[r]&&(c=!0):delete e[r]}catch(e){}c?e[r]=n:i.f(e,r,{value:n,enumerable:!1,configurable:!u.nonConfigurable,writable:!u.nonWritable})}return e}},2095:(e,r,n)=>{"use strict";var o=n(5578),i=Object.defineProperty;e.exports=function(e,r){try{i(o,e,{value:r,configurable:!0,writable:!0})}catch(n){o[e]=r}return r}},382:(e,r,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},3145:(e,r,n)=>{"use strict";var o=n(5578),i=n(1704),a=o.document,s=i(a)&&i(a.createElement);e.exports=function(e){return s?a.createElement(e):{}}},1091:e=>{"use strict";var r=TypeError;e.exports=function(e){if(e>9007199254740991)throw r("Maximum allowed index exceeded");return e}},4741:e=>{"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},9461:(e,r,n)=>{"use strict";var o=n(5578).navigator,i=o&&o.userAgent;e.exports=i?String(i):""},6477:(e,r,n)=>{"use strict";var o,i,a=n(5578),s=n(9461),u=a.process,c=a.Deno,f=u&&u.versions||c&&c.version,p=f&&f.v8;p&&(i=(o=p.split("."))[0]>0&&o[0]<4?1:+(o[0]+o[1])),!i&&s&&(!(o=s.match(/Edge\/(\d+)/))||o[1]>=74)&&(o=s.match(/Chrome\/(\d+)/))&&(i=+o[1]),e.exports=i},8612:(e,r,n)=>{"use strict";var o=n(5578),i=n(4961).f,a=n(9037),s=n(7914),u=n(2095),c=n(6726),f=n(8730);e.exports=function(e,r){var n,p,g,C,v,_=e.target,b=e.global,x=e.stat;if(n=b?o:x?o[_]||u(_,{}):o[_]&&o[_].prototype)for(p in r){if(C=r[p],g=e.dontCallGetSet?(v=i(n,p))&&v.value:n[p],!f(b?p:_+(x?".":"#")+p,e.forced)&&void 0!==g){if(typeof C==typeof g)continue;c(C,g)}(e.sham||g&&g.sham)&&a(C,"sham",!0),s(n,p,C,e)}}},8473:e=>{"use strict";e.exports=function(e){try{return!!e()}catch(e){return!0}}},274:(e,r,n)=>{"use strict";var o=n(8473);e.exports=!o((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},1807:(e,r,n)=>{"use strict";var o=n(274),i=Function.prototype.call;e.exports=o?i.bind(i):function(){return i.apply(i,arguments)}},2048:(e,r,n)=>{"use strict";var o=n(382),i=n(5755),a=Function.prototype,s=o&&Object.getOwnPropertyDescriptor,u=i(a,"name"),c=u&&"something"===function something(){}.name,f=u&&(!o||o&&s(a,"name").configurable);e.exports={EXISTS:u,PROPER:c,CONFIGURABLE:f}},4762:(e,r,n)=>{"use strict";var o=n(274),i=Function.prototype,a=i.call,s=o&&i.bind.bind(a,a);e.exports=o?s:function(e){return function(){return a.apply(e,arguments)}}},1409:(e,r,n)=>{"use strict";var o=n(5578),i=n(1483);e.exports=function(e,r){return arguments.length<2?(n=o[e],i(n)?n:void 0):o[e]&&o[e][r];var n}},2564:(e,r,n)=>{"use strict";var o=n(8120),i=n(5983);e.exports=function(e,r){var n=e[r];return i(n)?void 0:o(n)}},5578:function(e,r,n){"use strict";var check=function(e){return e&&e.Math===Math&&e};e.exports=check("object"==typeof globalThis&&globalThis)||check("object"==typeof window&&window)||check("object"==typeof self&&self)||check("object"==typeof n.g&&n.g)||check("object"==typeof this&&this)||function(){return this}()||Function("return this")()},5755:(e,r,n)=>{"use strict";var o=n(4762),i=n(2347),a=o({}.hasOwnProperty);e.exports=Object.hasOwn||function hasOwn(e,r){return a(i(e),r)}},1507:e=>{"use strict";e.exports={}},2811:(e,r,n)=>{"use strict";var o=n(1409);e.exports=o("document","documentElement")},1799:(e,r,n)=>{"use strict";var o=n(382),i=n(8473),a=n(3145);e.exports=!o&&!i((function(){return 7!==Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},2121:(e,r,n)=>{"use strict";var o=n(4762),i=n(8473),a=n(1278),s=Object,u=o("".split);e.exports=i((function(){return!s("z").propertyIsEnumerable(0)}))?function(e){return"String"===a(e)?u(e,""):s(e)}:s},7268:(e,r,n)=>{"use strict";var o=n(4762),i=n(1483),a=n(1831),s=o(Function.toString);i(a.inspectSource)||(a.inspectSource=function(e){return s(e)}),e.exports=a.inspectSource},4483:(e,r,n)=>{"use strict";var o,i,a,s=n(4644),u=n(5578),c=n(1704),f=n(9037),p=n(5755),g=n(1831),C=n(5409),v=n(1507),_="Object already initialized",b=u.TypeError,x=u.WeakMap;if(s||g.state){var E=g.state||(g.state=new x);E.get=E.get,E.has=E.has,E.set=E.set,o=function(e,r){if(E.has(e))throw new b(_);return r.facade=e,E.set(e,r),r},i=function(e){return E.get(e)||{}},a=function(e){return E.has(e)}}else{var R=C("state");v[R]=!0,o=function(e,r){if(p(e,R))throw new b(_);return r.facade=e,f(e,R,r),r},i=function(e){return p(e,R)?e[R]:{}},a=function(e){return p(e,R)}}e.exports={set:o,get:i,has:a,enforce:function(e){return a(e)?i(e):o(e,{})},getterFor:function(e){return function(r){var n;if(!c(r)||(n=i(r)).type!==e)throw new b("Incompatible receiver, "+e+" required");return n}}}},4914:(e,r,n)=>{"use strict";var o=n(1278);e.exports=Array.isArray||function isArray(e){return"Array"===o(e)}},1483:e=>{"use strict";var r="object"==typeof document&&document.all;e.exports=void 0===r&&void 0!==r?function(e){return"function"==typeof e||e===r}:function(e){return"function"==typeof e}},8730:(e,r,n)=>{"use strict";var o=n(8473),i=n(1483),a=/#|\.prototype\./,isForced=function(e,r){var n=u[s(e)];return n===f||n!==c&&(i(r)?o(r):!!r)},s=isForced.normalize=function(e){return String(e).replace(a,".").toLowerCase()},u=isForced.data={},c=isForced.NATIVE="N",f=isForced.POLYFILL="P";e.exports=isForced},5983:e=>{"use strict";e.exports=function(e){return null==e}},1704:(e,r,n)=>{"use strict";var o=n(1483);e.exports=function(e){return"object"==typeof e?null!==e:o(e)}},9557:e=>{"use strict";e.exports=!1},1423:(e,r,n)=>{"use strict";var o=n(1409),i=n(1483),a=n(4815),s=n(5022),u=Object;e.exports=s?function(e){return"symbol"==typeof e}:function(e){var r=o("Symbol");return i(r)&&a(r.prototype,u(e))}},6960:(e,r,n)=>{"use strict";var o=n(8324);e.exports=function(e){return o(e.length)}},169:(e,r,n)=>{"use strict";var o=n(4762),i=n(8473),a=n(1483),s=n(5755),u=n(382),c=n(2048).CONFIGURABLE,f=n(7268),p=n(4483),g=p.enforce,C=p.get,v=String,_=Object.defineProperty,b=o("".slice),x=o("".replace),E=o([].join),R=u&&!i((function(){return 8!==_((function(){}),"length",{value:8}).length})),w=String(String).split("String"),P=e.exports=function(e,r,n){"Symbol("===b(v(r),0,7)&&(r="["+x(v(r),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),n&&n.getter&&(r="get "+r),n&&n.setter&&(r="set "+r),(!s(e,"name")||c&&e.name!==r)&&(u?_(e,"name",{value:r,configurable:!0}):e.name=r),R&&n&&s(n,"arity")&&e.length!==n.arity&&_(e,"length",{value:n.arity});try{n&&s(n,"constructor")&&n.constructor?u&&_(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var o=g(e);return s(o,"source")||(o.source=E(w,"string"==typeof r?r:"")),e};Function.prototype.toString=P((function toString(){return a(this)&&C(this).source||f(this)}),"toString")},1703:e=>{"use strict";var r=Math.ceil,n=Math.floor;e.exports=Math.trunc||function trunc(e){var o=+e;return(o>0?n:r)(o)}},5290:(e,r,n)=>{"use strict";var o,i=n(2293),a=n(5799),s=n(4741),u=n(1507),c=n(2811),f=n(3145),p=n(5409),g="prototype",C="script",v=p("IE_PROTO"),EmptyConstructor=function(){},scriptTag=function(e){return"<"+C+">"+e+""},NullProtoObjectViaActiveX=function(e){e.write(scriptTag("")),e.close();var r=e.parentWindow.Object;return e=null,r},NullProtoObject=function(){try{o=new ActiveXObject("htmlfile")}catch(e){}var e,r,n;NullProtoObject="undefined"!=typeof document?document.domain&&o?NullProtoObjectViaActiveX(o):(r=f("iframe"),n="java"+C+":",r.style.display="none",c.appendChild(r),r.src=String(n),(e=r.contentWindow.document).open(),e.write(scriptTag("document.F=Object")),e.close(),e.F):NullProtoObjectViaActiveX(o);for(var i=s.length;i--;)delete NullProtoObject[g][s[i]];return NullProtoObject()};u[v]=!0,e.exports=Object.create||function create(e,r){var n;return null!==e?(EmptyConstructor[g]=i(e),n=new EmptyConstructor,EmptyConstructor[g]=null,n[v]=e):n=NullProtoObject(),void 0===r?n:a.f(n,r)}},5799:(e,r,n)=>{"use strict";var o=n(382),i=n(3896),a=n(5835),s=n(2293),u=n(5599),c=n(3658);r.f=o&&!i?Object.defineProperties:function defineProperties(e,r){s(e);for(var n,o=u(r),i=c(r),f=i.length,p=0;f>p;)a.f(e,n=i[p++],o[n]);return e}},5835:(e,r,n)=>{"use strict";var o=n(382),i=n(1799),a=n(3896),s=n(2293),u=n(3815),c=TypeError,f=Object.defineProperty,p=Object.getOwnPropertyDescriptor,g="enumerable",C="configurable",v="writable";r.f=o?a?function defineProperty(e,r,n){if(s(e),r=u(r),s(n),"function"==typeof e&&"prototype"===r&&"value"in n&&v in n&&!n[v]){var o=p(e,r);o&&o[v]&&(e[r]=n.value,n={configurable:C in n?n[C]:o[C],enumerable:g in n?n[g]:o[g],writable:!1})}return f(e,r,n)}:f:function defineProperty(e,r,n){if(s(e),r=u(r),s(n),i)try{return f(e,r,n)}catch(e){}if("get"in n||"set"in n)throw new c("Accessors not supported");return"value"in n&&(e[r]=n.value),e}},4961:(e,r,n)=>{"use strict";var o=n(382),i=n(1807),a=n(7611),s=n(7738),u=n(5599),c=n(3815),f=n(5755),p=n(1799),g=Object.getOwnPropertyDescriptor;r.f=o?g:function getOwnPropertyDescriptor(e,r){if(e=u(e),r=c(r),p)try{return g(e,r)}catch(e){}if(f(e,r))return s(!i(a.f,e,r),e[r])}},2278:(e,r,n)=>{"use strict";var o=n(6742),i=n(4741).concat("length","prototype");r.f=Object.getOwnPropertyNames||function getOwnPropertyNames(e){return o(e,i)}},4347:(e,r)=>{"use strict";r.f=Object.getOwnPropertySymbols},4815:(e,r,n)=>{"use strict";var o=n(4762);e.exports=o({}.isPrototypeOf)},6742:(e,r,n)=>{"use strict";var o=n(4762),i=n(5755),a=n(5599),s=n(6651).indexOf,u=n(1507),c=o([].push);e.exports=function(e,r){var n,o=a(e),f=0,p=[];for(n in o)!i(u,n)&&i(o,n)&&c(p,n);for(;r.length>f;)i(o,n=r[f++])&&(~s(p,n)||c(p,n));return p}},3658:(e,r,n)=>{"use strict";var o=n(6742),i=n(4741);e.exports=Object.keys||function keys(e){return o(e,i)}},7611:(e,r)=>{"use strict";var n={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!n.call({1:2},1);r.f=i?function propertyIsEnumerable(e){var r=o(this,e);return!!r&&r.enumerable}:n},348:(e,r,n)=>{"use strict";var o=n(1807),i=n(1483),a=n(1704),s=TypeError;e.exports=function(e,r){var n,u;if("string"===r&&i(n=e.toString)&&!a(u=o(n,e)))return u;if(i(n=e.valueOf)&&!a(u=o(n,e)))return u;if("string"!==r&&i(n=e.toString)&&!a(u=o(n,e)))return u;throw new s("Can't convert object to primitive value")}},9497:(e,r,n)=>{"use strict";var o=n(1409),i=n(4762),a=n(2278),s=n(4347),u=n(2293),c=i([].concat);e.exports=o("Reflect","ownKeys")||function ownKeys(e){var r=a.f(u(e)),n=s.f;return n?c(r,n(e)):r}},3312:(e,r,n)=>{"use strict";var o=n(5983),i=TypeError;e.exports=function(e){if(o(e))throw new i("Can't call method on "+e);return e}},5409:(e,r,n)=>{"use strict";var o=n(7255),i=n(1866),a=o("keys");e.exports=function(e){return a[e]||(a[e]=i(e))}},1831:(e,r,n)=>{"use strict";var o=n(9557),i=n(5578),a=n(2095),s="__core-js_shared__",u=e.exports=i[s]||a(s,{});(u.versions||(u.versions=[])).push({version:"3.38.1",mode:o?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.38.1/LICENSE",source:"https://github.com/zloirock/core-js"})},7255:(e,r,n)=>{"use strict";var o=n(1831);e.exports=function(e,r){return o[e]||(o[e]=r||{})}},6029:(e,r,n)=>{"use strict";var o=n(6477),i=n(8473),a=n(5578).String;e.exports=!!Object.getOwnPropertySymbols&&!i((function(){var e=Symbol("symbol detection");return!a(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&o&&o<41}))},3392:(e,r,n)=>{"use strict";var o=n(3005),i=Math.max,a=Math.min;e.exports=function(e,r){var n=o(e);return n<0?i(n+r,0):a(n,r)}},5599:(e,r,n)=>{"use strict";var o=n(2121),i=n(3312);e.exports=function(e){return o(i(e))}},3005:(e,r,n)=>{"use strict";var o=n(1703);e.exports=function(e){var r=+e;return r!=r||0===r?0:o(r)}},8324:(e,r,n)=>{"use strict";var o=n(3005),i=Math.min;e.exports=function(e){var r=o(e);return r>0?i(r,9007199254740991):0}},2347:(e,r,n)=>{"use strict";var o=n(3312),i=Object;e.exports=function(e){return i(o(e))}},2355:(e,r,n)=>{"use strict";var o=n(1807),i=n(1704),a=n(1423),s=n(2564),u=n(348),c=n(1),f=TypeError,p=c("toPrimitive");e.exports=function(e,r){if(!i(e)||a(e))return e;var n,c=s(e,p);if(c){if(void 0===r&&(r="default"),n=o(c,e,r),!i(n)||a(n))return n;throw new f("Can't convert object to primitive value")}return void 0===r&&(r="number"),u(e,r)}},3815:(e,r,n)=>{"use strict";var o=n(2355),i=n(1423);e.exports=function(e){var r=o(e,"string");return i(r)?r:r+""}},8761:e=>{"use strict";var r=String;e.exports=function(e){try{return r(e)}catch(e){return"Object"}}},1866:(e,r,n)=>{"use strict";var o=n(4762),i=0,a=Math.random(),s=o(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+s(++i+a,36)}},5022:(e,r,n)=>{"use strict";var o=n(6029);e.exports=o&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},3896:(e,r,n)=>{"use strict";var o=n(382),i=n(8473);e.exports=o&&i((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},4644:(e,r,n)=>{"use strict";var o=n(5578),i=n(1483),a=o.WeakMap;e.exports=i(a)&&/native code/.test(String(a))},1:(e,r,n)=>{"use strict";var o=n(5578),i=n(7255),a=n(5755),s=n(1866),u=n(6029),c=n(5022),f=o.Symbol,p=i("wks"),g=c?f.for||f:f&&f.withoutSetter||s;e.exports=function(e){return a(p,e)||(p[e]=u&&a(f,e)?f[e]:g("Symbol."+e)),p[e]}},6281:(e,r,n)=>{"use strict";var o=n(8612),i=n(6651).includes,a=n(8473),s=n(7095);o({target:"Array",proto:!0,forced:a((function(){return!Array(1).includes()}))},{includes:function includes(e){return i(this,e,arguments.length>1?arguments[1]:void 0)}}),s("includes")},5724:(e,r,n)=>{"use strict";var o=n(8612),i=n(2347),a=n(6960),s=n(9273),u=n(1091);o({target:"Array",proto:!0,arity:1,forced:n(8473)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function push(e){var r=i(this),n=a(r),o=arguments.length;u(n+o);for(var c=0;c{"use strict";new(__webpack_require__(6784)(__webpack_require__(9097)).default)})()})();/** * External dependencies */ import { __ } from '@wordpress/i18n'; import EditProductLink from '@woocommerce/editor-components/edit-product-link'; import { useProductDataContext } from '@woocommerce/shared-context'; import classnames from 'classnames'; import { Disabled, PanelBody, ToggleControl, Notice, } from '@wordpress/components'; import { InspectorControls } from '@wordpress/block-editor'; import { productSupportsAddToCartForm } from '@woocommerce/base-utils'; /** * Internal dependencies */ import './style.scss'; import Block from './block'; import withProductSelector from '../shared/with-product-selector'; import { BLOCK_TITLE, BLOCK_ICON } from './constants'; const Edit = ( { attributes, setAttributes } ) => { const { product } = useProductDataContext(); const { className, showFormElements } = attributes; return (
{ productSupportsAddToCartForm( product ) ? ( setAttributes( { showFormElements: ! showFormElements, } ) } /> ) : ( { __( 'This product does not support the block based add to cart form. A link to the product page will be shown instead.', 'woocommerce' ) } ) }
); }; export default withProductSelector( { icon: BLOCK_ICON, label: BLOCK_TITLE, description: __( 'Choose a product to display its add to cart form.', 'woocommerce' ), } )( Edit ); /** * List block tracker for UUID-aware list editing and serialization. * * Dependencies: wp.blocks, SFE.ElementPrep * Exposes: SFE.ListBlockTracker */ (function() { 'use strict'; window.MWP = window.MWP || {}; window.MWP.SFE = window.MWP.SFE || {}; const SFE = window.MWP.SFE; SFE.ManagerData = SFE.ManagerData || {}; const { createBlock, serialize: serializeBlocks } = window.wp?.blocks || {}; const UUID_ATTR_KEYS = ['mwpSfeUuid', 'mwpSfeUuidShadow']; const LIST_ITEM_TEXT_ATTR = 'data-mwp-sfe-list-item-text'; const LIST_ITEM_TEXT_CLASS = 'mwp-sfe-list-item-text'; const PLACEHOLDER_ATTR = 'data-rich-text-placeholder'; const LIST_ID_ATTR = 'data-list-id'; const LIST_ITEM_ID_ATTR = 'data-item-id'; const LIST_RUNTIME_UUID_ATTR = 'data-mwp-sfe-list-runtime-uuid'; const LIST_ITEM_RUNTIME_UUID_ATTR = 'data-mwp-sfe-list-item-runtime-uuid'; /** * Return whether one node is a nested list element. * * @param {Node|null} node Candidate DOM node. * @returns {boolean} True when the node is a nested list. */ function isNestedListNode(node) { return !!( node && node.nodeType === Node.ELEMENT_NODE && (node.tagName === 'UL' || node.tagName === 'OL') ); } /** * Return whether one node is ignorable formatting whitespace between list * structures. * * Pretty-printed block markup often leaves direct `\n` text nodes between a * list item's own text and its nested child list. Those nodes should not be * moved into the direct text surface because they become visible editing * artifacts once wrapped. * * @param {Node|null} node Candidate DOM node. * @returns {boolean} True when the node is ignorable whitespace. */ function isIgnorableListWhitespaceNode(node) { return !!( node && node.nodeType === Node.TEXT_NODE && String(node.textContent || '') .replace(/\uFEFF/g, '') .replace(/\u00A0/g, ' ') .trim() .length === 0 ); } /** * Return the direct inline text surface for one list item. * * @param {HTMLLIElement|null} liElement Candidate list item. * @returns {HTMLElement|null} Existing direct text surface, if any. */ function getDirectItemTextSurface(liElement) { if (!liElement || liElement.nodeType !== Node.ELEMENT_NODE || liElement.tagName !== 'LI') { return null; } return Array.from(liElement.children || []).find(child => ( child && child.nodeType === Node.ELEMENT_NODE && child.getAttribute(LIST_ITEM_TEXT_ATTR) === '1' )) || null; } /** * Return the DOM attribute name that stores one session-scoped runtime UUID. * * Runtime UUIDs are distinct from the existing serialization/attr UUIDs. They * exist only while the editor session is open so external callers can point at * the current live list cursor/target without having to manage shifting paths. * * @param {string} type Supported runtime identity type. * @returns {string} Attribute name, or an empty string for invalid types. */ function getRuntimeUuidAttributeName(type) { if (type === 'list') { return LIST_RUNTIME_UUID_ATTR; } if (type === 'item') { return LIST_ITEM_RUNTIME_UUID_ATTR; } return ''; } /** * Normalize one runtime UUID candidate. * * @param {*} value Candidate runtime UUID. * @returns {string} Trimmed runtime UUID, or an empty string. */ function normalizeRuntimeUuid(value) { return String(value || '').trim(); } /** * Return whether one element matches the requested runtime-identity type. * * @param {Element|null} element Candidate DOM element. * @param {string} type Supported runtime identity type. * @returns {boolean} True when the element matches the type. */ function isRuntimeIdentityElement(element, type) { if (!element || element.nodeType !== Node.ELEMENT_NODE) { return false; } if (type === 'list') { return element.tagName === 'UL' || element.tagName === 'OL'; } if (type === 'item') { return element.tagName === 'LI'; } return false; } /** * Return one tracked element by runtime UUID from the live DOM. * * This intentionally queries the current DOM first instead of trusting only a * cached map so history restores and other structural replacements can keep * runtime UUID resolution stable as long as the attributes remain present. * * @param {Object|null} tracker Active list tracker. * @param {string} runtimeUuid Session-scoped runtime UUID. * @param {string} type Supported runtime identity type. * @returns {Element|null} Matching live DOM element. */ function findElementByRuntimeUuid(tracker, runtimeUuid, type) { const normalizedRuntimeUuid = normalizeRuntimeUuid(runtimeUuid); const attrName = getRuntimeUuidAttributeName(type); if ( !tracker?.listElement || !normalizedRuntimeUuid || !attrName || !isRuntimeIdentityElement(tracker.listElement, 'list') ) { return null; } if ( type === 'list' && tracker.listElement.getAttribute(attrName) === normalizedRuntimeUuid ) { return tracker.listElement; } try { const selector = `[${attrName}="${CSS.escape(normalizedRuntimeUuid)}"]`; return tracker.listElement.querySelector(selector); } catch (error) { const escapedUuid = normalizedRuntimeUuid.replace(/"/g, '\\"'); return tracker.listElement.querySelector(`[${attrName}="${escapedUuid}"]`); } } /** * Return every direct text surface currently attached to one list item. * * Merge/delete flows can temporarily move multiple direct text surfaces into * the same list item. The shared list normalizer must collapse them back to * one canonical surface before placeholder syncing or serialization. * * @param {HTMLLIElement|null} liElement Candidate list item. * @returns {HTMLElement[]} Direct text surfaces in DOM order. */ function getAllDirectItemTextSurfaces(liElement) { if (!liElement || liElement.nodeType !== Node.ELEMENT_NODE || liElement.tagName !== 'LI') { return []; } return Array.from(liElement.children || []).filter(child => ( child && child.nodeType === Node.ELEMENT_NODE && child.getAttribute(LIST_ITEM_TEXT_ATTR) === '1' )); } /** * Return whether one node is only placeholder/caret scaffolding. * * Duplicate direct text surfaces may carry empty placeholder anchors or * caret `
` nodes. Those artifacts should be dropped when collapsing * duplicate surfaces instead of being concatenated into visible stacks. * * @param {Node|null} node Candidate DOM node. * @returns {boolean} True when the node is redundant placeholder UI. */ function isRedundantSurfaceArtifact(node) { if (!node) { return true; } if (isIgnorableListWhitespaceNode(node)) { return true; } if (node.nodeType === Node.TEXT_NODE) { return String(node.textContent || '') .replace(/\uFEFF/g, '') .replace(/\u00A0/g, ' ') .trim() .length === 0; } if (node.nodeType !== Node.ELEMENT_NODE) { return false; } if (node.tagName === 'BR') { return true; } return !!node.hasAttribute?.(PLACEHOLDER_ATTR); } /** * Ensure one list item owns one direct inline text surface. * * The root list remains the single live editor host, but this wrapper gives * schema/ABE flows one stable DOM surface per list item's own text content. * * @param {HTMLLIElement|null} liElement Candidate list item. * @returns {HTMLElement|null} Ensured direct text surface. */ function ensureDirectItemTextSurface(liElement) { if (!liElement || liElement.nodeType !== Node.ELEMENT_NODE || liElement.tagName !== 'LI') { return null; } let surface = getDirectItemTextSurface(liElement); if (!surface) { surface = document.createElement('span'); surface.setAttribute(LIST_ITEM_TEXT_ATTR, '1'); surface.classList.add(LIST_ITEM_TEXT_CLASS); liElement.insertBefore( surface, Array.from(liElement.childNodes || []).find(isNestedListNode) || null ); } getAllDirectItemTextSurfaces(liElement) .filter(candidate => candidate && candidate !== surface) .forEach(duplicateSurface => { Array.from(duplicateSurface.childNodes || []).forEach(node => { if (isRedundantSurfaceArtifact(node)) { node.remove(); return; } surface.appendChild(node); }); duplicateSurface.remove(); }); const childNodes = Array.from(liElement.childNodes || []); childNodes.forEach(node => { if ( node && node !== surface && !isNestedListNode(node) && isIgnorableListWhitespaceNode(node) ) { node.remove(); } }); const movableNodes = childNodes.filter(node => { if (!node || node === surface || isNestedListNode(node)) { return false; } if (isIgnorableListWhitespaceNode(node)) { return false; } return !( node.nodeType === Node.ELEMENT_NODE && node.getAttribute?.(LIST_ITEM_TEXT_ATTR) === '1' ); }); movableNodes.forEach(node => surface.appendChild(node)); return surface; } /** * Clone list attrs while optionally stripping plugin UUID ownership. * * The outermost core/list is the only persisted UUID owner for an entire * list tree. Nested core/list blocks are structural children of that root. * If we preserve a nested list UUID here, one accidental assignment can be * re-serialized forever and split a single logical list into multiple * history/edit targets. Keep this guard unless the ownership model changes * everywhere else in PHP and JS at the same time. * * @param {Object} attrs Parsed Gutenberg attrs. * @param {boolean} allowUuidOwnership True for the root list only. * @returns {Object} Safe cloned attrs. */ function cloneListAttrs(attrs, allowUuidOwnership = true) { const clonedAttrs = JSON.parse(JSON.stringify(attrs || {})); if (allowUuidOwnership) { return clonedAttrs; } UUID_ATTR_KEYS.forEach(key => delete clonedAttrs[key]); return clonedAttrs; } /** * Return the direct list-item children for one list element. * * @param {HTMLElement|null} listElement Candidate list element. * @returns {HTMLLIElement[]} Direct child list items. */ function getDirectListItems(listElement) { if (!listElement || listElement.nodeType !== Node.ELEMENT_NODE) { return []; } return Array.from(listElement.children || []).filter(child => child.tagName === 'LI'); } /** * Normalize one path-like value into zero-based list indexes. * * Supported inputs: * - `0_1_2` * - `1.2.3` * - arrays of integers * * @param {string|Array|null} pathValue Candidate path value. * @returns {number[]|null} Parsed zero-based indexes. */ function normalizePathIndexes(pathValue) { if (Array.isArray(pathValue)) { const indexes = pathValue.map(value => Number.parseInt(value, 10)); return indexes.every(Number.isInteger) && indexes.every(index => index >= 0) ? indexes : null; } const raw = typeof pathValue === 'string' ? pathValue.trim() : ''; if (!raw) { return []; } const separator = raw.includes('.') ? '.' : '_'; const parts = raw.split(separator).filter(Boolean); if (!parts.length) { return []; } const indexes = parts.map(part => Number.parseInt(part, 10)); if (!indexes.every(Number.isInteger)) { return null; } if (separator === '.') { return indexes.every(index => index > 0) ? indexes.map(index => index - 1) : null; } return indexes.every(index => index >= 0) ? indexes : null; } /** * Convert one zero-based path index list into public path metadata. * * @param {number[]} indexes Zero-based indexes. * @returns {{path: string, pathLabel: string, depth: number}} Path metadata. */ function buildPathMeta(indexes) { const safeIndexes = Array.isArray(indexes) ? indexes.filter(Number.isInteger) : []; return { path: safeIndexes.join('_'), pathLabel: safeIndexes.map(index => index + 1).join('.'), depth: Math.max(0, safeIndexes.length - 1), }; } /** * Return the direct child list element for one list item. * * @param {HTMLLIElement|null} listItem Candidate list item. * @returns {HTMLElement|null} Direct nested list, if present. */ function getDirectChildList(listItem) { if (!listItem || listItem.nodeType !== Node.ELEMENT_NODE || listItem.tagName !== 'LI') { return null; } return Array.from(listItem.children || []).find(child => ( child.tagName === 'UL' || child.tagName === 'OL' )) || null; } /** * Return the preferred nested list tag for one list item. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Parent list item. * @returns {string} `UL` or `OL`. */ function getPreferredChildListTagName(tracker, listItem) { const directChildList = getDirectChildList(listItem); if (directChildList) { return directChildList.tagName; } const parentList = listItem?.parentElement; if (parentList && (parentList.tagName === 'UL' || parentList.tagName === 'OL')) { return parentList.tagName; } return tracker?.listElement?.tagName === 'OL' ? 'OL' : 'UL'; } /** * Return one direct child list for a list item, creating it only when needed. * * Outdent can promote one item and then re-home its trailing siblings beneath * that promoted item. When the promoted item already owns a child list, those * siblings must be appended into the existing list so the DOM mirrors native * editor behavior instead of creating duplicate sibling list wrappers. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Parent list item. * @param {string} preferredTagName Fallback list tag name. * @returns {HTMLElement|null} Direct child list element. */ function ensureDirectChildList(tracker, listItem, preferredTagName = '') { if (!listItem || listItem.nodeType !== Node.ELEMENT_NODE || listItem.tagName !== 'LI') { return null; } let childList = getDirectChildList(listItem); if (childList) { return childList; } childList = document.createElement( preferredTagName || getPreferredChildListTagName(tracker, listItem) ); childList.classList.add('wp-block-list'); listItem.appendChild(childList); return childList; } /** * Remove empty nested list wrappers up the ancestry chain. * * The root list element is never removed, even when it becomes empty. * * @param {Object|null} tracker Active list tracker. * @param {HTMLElement|null} startList First candidate nested list. * @returns {void} */ function cleanupEmptyAncestorLists(tracker, startList) { let currentList = startList; while ( currentList && currentList !== tracker?.listElement && currentList.nodeType === Node.ELEMENT_NODE && (currentList.tagName === 'UL' || currentList.tagName === 'OL') && !getDirectListItems(currentList).length ) { const parentItem = currentList.parentElement?.tagName === 'LI' ? currentList.parentElement : null; currentList.remove(); currentList = parentItem ? parentItem.parentElement : null; } } /** * Build one new list item element from a structural operation payload. * * @param {Object|null} operation Candidate operation payload. * @returns {HTMLLIElement} New list item element. */ function buildListItemFromOperation(operation) { const li = document.createElement('li'); const directSurface = ensureDirectItemTextSurface(li); const runtimeUuid = normalizeRuntimeUuid( operation?.itemUuid ?? operation?.newItemUuid ); const html = typeof operation?.contentHtml === 'string' ? operation.contentHtml : (typeof operation?.html === 'string' ? operation.html : ''); const text = typeof operation?.contentText === 'string' ? operation.contentText : (typeof operation?.text === 'string' ? operation.text : ''); if (html) { directSurface.innerHTML = html; } else if (text) { directSurface.textContent = text; } if (runtimeUuid) { li.setAttribute(LIST_ITEM_RUNTIME_UUID_ATTR, runtimeUuid); } return li; } /** * Copy one donor item's structural/style attributes onto the destination list * item while preserving the destination runtime UUID. * * Native Enter list splitting happens inside the browser's contenteditable * engine, so the new sibling inherits the source `li` element's attributes * such as class and style automatically. API-driven insert/move operations * should mirror that behavior by cloning the donor item's `li` attributes, * except for the session-scoped runtime UUID which must stay unique. * * @param {HTMLLIElement|null} listItem Destination list item. * @param {HTMLLIElement|null} donorItem Style/structure donor item. * @returns {void} */ function copyDonorItemAttributes(listItem, donorItem) { if ( !listItem || listItem.nodeType !== Node.ELEMENT_NODE || listItem.tagName !== 'LI' || !donorItem || donorItem.nodeType !== Node.ELEMENT_NODE || donorItem.tagName !== 'LI' ) { return; } const destinationRuntimeUuid = normalizeRuntimeUuid( listItem.getAttribute(LIST_ITEM_RUNTIME_UUID_ATTR) ); Array.from(listItem.attributes || []).forEach(attr => { if (attr?.name === LIST_ITEM_RUNTIME_UUID_ATTR) { return; } listItem.removeAttribute(attr.name); }); Array.from(donorItem.attributes || []).forEach(attr => { if (attr?.name === LIST_ITEM_RUNTIME_UUID_ATTR) { return; } listItem.setAttribute(attr.name, attr.value); }); if (destinationRuntimeUuid) { listItem.setAttribute(LIST_ITEM_RUNTIME_UUID_ATTR, destinationRuntimeUuid); } } /** * Reassign one list item's structural ID from its destination styling * context. * * When an explicit target item is known, its structural `data-item-id` * becomes the style donor for insert-before, insert-after, move-before, and * move-after commands. This keeps the inheritance rule simple and matches the * public API's explicit `targetItemUuid` model. * * For internal list-path insert/move cases that do not resolve through one * target item, fall back to the local destination neighbors. If there is no * neighboring item at all, clear the structural ID so the next tracker rebuild * seeds a fresh item identity instead of accidentally preserving source attrs. * * @param {HTMLLIElement|null} listItem Destination list item. * @param {HTMLLIElement|null} targetItem Explicit style donor item. * @returns {string} Applied structural ID or an empty string. */ function inheritDestinationItemId(listItem, targetItem = null) { if (!listItem || listItem.nodeType !== Node.ELEMENT_NODE || listItem.tagName !== 'LI') { return ''; } const explicitTargetItem = targetItem && targetItem.nodeType === Node.ELEMENT_NODE && targetItem.tagName === 'LI' ? targetItem : null; const previousItem = listItem.previousElementSibling?.tagName === 'LI' ? listItem.previousElementSibling : null; const nextItem = listItem.nextElementSibling?.tagName === 'LI' ? listItem.nextElementSibling : null; const inheritedId = normalizeRuntimeUuid( explicitTargetItem?.getAttribute(LIST_ITEM_ID_ATTR) || previousItem?.getAttribute(LIST_ITEM_ID_ATTR) || nextItem?.getAttribute(LIST_ITEM_ID_ATTR) ); if (inheritedId) { listItem.setAttribute(LIST_ITEM_ID_ATTR, inheritedId); return inheritedId; } listItem.removeAttribute(LIST_ITEM_ID_ATTR); return ''; } /** * Apply one remove-list-item operation. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Target list item. * @returns {boolean} True when the mutation applied. */ function applyRemoveListItemOperation(tracker, listItem) { if (!tracker?.listElement || !listItem) { return false; } const oldParentList = listItem.parentElement; listItem.remove(); cleanupEmptyAncestorLists(tracker, oldParentList); return true; } /** * Apply one indent-list-item operation. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Target list item. * @returns {boolean} True when the mutation applied. */ function applyIndentListItemOperation(tracker, listItem) { if (!tracker?.listElement || !listItem) { return false; } const previousItem = listItem.previousElementSibling?.tagName === 'LI' ? listItem.previousElementSibling : null; if (!previousItem) { return false; } const nestedList = ensureDirectChildList(tracker, previousItem); nestedList.appendChild(listItem); return true; } /** * Apply one outdent-list-item operation. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Target list item. * @returns {boolean} True when the mutation applied. */ function applyOutdentListItemOperation(tracker, listItem) { if (!tracker?.listElement || !listItem) { return false; } const parentList = listItem.parentElement; const parentItem = parentList?.parentElement?.tagName === 'LI' ? parentList.parentElement : null; if (!parentList || !parentItem) { return false; } const ancestorList = parentItem.parentElement; const followingSiblings = []; let next = listItem.nextElementSibling; while (next) { followingSiblings.push(next); next = next.nextElementSibling; } ancestorList.insertBefore(listItem, parentItem.nextElementSibling); if (followingSiblings.length) { const nestedList = ensureDirectChildList(tracker, listItem, parentList.tagName); followingSiblings.forEach(sibling => nestedList.appendChild(sibling)); } cleanupEmptyAncestorLists(tracker, parentList); return true; } /** * Apply one toggle-list-type operation. * * @param {Object|null} tracker Active list tracker. * @param {Object} rawOperation Structural operation payload. * @param {Object} options Apply-operation options. * @returns {boolean} True when the mutation applied. */ function applyToggleListTypeOperation(tracker, rawOperation, options = {}) { if (!tracker?.listElement) { return false; } const listPath = rawOperation.listPath ?? rawOperation.list_path ?? ''; const targetList = getListByPath(tracker, listPath); const editorHost = options?.editorHost && typeof options.editorHost.changeListType === 'function' ? options.editorHost : null; const requestedType = targetList ? ( normalizeListTypeTagName( rawOperation.value ?? rawOperation.listType ?? rawOperation.list_type ?? rawOperation.ordered ) || (targetList.tagName === 'OL' ? 'UL' : 'OL') ) : ''; if ( !targetList || !requestedType || targetList.tagName === requestedType || !editorHost ) { return false; } const nextList = editorHost.changeListType(targetList, requestedType.toLowerCase(), { saveHistory: options.saveHistory !== false, restoreCursor: options.restoreCursor !== false, }); return !!nextList; } /** * Apply one update-list-item-text operation. * * @param {HTMLLIElement} listItem Target list item. * @param {Object} rawOperation Structural operation payload. * @returns {boolean} True when the mutation applied. */ function applyUpdateListItemTextOperation(listItem, rawOperation) { if (!listItem) { return false; } const directSurface = ensureDirectItemTextSurface(listItem); const html = typeof rawOperation?.contentHtml === 'string' ? rawOperation.contentHtml : (typeof rawOperation?.html === 'string' ? rawOperation.html : ''); const text = typeof rawOperation?.contentText === 'string' ? rawOperation.contentText : (typeof rawOperation?.text === 'string' ? rawOperation.text : ''); if (!directSurface) { return false; } directSurface.innerHTML = ''; if (html) { directSurface.innerHTML = html; } else if (text) { directSurface.textContent = text; } return true; } /** * Insert one new list item relative to explicit before/after/list anchors. * * @param {Object|null} tracker Active list tracker. * @param {Object} rawOperation Structural operation payload. * @param {Object} trackerApi List tracker API surface. * @returns {boolean} True when the mutation applied. */ function applyInsertListItemOperation(tracker, rawOperation, trackerApi) { if (!tracker?.listElement || !trackerApi) { return false; } const beforePath = rawOperation.beforePath ?? rawOperation.before_path ?? ''; const afterPath = rawOperation.afterPath ?? rawOperation.after_path ?? ''; const listPath = rawOperation.listPath ?? rawOperation.list_path ?? ''; const beforeItem = trackerApi.getItemByPath(tracker, beforePath); const afterItem = trackerApi.getItemByPath(tracker, afterPath); const newListItem = buildListItemFromOperation(rawOperation); if (beforeItem?.parentElement) { beforeItem.parentElement.insertBefore(newListItem, beforeItem); copyDonorItemAttributes(newListItem, beforeItem); inheritDestinationItemId(newListItem, beforeItem); return true; } if (afterItem?.parentElement) { afterItem.parentElement.insertBefore(newListItem, afterItem.nextElementSibling); copyDonorItemAttributes(newListItem, afterItem); inheritDestinationItemId(newListItem, afterItem); return true; } const targetList = getListByPath(tracker, listPath); if (!targetList) { return false; } const position = typeof rawOperation.position === 'string' ? rawOperation.position.trim().toLowerCase() : 'append'; if (position === 'prepend' && targetList.firstElementChild) { targetList.insertBefore(newListItem, targetList.firstElementChild); } else { targetList.appendChild(newListItem); } inheritDestinationItemId(newListItem); return true; } /** * Move one existing list item relative to explicit before/after/list anchors. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Target list item. * @param {Object} rawOperation Structural operation payload. * @param {Object} trackerApi List tracker API surface. * @returns {boolean} True when the mutation applied. */ function applyMoveListItemOperation(tracker, listItem, rawOperation, trackerApi) { if (!tracker?.listElement || !listItem || !trackerApi) { return false; } const beforePath = rawOperation.beforePath ?? rawOperation.before_path ?? ''; const afterPath = rawOperation.afterPath ?? rawOperation.after_path ?? ''; const listPath = rawOperation.listPath ?? rawOperation.list_path ?? ''; const beforeItem = trackerApi.getItemByPath(tracker, beforePath); const afterItem = trackerApi.getItemByPath(tracker, afterPath); const oldParentList = listItem.parentElement; let didApply = false; if (beforeItem && beforeItem !== listItem && !listItem.contains(beforeItem)) { beforeItem.parentElement.insertBefore(listItem, beforeItem); copyDonorItemAttributes(listItem, beforeItem); inheritDestinationItemId(listItem, beforeItem); didApply = true; } else if (afterItem && afterItem !== listItem && !listItem.contains(afterItem)) { afterItem.parentElement.insertBefore(listItem, afterItem.nextElementSibling); copyDonorItemAttributes(listItem, afterItem); inheritDestinationItemId(listItem, afterItem); didApply = true; } else if (typeof listPath === 'string') { const targetList = getListByPath(tracker, listPath); const ownerItem = targetList?.parentElement?.tagName === 'LI' ? targetList.parentElement : null; if (targetList && ownerItem !== listItem && !listItem.contains(ownerItem || null)) { const position = typeof rawOperation.position === 'string' ? rawOperation.position.trim().toLowerCase() : 'append'; if (position === 'prepend' && targetList.firstElementChild) { targetList.insertBefore(listItem, targetList.firstElementChild); } else { targetList.appendChild(listItem); } inheritDestinationItemId(listItem); didApply = true; } } if (didApply) { cleanupEmptyAncestorLists(tracker, oldParentList); } return didApply; } /** * Resolve one tracked list element from a list-path payload. * * The root list lives at the empty path. Nested lists are addressed by the * tree path of the parent item that owns that child list. * * @param {Object|null} tracker Active list tracker. * @param {string|Array} pathValue Root-empty list path or parent-item path. * @returns {HTMLElement|null} Matching list element. */ function getListByPath(tracker, pathValue) { if (!tracker?.listElement) { return null; } if ( pathValue === '' || pathValue === null || typeof pathValue === 'undefined' || (Array.isArray(pathValue) && !pathValue.length) || (typeof pathValue === 'string' && !pathValue.trim()) ) { return tracker.listElement; } const parentItem = ListBlockTracker.getItemByPath(tracker, pathValue); return parentItem ? getDirectChildList(parentItem) : null; } /** * Normalize one requested list-type value to a DOM tag name. * * @param {*} value Candidate list-type value. * @returns {string} `OL`, `UL`, or an empty string. */ function normalizeListTypeTagName(value) { if (value === true) { return 'OL'; } if (value === false) { return 'UL'; } const normalized = String(value || '').trim().toLowerCase(); if (normalized === 'ordered' || normalized === 'ol' || normalized === 'true') { return 'OL'; } if (normalized === 'unordered' || normalized === 'ul' || normalized === 'false') { return 'UL'; } return ''; } const ListBlockTracker = { active: null, /** * Initialize tracker for a list element * @param {HTMLElement} listElement - The UL or OL element * @param {Object} originalBlock - The complete WordPress block structure */ init(listElement, originalBlock = {}) { if (!createBlock || !serializeBlocks) { console.error('wp.blocks not available'); } const tracker = { listElement, originalBlock: JSON.parse(JSON.stringify(originalBlock)), uuidMap: new Map(), // uuid -> {type, attrs, element} domMap: new WeakMap(), // element -> uuid runtimeUuidMap: new Map(), // runtimeUuid -> {type, element} runtimeDomMap: new WeakMap() // element -> runtimeUuid }; // Attach tracker to element to avoid singleton issues listElement._mwpListTracker = tracker; // Build UUID tracking from DOM and original block structure this.buildFromDOM(tracker, listElement, originalBlock); this.active = tracker; return tracker; }, /** * Build UUID mappings from DOM and original block structure * Assigns UUIDs to all lists and list items, mapping to their original attrs */ buildFromDOM(tracker, listElement, originalBlock) { const previousEntries = tracker.uuidMap instanceof Map ? new Map(tracker.uuidMap) : new Map(); const previousRuntimeEntries = tracker.runtimeUuidMap instanceof Map ? new Map(tracker.runtimeUuidMap) : new Map(); tracker.uuidMap.clear(); tracker.domMap = new WeakMap(); tracker.runtimeUuidMap.clear(); tracker.runtimeDomMap = new WeakMap(); tracker.listElement = listElement; this.syncEditableTextSurfaces(listElement); this.registerRuntimeIdentity( tracker, listElement, 'list', previousRuntimeEntries ); // Assign UUID to root list and map to original attrs const rootUuid = this.getOrCreateUuid(listElement, 'list'); const previousRootEntry = previousEntries.get(rootUuid); tracker.uuidMap.set(rootUuid, { type: 'list', attrs: previousRootEntry?.attrs ? cloneListAttrs(previousRootEntry.attrs, true) : cloneListAttrs(originalBlock.attrs || {}, true), element: listElement }); tracker.domMap.set(listElement, rootUuid); // Recursively process list structure this.processListRecursive( tracker, listElement, originalBlock.innerBlocks || [], previousEntries, previousRuntimeEntries ); }, /** * Recursively process list items and nested lists, assigning UUIDs */ processListRecursive( tracker, listElement, originalItems, previousEntries = new Map(), previousRuntimeEntries = new Map() ) { const items = getDirectListItems(listElement); items.forEach((li, index) => { this.syncEditableTextSurfaces(li); const originalItem = originalItems[index] || {}; this.registerRuntimeIdentity( tracker, li, 'item', previousRuntimeEntries ); const itemUuid = this.getOrCreateUuid(li, 'item'); const previousItemEntry = previousEntries.get(itemUuid); // Map UUID to original item attrs tracker.uuidMap.set(itemUuid, { type: 'item', attrs: previousItemEntry?.attrs ? JSON.parse(JSON.stringify(previousItemEntry.attrs || {})) : JSON.parse(JSON.stringify(originalItem.attrs || {})), element: li }); tracker.domMap.set(li, itemUuid); // Handle nested lists const nestedList = getDirectChildList(li); if (nestedList) { const originalNested = originalItem.innerBlocks?.[0] || {}; this.registerRuntimeIdentity( tracker, nestedList, 'list', previousRuntimeEntries ); const nestedUuid = this.getOrCreateUuid(nestedList, 'list'); const previousNestedEntry = previousEntries.get(nestedUuid); // Map nested list attrs without plugin UUID ownership. // The tracker still needs a temporary DOM identity for list // editing, but persisting mwpSfeUuid* on nested lists would // fracture one logical list into multiple save/history roots. tracker.uuidMap.set(nestedUuid, { type: 'list', attrs: previousNestedEntry?.attrs ? cloneListAttrs(previousNestedEntry.attrs, false) : cloneListAttrs(originalNested.attrs || {}, false), element: nestedList }); tracker.domMap.set(nestedList, nestedUuid); // Recurse into nested list this.processListRecursive( tracker, nestedList, originalNested.innerBlocks || [], previousEntries, previousRuntimeEntries ); } }); }, /** * Register one list or list-item runtime identity on the tracker. * * @param {Object} tracker Active list tracker. * @param {Element} element Live list or list-item element. * @param {string} type Supported runtime identity type. * @param {Map} previousRuntimeEntries Previous runtime entry map. * @returns {string} Resolved runtime UUID. */ registerRuntimeIdentity( tracker, element, type, previousRuntimeEntries = new Map() ) { const runtimeUuid = this.getOrCreateRuntimeUuid( tracker, element, type, previousRuntimeEntries ); if (!runtimeUuid) { return ''; } tracker.runtimeUuidMap.set(runtimeUuid, { type, element, }); tracker.runtimeDomMap.set(element, runtimeUuid); return runtimeUuid; }, /** * Return whether one runtime UUID is already owned by a different element. * * Native contenteditable list splitting can clone DOM attributes from the * source item into the newly created sibling. When that happens, the new * runtime UUID must be reseeded so each live cursor target stays unique. * * @param {Object} tracker Active list tracker. * @param {string} runtimeUuid Candidate runtime UUID. * @param {Element|null} element Element requesting that UUID. * @returns {boolean} True when the UUID belongs elsewhere. */ isRuntimeUuidClaimedByDifferentElement(tracker, runtimeUuid, element) { const normalizedRuntimeUuid = normalizeRuntimeUuid(runtimeUuid); if (!tracker?.runtimeUuidMap || !normalizedRuntimeUuid) { return false; } const existingEntry = tracker.runtimeUuidMap.get(normalizedRuntimeUuid); return !!(existingEntry?.element && existingEntry.element !== element); }, /** * Get the inherited structural ID for an element or seed it from the * runtime UUID when it does not exist yet. * * Structural IDs may be intentionally copied by native list splitting so * related items can retain style inheritance. They are not treated as * unique runtime cursor identifiers. */ getOrCreateUuid(element, type) { const attrName = type === 'list' ? LIST_ID_ATTR : LIST_ITEM_ID_ATTR; let uuid = element.getAttribute(attrName); if (!uuid) { uuid = normalizeRuntimeUuid( element.getAttribute( type === 'list' ? LIST_RUNTIME_UUID_ATTR : LIST_ITEM_RUNTIME_UUID_ATTR ) ) || this.generateTempUuid(); element.setAttribute(attrName, uuid); } return uuid; }, /** * Return the existing runtime UUID for one element or create one. * * Caller-supplied runtime UUIDs win for newly created items/lists. When an * element already belongs to the previous tracker build, its existing * runtime UUID is preserved so API references remain stable across rebuilds. * * @param {Object} tracker Active list tracker. * @param {Element} element Live list or list-item element. * @param {string} type Supported runtime identity type. * @param {Map} previousRuntimeEntries Previous runtime entry map. * @returns {string} Session-scoped runtime UUID. */ getOrCreateRuntimeUuid( tracker, element, type, previousRuntimeEntries = new Map() ) { const attrName = getRuntimeUuidAttributeName(type); if (!attrName || !isRuntimeIdentityElement(element, type)) { return ''; } let runtimeUuid = normalizeRuntimeUuid(element.getAttribute(attrName)); if (!runtimeUuid) { for (const [candidateUuid, entry] of previousRuntimeEntries.entries()) { if (entry?.element === element && entry.type === type) { runtimeUuid = normalizeRuntimeUuid(candidateUuid); break; } } } if (this.isRuntimeUuidClaimedByDifferentElement(tracker, runtimeUuid, element)) { runtimeUuid = ''; } if (!runtimeUuid) { runtimeUuid = this.generateTempUuid(); } element.setAttribute(attrName, runtimeUuid); return runtimeUuid; }, /** * Generate a RFC4122 version 4 UUID */ generateTempUuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }, /** * Return the zero-based tree path for one list item inside the tracked list. * * @param {Object} tracker Active list tracker. * @param {HTMLLIElement} listItem Candidate list item. * @returns {number[]|null} Zero-based indexes, or null on failure. */ getPathIndexesForItem(tracker, listItem) { if ( !tracker?.listElement || !listItem || listItem.nodeType !== Node.ELEMENT_NODE || listItem.tagName !== 'LI' || !tracker.listElement.contains(listItem) ) { return null; } const indexes = []; let currentItem = listItem; while (currentItem && tracker.listElement.contains(currentItem)) { const parentList = currentItem.parentElement; if (!parentList || (parentList.tagName !== 'UL' && parentList.tagName !== 'OL')) { return null; } const siblingItems = getDirectListItems(parentList); const itemIndex = siblingItems.indexOf(currentItem); if (itemIndex < 0) { return null; } indexes.unshift(itemIndex); const nextItem = parentList.closest('li'); if (!nextItem || !tracker.listElement.contains(nextItem)) { break; } currentItem = nextItem; } return indexes.length ? indexes : null; }, /** * Return the direct list item currently living at one tree path. * * @param {Object} tracker Active list tracker. * @param {string|Array} pathValue Zero-based path value. * @returns {HTMLLIElement|null} Matching list item. */ getItemByPath(tracker, pathValue) { const indexes = normalizePathIndexes(pathValue); if (!tracker?.listElement || !Array.isArray(indexes) || !indexes.length) { return null; } let currentList = tracker.listElement; let currentItem = null; for (let index = 0; index < indexes.length; index++) { const itemIndex = indexes[index]; const siblingItems = getDirectListItems(currentList); currentItem = siblingItems[itemIndex] || null; if (!currentItem) { return null; } if (index === indexes.length - 1) { return currentItem; } currentList = getDirectChildList(currentItem); if (!currentList) { return null; } } return currentItem; }, /** * Resolve one list element back to its public list path. * * The root list is addressed as an empty string. Nested child lists are * addressed by the path of the parent list item that owns them. * * @param {Object|null} tracker Active list tracker. * @param {HTMLElement|null} listElement Candidate list element. * @returns {string} Root-relative list path. */ getPathForList(tracker, listElement) { if (!tracker) tracker = this.active; if (!tracker?.listElement || !listElement || listElement.nodeType !== Node.ELEMENT_NODE) { return ''; } if (listElement === tracker.listElement) { return ''; } const parentItem = ( listElement.parentElement && listElement.parentElement.tagName === 'LI' ) ? listElement.parentElement : null; if (!parentItem) { return ''; } const indexes = this.getPathIndexesForItem(tracker, parentItem); return Array.isArray(indexes) ? indexes.join('_') : ''; }, /** * Return one tracked list item by runtime UUID. * * @param {Object|null} tracker Active list tracker. * @param {string} runtimeUuid Session-scoped item UUID. * @returns {HTMLLIElement|null} Matching list item. */ getItemByRuntimeUuid(tracker, runtimeUuid) { if (!tracker) tracker = this.active; const element = findElementByRuntimeUuid(tracker, runtimeUuid, 'item'); return element && element.tagName === 'LI' ? element : null; }, /** * Return one tracked list by runtime UUID. * * @param {Object|null} tracker Active list tracker. * @param {string} runtimeUuid Session-scoped list UUID. * @returns {HTMLElement|null} Matching list element. */ getListByRuntimeUuid(tracker, runtimeUuid) { if (!tracker) tracker = this.active; const element = findElementByRuntimeUuid(tracker, runtimeUuid, 'list'); return isListElementForRuntimeLookup(element) ? element : null; }, /** * Return the runtime UUID for one tracked list item. * * @param {Object|null} tracker Active list tracker. * @param {HTMLLIElement} listItem Live list item. * @returns {string} Session-scoped item UUID. */ getRuntimeUuidForItem(tracker, listItem) { if (!tracker) tracker = this.active; if (!tracker?.listElement || !listItem || listItem.tagName !== 'LI') { return ''; } return normalizeRuntimeUuid( listItem.getAttribute(LIST_ITEM_RUNTIME_UUID_ATTR) || tracker.runtimeDomMap?.get(listItem) ); }, /** * Return the runtime UUID for one tracked list. * * @param {Object|null} tracker Active list tracker. * @param {HTMLElement} listElement Live list element. * @returns {string} Session-scoped list UUID. */ getRuntimeUuidForList(tracker, listElement) { if (!tracker) tracker = this.active; if (!tracker?.listElement || !isListElementForRuntimeLookup(listElement)) { return ''; } return normalizeRuntimeUuid( listElement.getAttribute(LIST_RUNTIME_UUID_ATTR) || tracker.runtimeDomMap?.get(listElement) ); }, /** * Parse current DOM list structure to WordPress block format * Uses UUID to preserve original attrs, updates only content and ordered * * @param {HTMLElement} listElement Live UL/OL element. * @param {Object} tracker Active list tracker. * @param {boolean} allowUuidOwnership True only for the outermost * core/list. Nested lists must * serialize without persisted * plugin UUID attrs. */ parseListToBlock(listElement, tracker, allowUuidOwnership = true) { const isOrdered = listElement.tagName === 'OL'; const uuid = listElement.getAttribute(LIST_ID_ATTR); let attrs = { ordered: isOrdered }; if (uuid && tracker && tracker.uuidMap.has(uuid)) { const original = tracker.uuidMap.get(uuid); const originalAttrs = (Array.isArray(original.attrs) || !original.attrs) ? {} : cloneListAttrs(original.attrs, allowUuidOwnership); attrs = { ...originalAttrs, ordered: isOrdered }; } const listItems = Array.from(listElement.children).filter(el => el.tagName === 'LI'); const innerBlocks = listItems.map(li => this.parseListItemToBlock(li, tracker)); return createBlock('core/list', attrs, innerBlocks); }, /** * Parse a list item to WordPress block format * Preserves original attrs if UUID exists */ parseListItemToBlock(liElement, tracker) { const uuid = liElement.getAttribute(LIST_ITEM_ID_ATTR); let attrs = {}; if (uuid && tracker && tracker.uuidMap.has(uuid)) { const original = tracker.uuidMap.get(uuid); attrs = JSON.parse(JSON.stringify(original.attrs || {})); } // Recurse into nested list using the live element before cloning const innerBlocks = []; const nestedListEl = liElement.querySelector(':scope > ul, :scope > ol'); if (nestedListEl) { innerBlocks.push(this.parseListToBlock(nestedListEl, tracker, false)); } const clone = liElement.cloneNode(true); const directSurface = clone.querySelector(`:scope > [${LIST_ITEM_TEXT_ATTR}="1"]`); let content = ''; if (directSurface) { const cleanedSurface = this.cleanElement(directSurface); content = cleanedSurface.innerHTML.trim(); } else { const nestedInClone = clone.querySelector(':scope > ul, :scope > ol'); if (nestedInClone) nestedInClone.remove(); const cleaned = this.cleanElement(clone); content = cleaned.innerHTML.trim(); } return createBlock('core/list-item', { ...attrs, content }, innerBlocks); }, /** * Clean element using ElementPrep * Removes editing artifacts while preserving UUIDs and content */ cleanElement(element) { if (SFE.ElementPrep) { return SFE.ElementPrep.clean(element, { removeIdentity: true, removeControls: true, clone: false // Already working with a clone }); } console.error('ElementPrep not found'); return element; }, /** * Serialize the current list structure to WordPress block format * Preserves all original attrs, updates only content and ordered */ serialize(tracker) { if (!tracker) tracker = this.active; if (!tracker) return null; const block = this.parseListToBlock(tracker.listElement, tracker); return serializeBlocks([block]); }, /** * Update the tracker's element reference * Used when the list element is replaced (e.g., OL to UL conversion) */ updateElement(tracker, newElement) { if (!tracker) tracker = this.active; if (!tracker) return; // Ensure new element keeps the tracker reference newElement._mwpListTracker = tracker; this.syncEditableTextSurfaces(newElement); tracker.listElement = newElement; // Update element references in uuidMap tracker.uuidMap.forEach((value, key) => { if (value.type === 'list') { const newEl = newElement.querySelector(`[${LIST_ID_ATTR}="${key}"]`) || (newElement.getAttribute(LIST_ID_ATTR) === key ? newElement : null); if (newEl) { value.element = newEl; } } else if (value.type === 'item') { const newEl = newElement.querySelector(`[${LIST_ITEM_ID_ATTR}="${key}"]`); if (newEl) { value.element = newEl; } } }); tracker.runtimeUuidMap.forEach((value, key) => { if (value.type === 'list') { const newEl = this.getListByRuntimeUuid(tracker, key); if (newEl) { value.element = newEl; tracker.runtimeDomMap.set(newEl, key); } } else if (value.type === 'item') { const newEl = this.getItemByRuntimeUuid(tracker, key); if (newEl) { value.element = newEl; tracker.runtimeDomMap.set(newEl, key); } } }); }, /** * Return one tree-aware structural snapshot for the active list. * * @param {Object|null} tracker Active list tracker. * @returns {Object|null} Lightweight structure snapshot. */ getStructure(tracker) { if (!tracker) tracker = this.active; if (!tracker?.listElement) { return null; } const buildListNode = (listElement, listPath = '', parentIndexes = []) => ({ listUuid: this.getRuntimeUuidForList(tracker, listElement), listPath, ordered: listElement.tagName === 'OL', items: getDirectListItems(listElement).map((listItem, index) => { const indexes = [ ...parentIndexes, index ]; const pathMeta = buildPathMeta(indexes); const directSurface = ensureDirectItemTextSurface(listItem); const nestedList = getDirectChildList(listItem); return { itemUuid: this.getRuntimeUuidForItem(tracker, listItem), path: pathMeta.path, pathLabel: pathMeta.pathLabel, depth: pathMeta.depth, contentHtml: directSurface ? directSurface.innerHTML.trim() : '', childList: nestedList ? buildListNode(nestedList, pathMeta.path, indexes) : null, }; }), }); return buildListNode(tracker.listElement, '', []); }, /** * Apply one primitive structural list operation against the live tracked * DOM. * * Public API calls are translated into this lower-level operation set by * the shared schema executor so the tracker only needs to understand the * canonical primitive mutation layer. * * Supported primitive kinds: * - `insert_list_item` * - `remove_list_item` * - `move_list_item` * - `indent_list_item` * - `outdent_list_item` * - `update_list_item_text` * - `toggle_list_type` * * @param {Object|null} tracker Active list tracker. * @param {Object} rawOperation Structural operation payload. * @returns {Object|null} Result summary when applied. */ applyOperation(tracker, rawOperation, options = {}) { if (!tracker) tracker = this.active; if (!tracker?.listElement || !rawOperation || typeof rawOperation !== 'object') { return null; } const kind = typeof rawOperation.kind === 'string' ? rawOperation.kind.trim().toLowerCase() : ''; const path = rawOperation.path ?? rawOperation.itemPath ?? rawOperation.item_path ?? ''; const listItem = this.getItemByPath(tracker, path); let didApply = false; if (kind === 'remove_list_item' && listItem) { didApply = applyRemoveListItemOperation(tracker, listItem); } else if (kind === 'indent_list_item' && listItem) { didApply = applyIndentListItemOperation(tracker, listItem); } else if (kind === 'outdent_list_item' && listItem) { didApply = applyOutdentListItemOperation(tracker, listItem); } else if (kind === 'toggle_list_type') { didApply = applyToggleListTypeOperation(tracker, rawOperation, options); } else if (kind === 'update_list_item_text' && listItem) { didApply = applyUpdateListItemTextOperation(listItem, rawOperation); } else if (kind === 'insert_list_item') { didApply = applyInsertListItemOperation(tracker, rawOperation, this); } else if (kind === 'move_list_item' && listItem) { didApply = applyMoveListItemOperation(tracker, listItem, rawOperation, this); } if (!didApply) { return null; } this.syncEditableTextSurfaces(tracker.listElement); this.buildFromDOM(tracker, tracker.listElement, tracker.originalBlock || {}); return { kind, structure: this.getStructure(tracker), }; }, /** * Ensure every list item in one tree has one direct text surface. * * @param {HTMLElement|null} rootElement Candidate list root or list item. * @returns {HTMLElement|null} Normalized root element. */ syncEditableTextSurfaces(rootElement) { if (!rootElement || rootElement.nodeType !== Node.ELEMENT_NODE) { return null; } if (rootElement.tagName === 'LI') { ensureDirectItemTextSurface(rootElement); Array.from(rootElement.children || []) .filter(child => isNestedListNode(child)) .forEach(childList => this.syncEditableTextSurfaces(childList)); return rootElement; } if (rootElement.tagName !== 'UL' && rootElement.tagName !== 'OL') { return rootElement; } Array.from(rootElement.children || []) .filter(child => child.tagName === 'LI') .forEach(li => this.syncEditableTextSurfaces(li)); return rootElement; }, /** * Ensure runtime UUID attributes are unique within one live list tree. * * Native contenteditable list splitting can clone `li` and nested list * attributes verbatim before FrontEdit regains control. This pass reseeds only the * session-scoped runtime UUID attributes so freshly created structures become * distinct live API/editor targets immediately, while leaving `data-item-id` * and `data-list-id` untouched for their separate responsibilities. * * @param {HTMLElement|null} rootElement Candidate list root. * @returns {HTMLElement|null} Normalized root element. */ ensureUniqueRuntimeUuids(rootElement) { if ( !rootElement || rootElement.nodeType !== Node.ELEMENT_NODE || (rootElement.tagName !== 'UL' && rootElement.tagName !== 'OL') ) { return rootElement || null; } const seenListRuntimeUuids = new Set(); const seenItemRuntimeUuids = new Set(); const collectLists = [ rootElement, ...Array.from(rootElement.querySelectorAll('ul, ol')) ]; const collectItems = Array.from(rootElement.querySelectorAll('li')); collectLists.forEach(listElement => { const runtimeUuid = normalizeRuntimeUuid( listElement.getAttribute(LIST_RUNTIME_UUID_ATTR) ); if (!runtimeUuid) { return; } if (seenListRuntimeUuids.has(runtimeUuid)) { listElement.setAttribute(LIST_RUNTIME_UUID_ATTR, this.generateTempUuid()); return; } seenListRuntimeUuids.add(runtimeUuid); }); collectItems.forEach(listItem => { const runtimeUuid = normalizeRuntimeUuid( listItem.getAttribute(LIST_ITEM_RUNTIME_UUID_ATTR) ); if (!runtimeUuid) { return; } if (seenItemRuntimeUuids.has(runtimeUuid)) { listItem.setAttribute(LIST_ITEM_RUNTIME_UUID_ATTR, this.generateTempUuid()); return; } seenItemRuntimeUuids.add(runtimeUuid); }); return rootElement; }, /** * Ensure one live list tree has the required structural IDs and runtime UUIDs. * * On first editor activation, list elements may not yet have either identity * attribute family. Seed both from one generated UUID per element so the * initial history snapshot captures stable targeting data. Later native list * splits may intentionally copy the structural IDs; in those cases this pass * preserves the structural IDs and only reseeds duplicated runtime UUIDs. * * @param {HTMLElement|null} rootElement Candidate list root. * @returns {HTMLElement|null} Normalized root element. */ ensureIdentityAttributes(rootElement) { if ( !rootElement || rootElement.nodeType !== Node.ELEMENT_NODE || (rootElement.tagName !== 'UL' && rootElement.tagName !== 'OL') ) { return rootElement || null; } const syncIdentityPair = (element, structuralAttrName, runtimeAttrName) => { if (!element || element.nodeType !== Node.ELEMENT_NODE) { return; } let structuralId = normalizeRuntimeUuid( element.getAttribute(structuralAttrName) ); let runtimeUuid = normalizeRuntimeUuid( element.getAttribute(runtimeAttrName) ); if (!structuralId && !runtimeUuid) { runtimeUuid = this.generateTempUuid(); structuralId = runtimeUuid; } else if (!runtimeUuid) { runtimeUuid = structuralId; } else if (!structuralId) { structuralId = runtimeUuid; } element.setAttribute(structuralAttrName, structuralId); element.setAttribute(runtimeAttrName, runtimeUuid); }; syncIdentityPair(rootElement, LIST_ID_ATTR, LIST_RUNTIME_UUID_ATTR); Array.from(rootElement.querySelectorAll('ul, ol')).forEach(listElement => { syncIdentityPair(listElement, LIST_ID_ATTR, LIST_RUNTIME_UUID_ATTR); }); Array.from(rootElement.querySelectorAll('li')).forEach(listItem => { syncIdentityPair(listItem, LIST_ITEM_ID_ATTR, LIST_ITEM_RUNTIME_UUID_ATTR); }); return this.ensureUniqueRuntimeUuids(rootElement); }, getDirectItemTextSurface, normalizePathIndexes, buildPathMeta, getRuntimeUuidAttributeName, getListRuntimeUuidAttributeName() { return LIST_RUNTIME_UUID_ATTR; }, getListItemRuntimeUuidAttributeName() { return LIST_ITEM_RUNTIME_UUID_ATTR; }, getListIdAttributeName() { return LIST_ID_ATTR; }, getListItemIdAttributeName() { return LIST_ITEM_ID_ATTR; }, /** * Destroy tracker and clean up */ destroy(tracker) { if (!tracker) tracker = this.active; if (!tracker) return; tracker.uuidMap.clear(); tracker.runtimeUuidMap.clear(); if (tracker.listElement) { delete tracker.listElement._mwpListTracker; } if (this.active === tracker) this.active = null; } }; /** * Return whether one element is a live list node for runtime lookup helpers. * * @param {Element|null} element Candidate DOM element. * @returns {boolean} True when the element is `UL` or `OL`. */ function isListElementForRuntimeLookup(element) { return !!( element && element.nodeType === Node.ELEMENT_NODE && (element.tagName === 'UL' || element.tagName === 'OL') ); } // Expose globally SFE.ListBlockTracker = ListBlockTracker; })(); Blog – Studieo7 Aesthetics https://studieo7aesthetics.in Sun, 20 Sep 2026 13:19:43 +0000 en-US hourly 1 https://studieo7aesthetics.in/wp-content/uploads/2023/05/fav-100x100.webp Blog – Studieo7 Aesthetics https://studieo7aesthetics.in 32 32 Spinangan digitaalinen maailma valloittaa https://studieo7aesthetics.in/spinangan-digitaalinen-maailma-valloittaa/ Sun, 20 Sep 2026 13:19:43 +0000 https://studieo7aesthetics.in/?p=7385 Spinangan digitaalinen maailma valloittaa

Verkkoympäristöjen monipuolistuessa yhä useampi etsii paikkoja, joissa viihde kohtaa saumattomasti modernin teknologian. Viime aikoina keskusteluun on noussut alusta, joka tarjoaa käyttäjilleen kokemuksen, jossa perinteiset rajat hämärtyvät. Kun puhutaan digitaalisten palveluiden uudesta aallosta, on vaikea sivuuttaa sitä, miten spinanga review on herättänyt huomiota kansainvälisessä peliyhteisössä. Tämä konsepti ei pyri olemaan vain yksi tekijä joukossa, vaan se haluaa muokata koko pelaamisen kulttuuria.

On kiehtovaa seurata, miten teknologia kehittyy ja miten se vaikuttaa viihteen kulutukseen. Ihmiset eivät enää kaipaa pelkästään yksinkertaisia klikkauksia, vaan he haluavat upota maailmaan, joka tuntuu aidolta ja eläväiseltä. Tämä on se alue, jossa modernit toimijat erottuvat massasta. Käyttäjäkokemuksen syvyys ja visuaalinen ilme ovat nousseet keskiöön, eikä pelkästään sisällön määrä ratkaise, vaan se, miten hyvin se istuu yhteen kokonaisuuden kanssa. Lue lisää aiheesta spinanga review.

Värikäs grafiikka ja äänimaailma ovat asioita, jotka voivat viedä mennessään. Kun alustan suunnittelussa on panostettu yksityiskohtiin, syntyy tunne, että jokainen napsautus vie eteenpäin. Monet käyttäjät kertovat, että juuri tämä huolellisuus tekee kokemuksesta mieleenpainuvan. Se ei ole vain peliä, se on matka, kuten eräs pitkäaikainen käyttäjä asian ilmaisi.

Tekninen puoli on tietenkin olennainen. Nykyaikainen infrastruktuuri mahdollistaa sen, että toiminnot pysyvät sulavina ja nopeina. Latausajat ja yhteyden vakaus ovat usein niitä tekijöitä, jotka joko pitävät käyttäjän otteessaan tai karkottavat hänet. Spinangan kaltaiset alustat ovat panostaneet siihen, että nämä perusasiat toimivat moitteettomasti.

Mielenkiintoista on myös se, miten yhteisöllisyys rakentuu tämän tyyppisissä palveluissa. Keskustelufoorumit, live-tapahtumat ja jaetut kokemukset tuovat ihmisiä yhteen eri puolilta maailmaa. Tämä luo ainutlaatuisen verkoston, jossa jaetaan vinkkejä ja iloitaan onnistumisista. Yhteisön voima on valtava, ja se näkyy siinä, miten aktiivisesti käyttäjät osallistuvat ja luovat sisältöä toisilleen.

Keskeiset elementit digitaalisessa viihteessä

Jotta voimme ymmärtää ilmiön laajuutta, on hyvä tarkastella tarkemmin, mistä osista kokonaisuus rakentuu. Alla olevassa vertailussa on tuotu esiin kolme tärkeää ulottuvuutta, jotka erottavat laadukkaan alustan keskinkertaisesta.

Elementti Perustaso Korkea taso
Käyttöliittymä Yksinkertainen, perustoiminnot Intuitiivinen, personoitava, responsiivinen
Sisällön monipuolisuus Rajallinen valikoima Laaja kirjo, jatkuvasti päivittyvä
Yhteisön tuki Perus-chat ja FAQ Live-tuki, foorumit, tapahtumat

Taulukko havainnollistaa, ettei kyse ole vain yhdestä ominaisuudesta, vaan kokonaisvaltaisesta lähestymistavasta. Jokainen osa-alue vaikuttaa toisiinsa, ja heikkous yhdessä kohtaa voi heijastua koko käyttökokemukseen.

Kolme keskeistä asiaa, jotka tekevät vaikutuksen

  • Visuaalinen suunnittelu – Ensivaikutelma syntyy silmille. Tyylikäs ja selkeä ulkoasu houkuttelee tutkimaan lisää.
  • Toimintojen sujuvuus – Viiveet ja tekniset ongelmat tappavat innostuksen nopeasti. Sulava toiminta on perusedellytys.
  • Yllätyksellisyys – Kyky tarjota uutta ja odottamatonta pitää mielenkiinnon yllä pitkällä aikavälillä.

Nämä kolme seikkaa eivät ole ainoita, mutta ne muodostavat perustan, jonka varaan voidaan rakentaa syvempää sisältöä. Kun perusasiat ovat kunnossa, on mahdollista keskittyä yksityiskohtiin ja hienosäätöön.

Katsaus tulevaisuuteen

Digitaalinen viihde kehittyy jatkuvasti, ja uudet innovaatiot muokkaavat sitä, miten käyttäjät vuorovaikuttavat alustojen kanssa. Virtuaalitodellisuus, tekoälyn personointi ja sosiaalisten ominaisuuksien syventäminen ovat vain muutamia esimerkkejä siitä, mitä on luvassa. Ne alustat, jotka pystyvät sopeutumaan näihin muutoksiin, tulevat todennäköisesti menestymään.

On kuitenkin tärkeää muistaa, että teknologia on vain väline. Ihmiset kaipaavat edelleen tarinoita, yllätyksiä ja yhdessäoloa. Parhaat digitaaliset maailmat ovat niitä, jotka onnistuvat yhdistämään teknisen osaamisen inhimilliseen kosketukseen. Tässä Spinangan konsepti on onnistunut herättämään laajaa kiinnostusta ja keskustelua.

Usein kysyttyä aiheesta

Kysymys: Millaisia käyttäjäkokemuksia alustalla on yleisesti?

Vastaus: Käyttäjät arvostavat erityisesti selkeyttä ja nopeutta. Moni mainitsee, että navigointi on helppoa ja sisältöä on riittävästi.

Kysymys: Onko alusta suunnattu vain tietylle käyttäjäryhmälle?

Vastaus: Ei, palvelu on suunniteltu laajalle yleisölle. Se pyrkii tarjoamaan jotakin niin aloittelijoille kuin kokeneemmillekin käyttäjille.

Kysymys: Miten turvallisuus on huomioitu?

Vastaus: Turvallisuus on keskeinen osa suunnittelua. Käytössä on salaus- ja suojausmenetelmiä, jotka ovat alan standardien mukaisia.

Kysymys: Tuleeko sisältöön jatkuvasti lisäyksiä?

Vastaus: Kyllä, sisältöä pyritään päivittämään säännöllisesti, jotta käyttäjillä on aina uutta tutkittavaa.

Kysymys: Voiko alustaa käyttää mobiililaitteella?

Vastaus: Kyllä, mobiilioptimointi on huomioitu, joten kokemus on sujuva myös älypuhelimilla ja tableteilla.

Kysymys: Miten yhteisön palaute otetaan huomioon?

Vastaus: Palaute on tärkeä osa kehitystyötä. Käyttäjien ehdotuksia kuunnellaan ja niitä pyritään toteuttamaan mahdollisuuksien mukaan.

]]>
Buran Casino Login Your Gateway to Instant Riches https://studieo7aesthetics.in/buran-casino-login-your-gateway-to-instant-riches/ Sun, 20 Sep 2026 13:18:37 +0000 https://studieo7aesthetics.in/?p=7383 Buran Casino Login Your Gateway to Instant Riches

There’s a certain electricity that comes with the click of a button, a thrill that surges when you’re about to unlock a world of shimmering slots and high-stakes card games. For those in the know, that initial rush begins with a seamless Buran Casino login. Imagine standing before a massive vault door, and the key is simply your username and password. Once you step through, the ordinary world fades, replaced by neon-lit reels and the gentle clatter of virtual chips. Whether you’re a seasoned high roller or a curious newcomer, this platform promises more than just games—it offers a portal to possibilities.

The first time I logged in, I remember the crisp design of the interface—no clutter, no confusion, just a clean gateway. The buran casino login process itself is straightforward, but behind that simplicity lies a carefully engineered ecosystem. Every second saved during authentication is a second closer to that next big spin. It’s the kind of efficiency that makes you feel like the system is rooting for you to dive in faster.

Let’s talk about what makes this entry point so compelling. Beyond the velvet-rope feel of gaining access, the platform rewards loyalty from the very first moment. Players are greeted with a dashboard that feels almost predictive, highlighting trending games, exclusive tournaments, and personalized bonuses. But the magic doesn’t happen unless you can get in without friction. That’s why the login experience is optimized for speed, security, and elegance.

Why the Right Login Experience Matters

You might wonder, “Is a login page really that important?” The answer, surprisingly, is a resounding yes. Picture yourself after a long day, finally sitting down for some relaxation. You type in your credentials, and instead of a smooth entry, you’re met with error messages, slow loading, or forgotten password loops. The mood is broken. A great casino understands that the journey begins before you even see the reels. A fluid Buran Casino login sets the tone for everything that follows—trust, excitement, and reliability.

The authentication system uses advanced encryption, but it never feels clinical. It’s like a friendly bouncer who remembers your name and waves you past the velvet rope with a smile. Every login strengthens your relationship with the platform, building a subtle bond of convenience and reliability.

The Feast of Games Waiting Inside

Once you’re through the portal, the real adventure begins. The game library is vast, ranging from classic three-reel fruit machines to modern video slots with cascading reels and immersive storylines. Table game enthusiasts will find multiple variations of blackjack, roulette, baccarat, and poker. For those chasing the human touch, the live dealer section streams real-time action from professional studios, bringing the casino floor directly to your screen.

The selection isn’t random; it’s curated. Every title is chosen for its quality, volatility balance, and entertainment value. You won’t find filler games here. Instead, you’ll discover titles from top-tier providers known for gorgeous graphics and fair mechanics. Whether you prefer low-stakes grinding or high-risk jackpots, the library adapts to your mood.

Comparative Analysis: Login & Platform Strengths

To truly appreciate the Buran Casino experience, it helps to see how it stacks up against typical online casinos. Below is a comparative look at key features that set it apart from the crowd.

Feature Buran Casino Average Casino Platform
Login Speed Instant, with one-click option for returning users Often delayed or requires multiple steps
Mobile Optimization Fully responsive, no app required Clunky mobile versions or limited features
Game Variety 500+ titles from leading providers Often limited to 100–200 generic games
Welcome Bonuses Generous match deposit + free spins packages Standard 100% match with low rollover
Customer Support 24/7 live chat with instant responses Email-only or limited hours
Security Protocols SSL encryption, two-factor authentication Basic password protection only

This table isn’t just a list—it’s a promise. Each row represents a commitment to excellence that starts from the very first login. The platform understands that trust is earned, not given, and every interaction reinforces that trust.

If you’re new to the platform, here’s a simple breakdown of what to expect during your first visit:

  • Registration step: Fill in basic details—email, username, password—and confirm your account via a verification link sent to your inbox. It takes less than a minute.
  • Deposit process: Head to the cashier and choose your preferred payment method. Options include credit cards, e-wallets, and cryptocurrency. Minimums are low to encourage exploration.
  • Claiming bonuses: The welcome offer appears automatically after your first deposit. Read the terms carefully, but don’t worry—they’re fair and transparent.
  • Exploring games: Use the search bar or browse categories. I recommend starting with a few free demo spins to get a feel for the mechanics before wagering real money.
  • Setting limits: Responsible gaming tools are built into the account settings. Set deposit limits, session reminders, or even a cool-off period if needed.

This roadmap might seem basic, but it’s designed to remove friction. The goal is to get you from curiosity to enjoyment in the smoothest way possible.

Frequently Asked Questions

Here are some common queries players have about the login process and platform features.

1. Is my personal information safe during login?
Absolutely. The platform uses 128-bit SSL encryption to protect all data transmission. Two-factor authentication is also available for an extra layer of security. Your details are kept confidential and never shared with third parties.

2. What if I forget my password?
Simply click the “Forgot Password” link on the login page. A reset link will be sent to your registered email address. The process takes only a few minutes, and you can set a new password immediately.

3. Can I play on my mobile device?
Yes, the entire platform is optimized for mobile browsers. No app download is required. The interface adapts to any screen size, and all features—including deposits and withdrawals—are fully functional on smartphones and tablets.

4. How long does it take to withdraw winnings?
Withdrawal processing times vary by method. E-wallets are typically the fastest, processing within 24 hours. Bank transfers and card withdrawals may take 3–5 business days. The platform processes requests promptly, usually within the same business day.

5. Are there any country restrictions?
Yes, some countries may be restricted due to local regulations. During registration, you can verify if your country is accepted. If you encounter issues, customer support can clarify eligibility quickly.

6. Do I need to verify my identity before the first withdrawal?
Yes, this is a standard security measure. You’ll need to submit a copy of a valid ID and a recent utility bill or bank statement. Verification is usually completed within 24 hours, after which withdrawals proceed smoothly.

These answers reflect the platform’s commitment to transparency and user convenience. If you have further questions, the 24/7 live chat team is always ready to assist.

In the end, logging in is more than a technical step—it’s an invitation. The Buran Casino login is your personal key to a kingdom of entertainment, where every click can lead to luck and every spin might rewrite your story. So take that step. The reels are waiting.

]]>
Spinning nyeremények a Spinit Kaszinóban https://studieo7aesthetics.in/spinning-nyeremenyek-a-spinit-kaszinoban/ Sun, 20 Sep 2026 13:18:26 +0000 https://studieo7aesthetics.in/?p=7381 Spinning nyeremények a Spinit Kaszinóban

Amikor az ember belép a modern online játékok világába, gyakran érezheti úgy, mintha egy hatalmas, fénylő játszótéren bolyongana. Rengeteg lehetőség, csillogó ajánlatok és ígéretek kavalkádja várja. Ebben a zsúfolt közegben a Spinit Kaszinó igyekszik kitűnni – nem csak a nevével, hanem a játékok kínálatával és a felhasználói élményre helyezett fókusszal is. A kaszinó egyik legvonzóbb része a nyerőgépek tárháza, ahol minden egyes pörgetés újabb izgalmakat tartogat. A spinitcasinohungary.com oldalon bepillantást nyerhetünk ebbe a virtuális kalandba, ahol a pörgetések nem csupán a szerencséről szólnak, hanem a gondosan összeállított témák és mechanikák élvezetéről is.

Az első benyomás: Pörgés és hangulat

A platform megnyitásakor az embert azonnal megragadja a letisztult, mégis vibráló design. A színek nem hivalkodóak, hanem inkább hívogatóak – mintha egy elegáns, modern játékterembe lépnénk be. A nyerőgépek kategóriája itt nem véletlenül kapott kiemelt helyet. A fejlesztők olyan címeket válogattak össze, amelyeknél a vizuális élmény és a játékmenet harmóniában van. Legyen szó egyiptomi kincsekről, skandináv mitológiáról vagy éppen vidám gyümölcsökről, minden slot saját kis történetet mesél el a pörgetések alatt.

Ami igazán megkülönbözteti ezt a helyet, az a változatosság – nem csak a témák, hanem a volatilitás és a fogadási határok tekintetében is. A kezdő játékosok találnak alacsony téttel indítható, gyakori, kisebb nyereményeket kínáló gépeket, míg a nagyobb kockázatot keresők a magas volatilitású, hatalmas főnyereményekkel kecsegtető automaták felé fordulhatnak.

A játékok szíve: Mechanikák és funkciók

Nem elég azonban, hogy a játékok szépek – a lényeg a mechanikában rejlik. A Spinit Kaszinóban található slotok többsége olyan innovatív funkciókkal van felszerelve, amelyek a megszokott pörgetéseket izgalmas kalanddá varázsolják.

  • Ingyenes pörgetések bővülő sorokkal: Egyes játékokban a scatter szimbólumok aktiválása nem csak díjakat, hanem extra játéklehetőségeket is hoz, ahol a nyerő vonalak száma megnőhet.
  • Wild szimbólumok és szorzók: A vad szimbólumok nem csak helyettesítenek, hanem gyakran megsokszorozzák a nyereményt – akár 10x-es szorzóval is találkozhatunk egy-egy szerencsés pörgetés során.
  • Kaszkád vagy összeomló mechanika: A nyerő kombinációk eltűnnek, helyükre új szimbólumok hullanak le, lehetőséget adva egymás utáni nyereményekre egyetlen pörgetésből.
  • Vásárolható bónuszkörök: Azoknak, akik nem szeretnek várni, egyes játékok lehetővé teszik a bónusz funkció közvetlen megvásárlását – persze bizonyos összegért cserébe.

Ezek a funkciók nem csak a nyereményt növelik, hanem a játékélményt is mélyítik. Ahogy pörögnek az orsók, a játékos figyelme fokozódik: vajon most jön be az a bizonyos szimbólumcsoport, ami elindítja a bónuszkört? Ez a fajta feszültség és izgalom teszi igazán emlékezetessé a pörgetéseket.

Különböző ízlésre szabva: A slotok típusai

Ahhoz, hogy jobban átlássuk a kínálatot, érdemes egy pillantást vetni a legnépszerűbb játéktípusokra és azok jellemzőire. Az alábbi táblázat segít eligazodni a lehetőségek között.

Típus Jellemzők Ajánlott játékosoknak
Klasszikus háromtárcsás Egyszerű felépítés, gyümölcsök, 7-esek, harangok; alacsony szórás Nosztalgiázni vágyóknak, kezdőknek
Videóslot (5 tárcsa) Gazdag témák, bónuszkörök, ingyenes pörgetések; közepes-magas volatilitás Történetkedvelőknek, akik szeretnek elmerülni a játékban
Progresszív jackpotos Hatalmas, folyamatosan növekvő főnyeremény; nagyon magas szórás Nagy álmokkal rendelkező, türelmes játékosoknak
Cluster pays (fürtös) Nincs hagyományos nyerővonal, a szimbólumcsoportok fizetnek; gyakori nyeremények Új mechanikákat kereső, kalandvágyó játékosoknak

Ez a változatosság biztosítja, hogy mindenki megtalálja a maga számára leginkább élvezetes játékot. A Spinit Kaszinóban a választék bőséges, és a keresés önmagában is egy kis felfedezőút lehet.

Felelős játék és élvezet

Természetesen a nyeremények ígérete mellett fontos szót ejteni a felelős játék fontosságáról is. A platform számos eszközt kínál, hogy a játékosok kontroll alatt tarthassák a költekezést és az időt. Betétkorlátok, időlimit beállítása, és a mérkőzésfigyelő funkciók mind azt a célt szolgálják, hogy a pörgetések továbbra is örömet nyújtsanak, ne pedig stresszt.

Emlékezzünk: a szerencsejáték elsősorban szórakozás. A nyeremények jönnek és mennek, de a lényeg az élmény maga. A Spinit Kaszinó abban segít, hogy ez az élmény minél magával ragadóbb legyen – legyen szó egy csendes esti játékról egy csésze tea mellett, vagy egy izgalmas hétvégi pörgetés-maratonról.

Gyakran ismételt kérdések

Milyen típusú nyereményekre számíthatok a slotokban?

A nyerőgépek különböző nyereménytípusokat kínálnak: kisebb, gyakori nyereményeket a normál pörgetések során, valamint nagyobb, bónuszkörökben elérhető díjakat. A progresszív jackpotos játékok életre szóló összegeket is tartogathatnak.

Van lehetőség ingyenes pörgetésekre bónusz nélkül?

Egyes slotok tartalmaznak olyan beépített funkciót, ahol a scatter szimbólumok összegyűjtésével ingyenes pörgetések aktiválódnak anélkül, hogy bónuszt kellene vásárolni. Ezek a játékok gyakran rendelkeznek nagyobb volatilitással.

Hogyan válasszak magamnak megfelelő slotot?

Érdemes megnézni a játékok volatilitását és RTP-jét (elméleti visszafizetési arány). Ha gyakori, kisebb nyereményeket szeretsz, válassz alacsony volatilitású gépet. Ha nagyobb kihívásra vágysz, keresd a magas volatilitású vagy jackpotos játékokat. Mindig a saját költségvetésedhez és hangulatodhoz igazítsd a választást.

Lehet mobil eszközön játszani a Spinit Kaszinóban?

Igen, a platform teljes mértékben optimalizált mobiltelefonokra és tabletekre. A játékok többsége hibátlanul fut a böngészőben, így bárhonnan, bármikor pörgethetsz, ahol van internetkapcsolat.

Vannak-e exkluzív játékok, amelyek csak itt elérhetőek?

A Spinit Kaszinó kínálatában szerepelnek olyan címek, amelyek csak bizonyos platformokon érhetőek el, és a partnerségnek köszönhetően a látogatók egyedi játékélményeket is kipróbálhatnak, amelyek máshol nem találhatóak meg.

Mennyi idő alatt kapom meg a nyereményemet kifizetés után?

A kifizetési idő a kiválasztott módszertől függ. Az elektronikus pénztárcák és kriptovaluták általában gyorsabbak (akár 24 órán belül), míg a banki átutalások hosszabb időt vehetnek igénybe. A pontos határidőket a kaszinó ügyfélszolgálata ismerteti.

Végső soron a pörgetések világa a Spinit Kaszinóban nem csupán a nyereményekről szól – hanem az utazásról, a kikapcsolódásról és a játék öröméről. Ahogy az orsók forognak, a lehetőségek is végtelenek. Jó szórakozást és szerencsés pörgetéseket kívánunk!

]]>
Bônus Slotuna Libera Ganhos Sem Limites https://studieo7aesthetics.in/bonus-slotuna-libera-ganhos-sem-limites/ Sun, 20 Sep 2026 13:17:50 +0000 https://studieo7aesthetics.in/?p=7379 Bônus Slotuna Libera Ganhos Sem Limites

Quando se trata de plataformas de entretenimento digital, a busca por ofertas que realmente façam a diferença na experiência do jogador é constante. No universo dos cassinos online, os benefícios oferecidos no momento do cadastro ou em promoções sazonais podem transformar completamente a forma como você interage com o site. É nesse contexto que o chamado bônus Slotuna ganha destaque, prometendo não apenas turbinar o saldo inicial, mas também abrir portas para uma jornada de apostas mais prolongada e interessante.

Diferente de promoções genéricas que muitas vezes vêm recheadas de condições confusas, a proposta da Slotuna parece ter sido desenhada pensando na fluidez da jogatina. Você não precisa ser um expert em termos técnicos para entender como funciona: ao ativar a oferta, o sistema credita valores extras que podem ser usados em uma vasta gama de títulos disponíveis na plataforma. Antes de mergulhar nos detalhes, vale a pena conferir a página oficial para tirar suas próprias conclusões: http://slotunapt.net. Lá você encontrará todas as regras atualizadas e poderá verificar se a oferta se encaixa no seu perfil.

Como a Proposta se Diferencia das Demais

O grande diferencial do bônus Slotuna não está apenas no valor creditado, mas na forma como ele permite que o jogador explore o catálogo sem amarras excessivas. Enquanto muitos sites impõem uma lista restrita de jogos elegíveis, aqui a sensação é de maior liberdade. Slots clássicos, vídeos com gráficos de ponta e até mesas de jogo ao vivo podem se beneficiar dos fundos promocionais. Isso dá ao usuário a chance de testar estratégias diferentes e descobrir novos títulos sem comprometer o próprio bolso.

Outro ponto que merece atenção é a política de rollover. Embora todo bônus venha com requisitos de aposta, a equipe da Slotuna parece ter equilibrado a balança de forma justa. As metas são alcançáveis para jogadores casuais e também para aqueles que preferem ritmo mais intenso. O segredo está em ler atentamente os termos antes de começar, especialmente as cláusulas sobre prazos e contribuição de cada jogo para o cumprimento do volume exigido.

Vantagens Práticas no Dia a Dia

Para quem está acostumado com o vaivém dos cassinos online, alguns benefícios saltam aos olhos. Listo abaixo os principais pontos que tornam essa oferta atrativa:

  • Crédito extra imediato: Assim que o depósito mínimo é feito, o bônus aparece na conta sem burocracia.
  • Variedade de jogos: Diferente de outras plataformas, você pode usar os fundos em praticamente toda a biblioteca.
  • Rodadas grátis inclusas: Em muitas campanhas, o pacote vem acompanhado de giros em títulos selecionados.
  • Suporte em português: A comunicação com o time de atendimento é clara e sem barreiras de idioma.
  • Notificações frequentes: O site avisa sobre novas promoções por e-mail ou no próprio painel, evitando que você perca prazos.

Essas características fazem com que o jogador se sinta valorizado, especialmente quando comparado a experiências frustrantes em outros sites onde o bônus parece existir apenas no papel.

Comparativo Entre Diferentes Tipos de Ofertas

Para ajudar na decisão, montei uma tabela que coloca lado a lado o que a Slotuna oferece em relação ao que se vê por aí. Lembre-se de que números exatos podem variar conforme a campanha ativa no momento.

Aspecto Bônus Slotuna Concorrência Geral
Percentual do depósito Geralmente agressivo, com boas porcentagens Médias mais conservadoras
Liberdade de uso Alta, com poucas restrições de categorias Frequentemente limitado a slots específicos
Rollover Moderado e transparente Pode ser excessivo em outras casas
Prazo para cumprir Prazo confortável (geralmente semanas) Muitas vezes apenas alguns dias

Como se vê, a proposta da Slotuna se destaca justamente por equilibrar generosidade com praticidade. O jogador não precisa se desesperar para cumprir metas impossíveis, o que torna a experiência mais prazerosa e menos ansiosa.

Perguntas Frequentes Sobre o Tema

Reuni algumas dúvidas comuns que surgem na hora de avaliar se vale a pena ativar o benefício:

Preciso digitar um código promocional?
Na maioria das vezes, o bônus é ativado automaticamente ao fazer o depósito qualificado. Verifique na página da campanha se há necessidade de inserir um código específico.

Posso sacar o valor do bônus imediatamente?
Não. Como em qualquer casa séria, o bônus precisa ser apostado um número mínimo de vezes antes de se tornar disponível para saque.

O bônus funciona no celular?
Sim, a plataforma é totalmente adaptada para dispositivos móveis, e a oferta pode ser usada tanto no navegador do celular quanto no computador.

E se eu mudar de ideia depois de ativar?
Algumas plataformas permitem recusar o bônus antes de qualquer aposta. Verifique os termos para saber se essa opção está disponível.

Há limite de ganhos com o bônus?
Embora a oferta se chame “ganhos sem limites”, na prática existe um teto máximo que pode ser sacado a partir dos fundos promocionais. Esse valor costuma ser justo e condizente com o mercado.

Palavras Finais Sobre a Proposta

O bônus Slotuna surge como uma alternativa sólida para quem deseja maximizar o tempo de jogo sem complicações. A combinação de percentuais atrativos, liberdade de escolha e requisitos realistas forma um pacote que agrada tanto novatos quanto veteranos. Como sempre, a recomendação é ler o regulamento completo antes de depositar, garantindo que não haja surpresas desagradáveis. Se você busca uma plataforma que valorize a sua diversão, essa pode ser uma excelente porta de entrada.

]]>
Spin, Win, Rise — MonsterWin Casino’s Jackpot Rush https://studieo7aesthetics.in/spin-win-rise-monsterwin-casinos-jackpot-rush/ Sun, 20 Sep 2026 09:37:54 +0000 https://studieo7aesthetics.in/?p=7377 Spin, Win, Rise — MonsterWin Casino’s Jackpot Rush

There’s a certain electricity that hums through the reels of a slot machine when the symbols start aligning just right. It’s that breathless moment, the pause before the music swells, that keeps players coming back for more. MonsterWin Casino has built its entire atmosphere around capturing that fleeting thrill, bottling it into a platform that feels less like a standard gaming site and more like an ongoing festival of luck. From the moment you land on the homepage, with its bold graphics and playful monstrous mascots, you understand this isn’t just another digital card room — it’s a destination for those who crave the chase.

What sets MonsterWin apart isn’t merely the catalog of games, though that certainly helps. It’s the philosophy embedded in every corner of the experience: treat every spin as a potential starting line. For newcomers, the journey begins with a welcoming gesture that softens the learning curve, allowing you to explore the vast library without immediately risking your own funds. And for those who like a head start, the monsterwin casino bonus code unlocks a treasure trove of extra spins and match incentives that effectively lengthen your playing session — giving you more opportunities to chase that elusive jackpot.

The game selection at MonsterWin reads like a love letter to variety. You’ll find classic three-reel fruit machines that hum with nostalgia, modern video slots dripping with cinematic storylines, and progressive jackpot networks where the prize pool grows with every wager placed across the platform. Table game enthusiasts aren’t left out either; the blackjack and roulette tables flow smoothly with crisp animations and dealer options that mimic the energy of a brick-and-mortar casino floor. Live dealer rooms add a human touch, streaming in real time from professional studios.

But let’s talk about the heart of the matter — the jackpot rush. The progressive pools are the main attraction, linking multiple games so that every spin feeds the collective pot. Watching that number tick upward is its own form of entertainment. The platform organizes its jackpot games into a well-curated section, so you never have to hunt for the biggest potential payouts. A quick glance at the lobby reveals which games are currently “hot,” and the interface updates in real time to reflect recent winners, adding a layer of community excitement that many competitors overlook.

Underneath the glitz, MonsterWin gets the fundamentals right. Account management is straightforward, with a clean dashboard that tracks your spins, deposits, and any active promotions without clutter. Withdrawal requests are handled through a transparent ticketing system that keeps you informed at every step. Customer support operates around the clock, and the live chat feature typically connects you with a knowledgeable agent within moments — no endless bot loops or frustrating menu trees.

A Side-by-Side Glance at the MonsterWin Experience

Aspect MonsterWin Typical Casino Site
Jackpot Variety Multiple progressive networks with live-updating totals One or two fixed jackpots that rarely change
Game Library Size Large, with curated sections for slots, table, and live Often cluttered, hard to navigate
Promotional Depth Layered bonuses, reloads, and a bonus code system Basic welcome offer with little follow-up
User Interface Intuitive, responsive, visually energetic Sometimes dated or slow to load
Support Speed Live chat with fast response times Email-only or delayed ticket systems

The mobile experience deserves special mention. Whether you’re on a phone or tablet, the site adapts beautifully, retaining all the functionality of the desktop version without forcing you to download a heavy app. Games load quickly even on standard connections, and the touch controls feel natural — a swipe to spin, a tap to adjust bet sizes. It’s clear that MonsterWin invested heavily in responsive design rather than just porting a clunky desktop clone.

For those who enjoy structure in their gaming, MonsterWin offers a VIP ladder that rewards consistency rather than mere luck. Climbing tiers unlocks personal account managers, exclusive tournaments, and cashback offers that cushion the inevitable losing streaks. The system is straightforward — you earn points through real-money play, and those points translate into tangible perks. It’s a refreshingly transparent approach to loyalty, without hidden conditions buried in fine print.

Frequently Asked Questions

How do I claim the MonsterWin bonus code?

Simply enter the code during the deposit process in the cashier section. The bonus is then credited automatically, usually within a few seconds of confirming your transaction.

Are the progressive jackpot games linked to other casinos?

Some jackpot networks are shared across multiple gaming providers, while others are exclusive to MonsterWin. The lobby clearly labels each game’s network, so you always know the pool size.

Can I play on my phone without downloading an app?

Yes, the mobile browser version is fully optimized. Just visit the site from your phone’s browser and log in as you normally would.

What happens if I lose my connection mid-spin?

The game state is preserved on the server side. When you reconnect, you’ll see the result of your spin in your history, ensuring no lost progress.

Is there a limit on how many bonuses I can claim per week?

Bonuses are typically tied to your deposit schedule and VIP tier. Check the promotions page for any cycling restrictions that may apply to your account level.

Final Thoughts on the Rush

MonsterWin Casino doesn’t reinvent the wheel, but it does make the wheel spin faster and more excitingly. The combination of aggressive jackpot tracking, a user-friendly layout, and responsive support creates an environment where both casual players and high rollers can find their rhythm. While the house always holds its edge, the entertainment value here is substantial — the thrill of watching those numbers climb, the camaraderie of live tables, the satisfaction of a well-timed bonus spin.

If you’re ready to test your luck, the path is simple: register, claim your code, and let the reels decide your fate. The jackpot rush awaits, and with MonsterWin’s polished platform, every session feels like a new chapter in your own personal winning story.

]]>
Gana en RodeoSlots con giros y toros salvajes https://studieo7aesthetics.in/gana-en-rodeoslots-con-giros-y-toros-salvajes/ Sun, 20 Sep 2026 09:37:21 +0000 https://studieo7aesthetics.in/?p=7375 Gana en RodeoSlots con giros y toros salvajes

Hay algo electrizante en la combinación de adrenalina y suerte. En el mundo del entretenimiento digital, pocas experiencias logran capturar esa chispa tan auténtica como la que ofrece la nueva plataforma de casino online que está dando que hablar. Si alguna vez soñaste con la emoción de un rodeo, con el rugido del público y la tensión del momento justo, quizás sea hora de darle un vistazo a lo que trae esta propuesta. Para empezar a explorar este universo, puedes visitar https://rodeoslots-es.es y descubrir de primera mano el ambiente que se respira.

La aplicación ha sido diseñada pensando en quienes buscan algo más que simples carretes giratorios. RodeoSlots no es solo un nombre: es una declaración de intenciones. La temática del Lejano Oeste, con vaqueros, botas de cowboy y paisajes desérticos, se fusiona con una mecánica de juego fluida que atrapa desde el primer momento. Pero lo que realmente distingue a esta app es su enfoque en la interacción dinámica con el usuario. Cada giro puede desbloquear bonus inesperados, como si un toro salvaje irrumpiera en la pista justo cuando menos lo esperas.

Una galería de tragamonedas con alma de rodeo

El catálogo de juegos dentro de la aplicación es variado y vibrante. Desde clásicas máquinas de frutas hasta slots temáticos de vaqueros, cada título ofrece una experiencia visual rica. Lo que más llama la atención es la inclusión de giros gratis y multiplicadores que se activan con combinaciones especiales. No es raro encontrarse con un toro de bronce que, al aparecer en los carretes, multiplica las ganancias por tres o hasta por cinco.

  • Bonus del Vaquero Solitario: Símbolo scatter que otorga hasta 20 giros gratis.
  • Ronda del Toro Salvaje: Minijuego donde eliges puertas para revelar premios ocultos.
  • Comodines Montados: Wilds que se expanden por todo el carrete.
  • Progresivo de la Estrella: Acumula parte de cada apuesta para un premio mayor.
  • Dobla o Nada Rodeo: Opción de arriesgar tus ganancias en una ruleta temática.

La variedad no termina ahí. La plataforma incorpora títulos de proveedores reconocidos que garantizan una experiencia justa y transparente. Cada sesión se siente como un paseo en un carrusel de emociones, donde la suerte y la estrategia se dan la mano.

Funcionalidades que marcan la diferencia

No todo es cuestión de suerte; la aplicación ha sido optimizada para dispositivos móviles y de escritorio por igual. La interfaz es intuitiva, con botones grandes que permiten ajustar apuestas con un solo toque. Además, el sistema de notificaciones push avisa sobre torneos relámpago y promociones especiales, como el “Día del Toro” donde los giros gratis se duplican.

El registro es rápido y seguro. Los nuevos usuarios reciben un bono de bienvenida que suele incluir giros adicionales para las tragamonedas más populares. Para los jugadores más experimentados, existe un programa de fidelidad con niveles que desbloquean recompensas exclusivas, desde retiros más rápidos hasta límites de apuesta más altos.

Comparativa de métodos de pago y velocidad

Método Depósito mínimo Tiempo de retiro Comisiones
Tarjeta de crédito/débito 10 EUR 1-3 días hábiles Sin comisión
Monedero electrónico 5 EUR Hasta 24 horas 0%
Transferencia bancaria 20 EUR 3-5 días hábiles Variable según banco
Criptomonedas Equivalente a 10 EUR Instantáneo 0.5%

Como se puede apreciar, la flexibilidad es uno de los pilares. Los jugadores pueden elegir el método que mejor se adapte a sus necesidades, y la app procesa las solicitudes con rapidez. La seguridad está garantizada mediante encriptación SSL y políticas de juego responsable que permiten establecer límites de depósito y tiempo.

El espíritu del Oeste en cada giro

La estética no es solo decorativa: cada elemento sonoro y visual está sincronizado para crear una atmósfera inmersiva. Desde el sonido de las espuelas al ganar una ronda hasta la animación de un toro que embiste la pantalla cuando se activa un jackpot, todo está cuidado al detalle. Los desarrolladores han puesto especial atención en que los jugadores sientan que están participando en un verdadero espectáculo de rodeo, donde cada giro es una monta de un toro bravo.

Para los amantes de las estadísticas, la aplicación ofrece un historial detallado de partidas, mostrando porcentajes de acierto y frecuencias de bonus. Esta transparencia ayuda a construir confianza y permite a los usuarios ajustar sus estrategias. Además, el chat en vivo con atención al cliente está disponible 24/7, con agentes que hablan español y conocen bien la plataforma.

Preguntas frecuentes sobre RodeoSlots

1. ¿Es seguro jugar en RodeoSlots desde el móvil?
Sí, la app utiliza protocolos de seguridad avanzados y está optimizada para proteger tus datos personales y financieros.

2. ¿Necesito descargar algo para jugar?
No es obligatorio. Puedes jugar directamente desde el navegador web, aunque la app descargable ofrece notificaciones y acceso más rápido.

3. ¿Los giros gratis tienen requisitos de apuesta?
Sí, como es estándar en la industria, los bonos suelen tener requisitos de apuesta que deben cumplirse antes de retirar las ganancias.

4. ¿Puedo jugar en RodeoSlots si estoy fuera de España?
La plataforma acepta jugadores de varios países, pero te recomendamos verificar la legalidad del juego online en tu jurisdicción local.

5. ¿Qué hago si olvido mi contraseña?
Usa la opción “Recuperar contraseña” en la pantalla de inicio de sesión. Recibirás un enlace para restablecerla en tu correo electrónico.

6. ¿Hay límite de cuánto puedo ganar en un solo giro?
No hay un límite fijo para las ganancias de un giro individual, pero los jackpots progresivos tienen un tope que se muestra claramente en cada juego.

En definitiva, RodeoSlots ha logrado tejer una experiencia que mezcla la nostalgia del Far West con la tecnología moderna. Ya sea que busques la emoción de un giro afortunado o la estrategia de un torneo, esta aplicación promete mantenerte al borde del asiento. Como en un verdadero rodeo, la clave está en agarrarse fuerte y disfrutar del viaje.

]]>
Unlock Fezbet Secret Rewards Beyond Your Wildest Bets https://studieo7aesthetics.in/unlock-fezbet-secret-rewards-beyond-your-wildest-bets/ Sun, 20 Sep 2026 09:37:12 +0000 https://studieo7aesthetics.in/?p=7373 Unlock Fezbet Secret Rewards Beyond Your Wildest Bets

There’s a certain thrill that comes with discovering a place where the games feel alive, the atmosphere hums with possibility, and every spin or hand carries a whisper of something more. That’s exactly the feeling you get when you step into the world of FEZbet. It’s not just about placing wagers and hoping for a lucky break; it’s about unraveling a tapestry of hidden incentives that can truly transform your entire gaming session. For those who are willing to look a little deeper, this platform offers a treasure trove of perks that go far beyond the standard welcome pat on the back. If you’ve been searching for a way to stretch your bankroll further and add an extra layer of excitement to every round, you’ve landed in the right corner of the internet. Let’s peel back the curtain and see what actually lies beneath the surface, starting with how the bonus ecosystem here is carefully designed to reward both the curious newcomer and the seasoned high roller alike.

At its core, the promotional structure at FEZbet is built on a philosophy of generosity that feels refreshingly straightforward. Unlike many platforms where you need a decoder ring to understand the terms, the offers here are presented with clarity in mind. The initial deposit bonus acts as a warm handshake, giving you extra funds to explore the vast library of slots, table games, and live dealer experiences. But that’s merely the appetizer. What truly sets this experience apart is the ongoing stream of promotions that ebb and flow with the calendar. Weekly reload offers, cashback cushions for those less fortunate evenings, and free spin giveaways tied to new game releases all contribute to a dynamic environment where your loyalty is constantly acknowledged. The fezbetbet.net hub provides a central place to check the latest updates, ensuring you never miss a beat when a fresh opportunity rolls out.

However, the real magic happens when you start to engage with the loyalty program. This isn’t your typical points-and-redeem system that feels like a chore. Instead, it’s a progressive journey where every bet you place, win or lose, adds to your player status. As you climb the tiers, the rewards evolve in scale and sophistication. You might find yourself unlocking personalized deposit bonuses that match your playing style, or gaining access to exclusive tournaments where the prize pools are surprisingly deep. The beauty of this system is that it rewards consistency, turning casual play into a rewarding habit. It’s a subtle psychology, but a powerful one—you feel valued, and that changes how you approach the games entirely.

Let’s break down the typical promotional landscape that you can expect to encounter. While specifics can change based on the season or your account history, the general framework remains robust. To give you a clearer picture, take a look at how the standard offerings usually compare side by side:

Promotion Type What It Does Ideal For
Welcome Boost Matches your first deposit with a percentage of extra funds. New players finding their footing.
Weekly Cashback Returns a slice of your net losses from the previous week. Those who play frequently and want a safety net.
Free Spins Drops Awarded on specific slots, especially during new releases. Slot enthusiasts who love trying fresh titles.
VIP Reload Personalized deposit matches for higher-tier loyalty members. High rollers and loyal regulars.

Understanding the nuances of these offers is where you gain a true edge. For instance, the cashback feature is particularly valuable because it operates on a simple principle: everyone has off days. This perk acknowledges that reality and gives you a portion of your losses back, allowing you to recoup and try again without feeling the sting as sharply. Similarly, the free spins aren’t just random giveaways; they are strategic, often tied to games that have strong potential for multipliers. It’s wise to check which games are eligible for these spins, as targeting the ones with higher volatility can sometimes lead to surprisingly substantial wins from a zero-cost starting point.

Now, let’s talk about strategy. To truly maximize what FEZbet has to offer, you need to approach bonuses with a tactical mindset. It’s not just about claiming everything in sight; it’s about selecting the right offers for your budget and play style. Here are a few core takeaways that many regulars swear by:

  • Read the fine print on wagering requirements to ensure you know exactly how to convert bonus funds into withdrawable cash.
  • Prioritize offers with lower turnover rates, as they are easier to clear and put less pressure on your bankroll.
  • Stay active in the promotions lobby, as flash bonuses often appear with minimal notice and for limited time windows.
  • Set a budget for bonus chasing; it should enhance your play, not dictate it entirely.
  • Track your status in the loyalty program to understand exactly how close you are to the next tier unlock.

There’s also a lot of chatter in the community about the “secret” rewards—those unadvertised perks that seem to materialize for players who frequently interact with the platform. These can range from birthday bonuses to surprise deposit boosts on specific dates of the year. The key to unlocking these is simple: keep your notifications on and check your messages regularly. The platform often communicates directly with players who are active, offering personal touches that make the experience feel less like a machine and more like a relationship. It’s these little moments that add a layer of delight to the entire adventure.

In the grand scheme, the bonus structure at FEZbet is less about a single massive jackpot and more about a consistent flow of added value. It’s about feeling rewarded for the time you invest and the wagers you place. Whether you are spinning the reels of a classic slot or testing your wits against a live dealer, the background presence of these perks enhances every moment. The casino has clearly spent time understanding what players actually want: clarity, fairness, and a reason to come back. And in those three pillars, they’ve built an experience that stands out in a crowded field.

Ultimately, the wisest approach is to see bonuses as a complement to your gaming skill, not a replacement for it. The rewards are there to give you more chances, more time, and more fun—the rest is up to you and the roll of the dice.

Frequently Asked Questions About the Rewards

How do I claim the initial offer?

Usually, it is automatically credited upon your first successful deposit. However, some promotions require you to opt-in or enter a bonus code during the deposit process. Always double-check the specific terms on the page before confirming your transaction.

What are wagering requirements?

These are conditions that dictate how many times you must play through the bonus amount before you can request a withdrawal. For example, a requirement might state that you need to wager the bonus a certain number of times. Lower requirements are generally more favorable.

Can I withdraw my bonus money immediately?

No, bonuses are typically held in a separate balance until the specified wagering conditions are satisfied. Once you complete those requirements, the funds convert to real withdrawable cash.

Are there limits on which games count towards wagering?

Yes, different games often contribute differently to the wagering progression. Slots usually count 100%, while table games and live dealer games might contribute a smaller percentage or be excluded entirely. It is important to review this list to avoid any surprises.

How often are new promotions released?

The frequency varies, but there is usually a steady stream of weekly and monthly offers. It is best to check the promotions page and your email inbox regularly to stay up to date with the latest drops.

Is there a loyalty program?

Yes, the platform operates a tiered system where you accumulate points based on your real-money play. Climbing through these tiers unlocks better rewards, including higher cashback percentages, personal account managers, and exclusive event invitations.

]]>
Big Bass Splash i Padiskutueshëm për Peshkatarët https://studieo7aesthetics.in/big-bass-splash-i-padiskutueshem-per-peshkataret/ Sun, 20 Sep 2026 09:37:07 +0000 https://studieo7aesthetics.in/?p=7371 Big Bass Splash i Padiskutueshëm për Peshkatarët

Kur flet për natyrën dhe qetësinë, pak gjëra e kapin thelbin e peshkimit aq bukur sa një liqen i qetë në agim. Por kur e gjithë kjo zhvendoset në botën dixhitale, emocioni merr një tjetër formë. Për ata që kërkojnë një përvojë që ndërthur pasionin për peshkimin me argëtimin modern, ka një emër që bie në sy: http://bigbasssplash-al.com/. Ky është një udhërrëfyes i plotë për atë që e bën këtë aventurë kaq të veçantë, duke eksploruar çdo cep të saj pa lënë gjë në hije.

Në fillim, mund të mendoni se është thjesht një lojë tjetër me peshq. Gabim. Ajo që dallon këtu është vëmendja ndaj detajeve dhe mënyra se si çdo element të tërheq brenda. Nga shkëlqimi i ujit deri te lëvizja e kallamit, gjithçka është ndërtuar për të krijuar një ndjenjë realiste. Nuk është çudi që ka kaq shumë entuziastë që e quajnë “loja e tyre e preferuar e pushimeve”.

Por çfarë e bën atë vërtet të veçantë në krahasim me të tjerat? Së pari, është thjeshtësia e qasjes. Nuk keni nevojë për manuale të gjata apo orë të tëra mësimi. Pasi të filloni, kuptoni menjëherë se çfarë duhet të bëni. Megjithatë, nën këtë thjeshtësi fshihet një thellësi strategjike që i mban lojtarët me orë të tëra. Është ai ekuilibër perfekt mes relaksit dhe tensionit që të mban në majë të gishtave.

Le të flasim për strukturën e lojës. Ajo përfshin disa raunde ku qëllimi kryesor është të kapni peshq të mëdhenj, sidomos atë trofeun e famshëm. Çdo kapje sjell shpërblime dhe çdo nivel vështirësie shton adrenalinën. Faza e bonuseve është veçanërisht e njohur, sepse aty ndodh magjia e vërtetë. Nuk është vetëm fati; ka një ritëm që, kur e kapni, e bën përvojën edhe më kënaqësuese.

Një aspekt që shumë e nënvlerësojnë është komuniteti që e rrethon. Në forume dhe rrjete sociale, peshkatarët dixhitalë ndajnë këshilla, tregojnë kapjet e tyre më të mira dhe krijojnë një atmosferë mbështetëse. Kjo shton një dimension social që shumë lojëra e humbasin. Nuk jeni vetëm kurrë; ka gjithmonë dikush që ka provuar një strategji të re dhe është i gatshëm ta ndajë.

Për të kuptuar më mirë se ku qëndron ndryshimi, le të shohim një krahasim të shpejtë me lojëra të ngjashme tematike.

Karakteristikë Big Bass Splash Lojëra të ngjashme peshkimi
Vështirësia e qasjes E ulët, miqësore për fillestarët Shpesh e mesme ose e lartë
Thellësia strategjike E ekuilibruar mirë Ndonjëherë e cekët ose shumë komplekse
Frekuenca e veçorive speciale E moderuar dhe e parashikueshme E rastësishme dhe e papritur
Apeli vizual I ngrohtë dhe tërheqës Ndonjëherë shumë i ndezur ose i zbehtë

Siç mund ta shihni, fokusi këtu është te përvoja e lëmuar dhe e këndshme. Nuk ka zhgënjime të mëdha; çdo sesion ofron diçka për të marrë me vete. Ky është një nga arsyet pse lojtarët kthehen vazhdimisht, edhe pas shumë orësh lojë.

Ata që e kanë provuar, shpesh përmendin disa pika kyçe që i bëjnë të bien në dashuri me të. Ja disa prej tyre:

  • Përditësimet e rregullta që sjellin sfida të reja.
  • Grafikat e detajuara që krijojnë një ambient relaksues.
  • Mekanika e qartë e lojës që nuk kërkon ndihmë nga jashtë.
  • Një ndjenjë e vazhdueshme progresi, edhe në seancat e shkurtra.
  • Mundësia për të eksperimentuar me stile të ndryshme loje.

Megjithatë, si çdo gjë në jetë, ka edhe anën tjetër të medaljes. Disa lojtarë më me përvojë mund të dëshironin më shumë opsione personalizimi ose një ritëm më të shpejtë në fillim. Por këto janë detaje që nuk ia zbehin fare shkëlqimin. Është si të kërkosh një liqen më të madh kur ai ku je tashmë është i mrekullueshëm.

Një gjë është e sigurt: për ata që e duan peshkimin, qoftë në natyrë apo në ekran, kjo është një nga mënyrat më të mira për të kaluar kohën. Nuk ka nevojë për pajisje të shtrenjta, as për mot të mirë. Gjithçka që ju nevojitet është kurioziteti për të provuar diçka të re dhe dëshira për t’u çlodhur.

Le të hedhim një vështrim edhe në disa pyetje që lindin shpesh. Është mirë të keni përgjigje të qarta përpara se të zhyteni.

Pyetje të Shpeshta rreth Aventurës

A është e përshtatshme për fillestarët absolut? Po, plotësisht. Mekanika themelore mësohet shumë shpejt dhe nuk ka nevojë për njohuri paraprake. Është projektuar për t’ju mirëpritur.

Sa kohë duhet për të parë rezultate të mira? Kjo varet nga stili juaj i lojës. Disa arrijnë të kuptojnë ritmin brenda një ore, ndërsa të tjerë preferojnë ta zbulojnë gradualisht. E bukura është se nuk ka presion.

Çfarë e bën ndryshe nga lojërat e tjera me peshq? Kombinimi i qetësisë vizuale me një lojë të brendshme që mban vëmendjen. Nuk është as shumë e ngadaltë, as shumë e furishme. Është në pikën e ëmbël.

A ka nevojë për ndonjë pajisje të veçantë? Jo, një shfletues i zakonshëm dhe një lidhje e mirë interneti janë të mjaftueshme. Thjeshtësia është një pikë e fortë.

Si mund ta provoj pa u angazhuar shumë? Thjesht hyni dhe kaloni disa minuta. Mjafton të ndjeni atmosferën. Nëse ju pëlqen ajo ndjesia e parë, ka shumë mundësi që të ktheheni.

Në fund të fundit, kjo është një histori për ata që duan të shijojnë momentin. Nuk ka domosdoshmëri për të nxituar, as për të arritur diçka specifike. Vlera është në vetë udhëtimin. Dhe ky udhëtim, me ujërat e tij të qeta dhe kapjet e tij emocionuese, ia vlen patjetër të provohet. Nëse jeni dikush që vlerëson një arratisje të vogël nga rutina, kjo mund të jetë pikërisht ajo që kërkonit. Pesha e vendimit është mbi supet tuaja, por mundësia është e hapur për të gjithë.

]]>
Sloturi cu o singura linie castigatoare https://studieo7aesthetics.in/sloturi-cu-o-singura-linie-castigatoare/ Sun, 20 Sep 2026 08:40:31 +0000 https://studieo7aesthetics.in/?p=7369 Sloturi cu o singură linie câștigătoare

În lumea vastă a cazinourilor online, unde jocurile video cu sute de linii de plată și mecanici complexe au devenit norma, există o categorie aparte care atrage din ce în ce mai mulți jucători: sloturile cu o singură linie câștigătoare. Fie că ești un pasionat al jocurilor clasice sau un explorator în căutarea unei experiențe autentice, https://1xslotsro.com oferă o selecție variată de astfel de aparate, gândite să readucă farmecul sălilor de joc tradiționale direct pe ecranul tău.

De ce să alegi simplitatea unei singure linii?

Pe măsură ce tehnologia avansează, tot mai mulți jucători simt nevoia să se întoarcă la baze. Sloturile cu o singură linie câștigătoare sunt exact asta: pure, necomplicate și directe. Nu există simboluri care să se împrăștie în toate direcțiile sau reguli greu de urmărit. Tu alegi miza, tragi maneta (virtuală) și aștepți ca cele trei sau cinci role să se alinieze perfect pe linia centrală. Această simplitate nu este doar o chestiune de nostalgie, ci și o strategie inteligentă pentru cei care doresc să își gestioneze mai ușor bankroll-ul.

În plus, aceste jocuri oferă adesea procente de plată mai transparente și o volatilitate care poate fi anticipată cu ușurință. Fără mize uriașe pe sute de linii active, fiecare rotire devine o mică aventură personală, iar emoția crește pe măsură ce simbolurile se opresc. Pentru jucătorii care apreciază controlul și previzibilitatea, acest format este o gură de aer proaspăt.

Cum funcționează mecanismele clasice?

Mecanismul din spatele acestor sloturi este similar cu cel al aparatelor fizice din anii ’80 și ’90. Rolele se învârt, iar combinațiile câștigătoare sunt formate doar pe linia centrală. Deși par simple, multe dintre ele includ și simboluri wild sau scatter, care pot declanșa rotiri gratuite sau multiplicatori. Diferența majoră față de sloturile moderne este că totul se concentrează pe o singură linie, ceea ce face ca fiecare rotire să fie mai ușor de urmărit.

Un alt aspect important este că RTP-ul (Return to Player) poate fi adesea mai mare la aceste jocuri, deoarece nu există costuri ascunse pentru activarea liniilor suplimentare. Astfel, jucătorii pot beneficia de o experiență mai echitabilă, fără surprize neplăcute la finalul sesiunii de joc.

Avantaje și dezavantaje ale sloturilor cu o singură linie

Ca în orice tip de joc, există atât puncte forte, cât și puncte slabe. Iată o listă cu principalele aspecte de luat în considerare:

  • Simplitate maximă: Nu trebuie să înveți reguli complicate sau să urmărești mai multe linii simultan.
  • Control mai bun al bugetului: Mizele sunt mai mici și mai ușor de gestionat pe termen lung.
  • Experiență nostalgică: Perfect pentru cei care își amintesc de sălile de joc tradiționale.
  • Câștiguri mai rare, dar mai consistente: Volatilitatea poate fi medie, oferind o senzație plăcută de stabilitate.
  • Mai puține opțiuni de bonus: Unele jocuri pot avea funcții limitate comparativ cu sloturile moderne.

Comparație între sloturile clasice și cele moderne

Caracteristică Sloturi cu o singură linie Sloturi moderne (multiple linii)
Număr de linii 1 linie fixă 10–100+ linii
Complexitate Scăzută Ridicată
Cost pe rotire Mic (miză pe o singură linie) Mare (miză pe multiple linii)
Volatilitate Medie spre scăzută Variabilă (de la scăzută la extrem de ridicată)
Experiență vizuală Simplă, retro Avansată, cu animații complexe

După cum se poate vedea, fiecare tip de slot are propriul său public. Cei care preferă liniștea și controlul vor alege probabil varianta clasică, în timp ce aventurierii în căutare de senzații tari se vor îndrepta spre sloturile moderne.

Sfaturi pentru jucătorii începători

Dacă ești la început de drum în lumea sloturilor, îți recomand să începi cu aceste jocuri simple. Învață cum funcționează rotirile, cum se formează combinațiile câștigătoare și cum poți să îți gestionezi eficient bugetul. Un sfat util este să testezi jocurile în modul demo, pentru a înțelege mecanismele fără a risca bani reali. Apoi, când te simți pregătit, poți trece la jocul cu mize reale, păstrând întotdeauna o atitudine responsabilă.

Întrebări frecvente (FAQ)

  1. Pot câștiga sume mari la sloturile cu o singură linie? Da, deși câștigurile maxime sunt adesea mai mici decât la sloturile cu jackpot progresiv, ele pot fi totuși consistente și frecvente.
  2. Există bonusuri speciale la aceste jocuri? Da, multe sloturi clasice includ simboluri wild, scatter și rotiri gratuite, dar într-o formă mai simplă.
  3. Este mai ușor să câștigi la sloturile cu o singură linie? Nu neapărat mai ușor, dar șansele sunt mai previzibile, iar gestionarea bankroll-ului este mai simplă.
  4. Pot juca aceste sloturi pe telefon sau tabletă? Da, majoritatea platformelor moderne, inclusiv cele menționate, sunt optimizate pentru dispozitive mobile.
  5. Care este cel mai bun sfat pentru un începător? Începe cu mize mici, joacă responsabil și nu încerca să recuperezi pierderile prin pariuri mari.

Concluzie

Sloturile cu o singură linie câștigătoare reprezintă o alegere excelentă pentru orice jucător care apreciază simplitatea și transparența. Fie că ești un veteran al jocurilor de noroc sau un novice curios, aceste aparate oferă o experiență relaxantă, dar plină de satisfacții. Nu uita să verifici întotdeauna termenii și condițiile platformei alese și să joci responsabil. Distracție plăcută!

]]>
Sportuna Kaszinó Extrém Nyereményei https://studieo7aesthetics.in/sportuna-kaszino-extrem-nyeremenyei/ Sun, 20 Sep 2026 08:37:30 +0000 https://studieo7aesthetics.in/?p=7367 Sportuna Kaszinó Extrém Nyereményei

Amikor a modern online szerencsejáték világába lépünk, hamar szembetűnő, hogy a legtöbb platform hasonló kínálattal próbálja megfogni a látogatókat. A Sportuna Kaszinó azonban egészen más megközelítést alkalmaz: nem a megszokott sablonokra épít, hanem merész, szinte szokatlan nyereménylehetőségeket kínál. A játékosok gyakran mesélnek olyan extrém kifizetésekről, amelyek messze túlmutatnak az iparági átlagokon. Ha szeretné kipróbálni ezt a különleges élményt, látogasson el a http://sportunahu.net oldalra, ahol első kézből tapasztalhatja meg, miről is beszélünk.

A platform egyik legnagyobb vonzereje, hogy a hagyományos nyerőgépek mellett olyan progresszív jackpot rendszereket is üzemeltet, amelyek akár több százezer forintos nyereményeket is termelhetnek. Ezek a nyereményalapok folyamatosan nőnek, és bármikor elérhetik a csúcsot. Ezt a mechanizmust a folyamatos tétgyűjtés táplálja, ami azt jelenti, hogy minél többen játszanak, annál magasabb a főnyeremény.

A játékválaszték rendkívül széles skálán mozog. A klasszikus gyümölcsslotoktól kezdve a legmodernebb videopóker variációkig mindent megtalálhat itt a játékos. Az egyediséget azonban azok a tematikus játékok adják, amelyek kifejezetten a magyar közönségre szabott grafikával és hangzással rendelkeznek. Ezek a játékok gyakran helyi legendákat, történelmi alakokat vagy népi motívumokat jelenítenek meg, ami igazán otthonossá varázsolja az élményt.

Fontos kiemelni, hogy a Sportuna nem csupán a nyeremények nagyságára fókuszál, hanem a játékélmény minőségére is. A weboldal letisztult, de mégis izgalmas dizájnja lehetővé teszi, hogy a játékosok könnyedén navigáljanak a kategóriák között. A mobil verzió is kimagaslóan jól optimalizált, így bárki, aki útközben szeretne játszani, zökkenőmentes élményre számíthat.

A legjobban fizető játékkategóriák

A kaszinó portfóliójában az alábbi típusok emelkednek ki a legmagasabb potenciális nyeremények tekintetében. Ezeket a játékokat érdemes elsőként kipróbálni, ha valaki valóban extrém kifizetésekre vágyik:

  • Progresszív jackpot slotok: ezek a játékok több platformról is összegyűjtik a téteket, így a nyereményalap akár napi szinten is millió forintokkal nőhet.
  • Video póker variánsok: a magas RTP-vel (visszajátszási aránnyal) működő pókerjátékokban a stratégiai döntések is segíthetik a nyerést.
  • Asztali játékok élő osztókkal: a rulett, a blackjack és a baccarat különböző változatai, ahol a játékosok akár százszoros téttel is nyerhetnek.

Az élő kaszinó részleg különösen népszerű, hiszen itt valódi osztók vezetik a játékokat, és a játékosok chat funkció segítségével kommunikálhatnak egymással és az osztókkal. Ez a társasági érzés sokat hozzáad az izgalomhoz, és a nyeremények is látványosabbak, hiszen a kamerák minden részletet rögzítenek.

Összehasonlító táblázat a kiemelt játékokról

Az alábbi táblázat segít átlátni, hogy melyik játéktípus miben nyújt többet. Az adatok tájékoztató jellegűek, hiszen minden játék esetében a véletlen és a szerencse is nagy szerepet játszik.

Játéktípus Nyeremény potenciál Stratégiai elem Legnagyobb jackpot (becsült)
Progresszív slotok Nagyon magas Alacsony Több százezer forint
Video póker Közepes-magas Magas (kártyatudás) Nincs jackpot, de magas RTP
Élő rulett Változó (maximum 36x tét) Alacsony (tiszta szerencse) Nincs, de kombinált fogadásokkal nagy nyeremény

Biztonság és felelősségteljes játék

A Sportuna Kaszinó nagy hangsúlyt fektet a biztonságra. A platform modern titkosítási technológiákat használ, hogy a játékosok személyes és pénzügyi adatait védje. Emellett a felelősségteljes játék szabályait is szigorúan betartatják: a játékosok limitet állíthatnak be a napi költéseikre, és szükség esetén ideiglenes szünetet is kérhetnek. Ez a hozzáállás azt mutatja, hogy a kaszinó nem csupán a profitot, hanem a játékosok jólétét is szem előtt tartja.

„A legtöbb játékos itt érzi először azt, hogy a nyeremény nem csak álom, hanem valóság is lehet. A rendszeres kifizetések és a gyors ügyfélszolgálat mindenki számára megkönnyíti a játékot.”

Gyakran Ismételt Kérdések (GYIK)

Milyen típusú extrém nyereményekre számíthatok?

A progresszív slotok és az élő kaszinó játékok kínálnak a legmagasabb potenciális nyereményeket. Ezek akár több százezer forintot is elérhetnek egyetlen kör alatt.

Mennyi idő alatt kapom meg a nyereményemet?

A kifizetések általában 24 órán belül megtörténnek, de ez függ a választott fizetési módtól. Az e-pénztárcák gyorsabbak, míg a banki átutalás néhány munkanapot is igénybe vehet.

Van-e bármilyen korlát a nyereményekre?

A platform nem alkalmaz szigorú felső korlátot, azonban egyes játékok esetében a maximális tét és a jackpot nagysága határozza meg a kifizethető összeget.

Szükséges letöltenem valamilyen programot?

Nem, a Sportuna Kaszinó teljes mértékben böngészőalapú. Mindössze egy internetkapcsolat és egy modern böngésző szükséges a játékhoz.

Mit tegyek, ha úgy érzem, hogy a játék problémává válik?

Az oldalon elérhető a felelősségteljes játék eszköztár, ahol napi, heti vagy havi limitet állíthat be. Emellett az ügyfélszolgálat segít a szüneteltetés vagy a fiók ideiglenes lezárása kapcsán.

]]>