@imagineio/configurator-sdk 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{Fragment as Z,jsx as d,jsxs as C}from"react/jsx-runtime";import{useMemo as $e,useRef as Ie,useEffect as ae,useSyncExternalStore as mt}from"react";import{HOSTED_PLACEMENT_ID_PREFIX as St}from"./23dc0ccf32.js";import"./4d7a0d1897.js";import"./ab6c80484f.js";import{subscribe as _t,getVersion as We,getPlacementBindings as Ve,getEffectiveSelections as ft,isOptionAvailable as Ke,isOptionVisible as bt,getPlacementOSAllowlist as yt}from"./817d930a49.js";import{ChevronLeft as Ce,LogoIcon as vt}from"./c5e990946e.js";import{useHasIcon as Pt}from"./09c4973968.js";import{getProductAllComponents as It,pieceKindOf as Ct}from"./9326c23506.js";import{isHostedProduct as Ot,isHostFloating as je}from"./061b81ad81.js";import"./87dcc12b65.js";import"./ee242c0099.js";import{applyFinishClick as Oe}from"./dc2a1a0e13.js";import kt from"./54f0fcf38b.js";import wt from"./c4790179f1.js";import{useSystemConfig as Tt,useSceneFeaturesReader as Ht}from"./6855e6a3b1.js";import{getCatalog as w,useCatalogMaps as Ft}from"./1458417bdb.js";import{useUIState as ze,useOptionGating as Nt,useHostedProductState as J,getUIState as ce,useUIRegion as Ge}from"./9840b9ce12.js";import{useCornerSlots as At,getBasePiecePositions as Dt,clearOverlapFlags as Lt,appendSceneHostedProduct as Rt}from"./367a479d3a.js";import{useSceneState as ke,getSceneState as we}from"./16a399703e.js";import{useSystem as Bt}from"./066fc9aa40.js";import{setSceneSelection as Ye,clearSceneSelection as Et,removeSceneInstance as xt,setSceneInstanceVariant as Ut,showInfo as Q,clearSceneLoading as Mt,clearPendingHostedProduct as $t,setPendingSlotPlacement as Wt,clearPendingSlotPlacement as Vt,clearDeferredHostedProductPlacement as Kt,deselect as jt}from"./2cafe3274b.js";import zt from"./6e2595aa36.js";import Gt from"./2990ba64d6.js";import Yt from"./6ba86aa3b8.js";import{selectOption as qt,selectProductOption as Xt}from"./dbd5ba1d07.js";import"./9526094bb7.js";import"./2774152dd2.js";import Jt from"./3fb3ab6757.js";import{resolveComponent as B,useComponentRegistry as Qt}from"./882bc739c8.js";import{SlotHost as qe}from"./73f7d65985.js";import{LayoutThumbnail as Zt,FinishThumbnail as en,OptionThumbnail as tn,AddProductToggle as nn,HostedProductThumbnail as sn}from"./c12c112c6f.js";import"./239b619005.css";let Te=null;function ji(){return Te||(Te=w().listHostedProducts()),Te}function Xe(E,ee,F){if(ee==null||!Array.isArray(E)||E.length===0)return null;const te=S=>S.value_product??S.valueProduct??S.value,ie=S=>S==null?null:F[S]||F[String(S)]||null,z=S=>String(S??"").toLowerCase().replace(/\s+/g," ").trim(),x=E.find(S=>{const N=te(S);return N!=null&&String(N)===String(ee)});if(x)return x;const u=ie(ee),ue=z(u?.name??u?.title);if(ue){const S=E.filter(N=>{const U=z(N.name??N.label??N.title);return U.length>0&&ue.includes(U)});if(S.length===1)return S[0]}const pe=u?u.productGraph??u.product_graph??null:null;if(pe!=null){const S=E.filter(N=>{const U=ie(te(N)),he=U?U.productGraph??U.product_graph??null:null;return he!=null&&String(he)===String(pe)});if(S.length===1)return S[0]}return null}function on({embedded:E=!1,optionSetIds:ee=null,filterFeatureIds:F=null,backHeader:te=!0}={}){F=ee??F;const ie=Pt("logo"),{confirmDialog:z,setConfirmDialog:x}=zt(),u=Yt(),ue=u.finishes,pe=u.widths,S=u.styles,N=u.handleTypes,U=u.hardwareFinishes,he=u.doorTypes,Je=u.productOverrides,Qe=u.materialOverrides,rn=u.materials,dn=u.freePieceTier,ln=u.freePieceWidthOption,an=u.setFinish,cn=u.setWidth,un=u.setStyle,pn=u.setHandleType,hn=u.setHardwareFinish,gn=u.setDoorType,mn=u.setProductOverride,Sn=u.setMaterialOverride,_n=u.setFreePieceTier,fn=u.setFreePieceWidthOption;Qt();const D=B("OptionSetSection",Jt),se=B("OptionThumbnail",tn),ge=B("FinishThumbnail",en),Ze=B("LayoutThumbnail",Zt),He=B("ChatBar",kt),et=B("HostedProductThumbnail",sn),tt=B("AddProductToggle",nn),me=B("ConfirmDialog",wt),{isMobile:nt,selectedFeatureId:G,selectedElementType:bn,isLayoutLoading:oe}=ze(),it=Ge("sidebar"),Fe=Ge("chat"),{selectedId:Se,locked:_e,instances:re,placementSelections:yn}=ke(),st=xt,ot=mt(_t,We,We),Ne=e=>{if(e==null)return null;const g=re?.[e];let r=Je?.[e]??g?.variantId??g?.productId??null;if(r==null&&String(e).endsWith("__host")){const i=w(),n=we(),o=String(e).replace(/__host$/,""),t=n.productInstances?.[o],s=i.getProduct?.(t?.variantId??t?.productId),a=s?.hostVariants??s?.host_variants,l=Array.isArray(a)?a.find(h=>h?.isDefault??h?.is_default)??a[0]:null;r=l?.hostVariantId??l?.host_variant_id??null}return r},{standalone:rt}=J(),{validCornerSlots:vn,wallCornerCount:Pn}=At(),{pending:fe}=J(),{pendingSlot:Ae}=J(),{placed:Y}=J(),{scene:dt,product:In,features:Cn,rulesReady:lt,rulesTriggerIndex:On}=Tt(),{name:at}=Bt(),{deferred:De}=J(),{occupiedSlots:kn}=J(),{pieceConfigSnapshot:wn}=ze(),Tn=e=>Y.some(g=>g.hostedProductId===e),de=Ie({}),T=Se!=null,f=Se??null;ae(()=>{G&&de.current[G]&&de.current[G].scrollIntoView({behavior:"smooth",block:"center"})},[G]);const Le=Ie(new Set);ae(()=>{const e=new Set((Y||[]).map(t=>t.id)),g=Le.current,r=[...e].filter(t=>!g.has(t)),i=[...g].filter(t=>!e.has(t));if(Le.current=e,r.length===0&&i.length===0||oe)return;const n=r,o=i.length>0;import("./a77b15c0d6.js").then(({placeHostedProduct:t,refreshCanonicalState:s})=>{n.forEach(a=>t(a)),o&&n.length===0&&s()}).catch(()=>{})},[Y,oe]),ae(()=>{if(!De)return;const e=setTimeout(()=>{ce().deferred&&(Kt(),Mt(),Q("Could not place the product \u2014 please try again"))},1e4);return()=>clearTimeout(e)},[De]);const{options:Re,materials:M,features:$}=Ft(),{activeSceneConfigId:be}=ke(),Be=Ht(),{sceneSelections:ct}=ke(),{disabled:Hn,hidden:ye,managedOptionSets:Fn,featureToOptions:Nn}=Nt(),W=$e(()=>be?Be(be):[],[be,Be,dt,ot]),An=$e(()=>{const e=W.find(n=>n.type==="layout_change"),g=W.filter(n=>n.type==="finish_change"),r=W.filter(n=>n.type==="load_new_product"),i=W.find(n=>n.type==="appliance_selection");return{layoutFeature:e,finishFeatures:g,productFeatures:r,appliancesFeature:i}},[W]),ut=Ie(new Map),pt=`${Object.keys($).length}_${Object.keys(Re).length}`;ae(()=>{ut.current.clear()},[pt]);const{getOptionsForFeature:O,getSelection:L,getEffectiveSelection:Dn,optionDisabledPropsFor:q,visibleOptions:X}=Gt(),le=qt,ht=(e,g)=>{const r=e?._hostedProductRecord||e;if(!r){Q("No product data.");return}const i=e?._hostedProductRecord?e:{id:r.id,name:r.name,isPlaced:Y?.some(o=>String(o.hostedProductId)===String(r.id)||String(o.hostedProductId)===String(r.optionId))||ce().standalone.some(o=>String(o.optionId)===String(r.optionId)||String(o.optionId)===String(r.id))};if(i.isPlaced){const o=we().productInstances,t=Object.values(o).find(s=>String(s.variantId??s.productId)===String(r.id));t&&import("./a77b15c0d6.js").then(({removeProduct:s})=>s(t.id)).then(s=>{s&&s.applied&&(st(t.id),Q(`${i.name} removed`))}).catch(()=>{});return}if(String(fe?.id)===String(r.id)||String(Ae?.productId)===String(r.id)){$t(),Vt();return}let n=r.modelUrl;if(!n&&r.id!=null&&(n=(It(r.id)||[]).find(t=>!!t.url)?.url||null),je(r)){const o=Dt(),t=Object.keys(o).filter(l=>Ct(l)==="base"&&o[l]?.position).sort((l,h)=>l.localeCompare(h,void 0,{numeric:!0}))[0];if(!t){Q(`Add a floor piece first \u2014 ${r.name} mounts above it.`);return}const s=o[t],a=`${St}${r.id}-${Date.now()}`;Rt({id:a,hostedProductId:r.id,name:r.name,modelUrl:n,position:[s.position[0],(s.position[1]||0)+1.5,s.position[2]],rotation:s.rotation||[0,0,0],scale:r.scale||[1,1,1],placement_type:"wall_mounted",replacedPiece:t}),Q(`${r.name} added`);return}Wt({productId:r.id,variantId:r.id,name:r.name??"product",compatibleGraphIds:Array.isArray(r.compatibleSlots)?r.compatibleSlots:Array.isArray(r.compatible_slots)?r.compatible_slots:[]}),Q(`Click a highlighted slot to place ${r.name}.`)},ve=()=>{jt(),Et()},Ee=e=>{const g=e?.feature_id??e?.id;let r=e?O(e)||[]:[];const i=T&&ye&&ye.size>0;let n=r.filter(t=>bt(g,t.id));i&&(n=n.filter(t=>!ye.has(String(t.id))));const o=n.map(t=>{const s=[t.value_product,t.valueProduct,typeof t.value=="number"?t.value:null].filter(c=>c!=null);let a=null,l=null;for(const c of s){const v=w().getHostedProduct(c);if(v){l=v,a=c;break}}l||(l={id:a??t.id,optionId:t.id,name:t.name||t.displayName||t.label||`Option ${t.id}`,thumbnail:t.thumbnail||t.thumbnailUrl||t.thumbnail_url||t.imageUrl||t.image_url||null,placement_type:"replace_full"});const h=l.optionId??l.option_id??l.id??t.id,b=rt?.some(c=>String(c.optionId)===String(h)||String(c.optionId)===String(l.id))||Y?.some(c=>String(c.hostedProductId)===String(h)||String(c.hostedProductId)===String(l.id))||Object.values(re||{}).some(c=>String(c.variantId??c.productId)===String(l.id));let y=!1;if(!b){const c=new Set((l.compatibleSlots??l.compatible_slots??[]).map(String)),v=w();y=je(l)?Object.keys(re||{}).length>0:c.size>0&&Object.values(re||{}).some(I=>{const K=v.getProduct?.(I.variantId)||v.getProduct?.(I.productId),R=K?.product_graph??K?.productGraph;return R!=null&&c.has(String(R))})}const A=!Ke(g,t.id),_=A||!b&&!y,m=A?"Not available":null;return{id:h,optId:t.id,name:l.name||String(h),thumbnail:l.thumbnail||l.thumbnailUrl||l.icon||null,description:l.description,isPlaced:b,isDisabled:_,disabledReason:m,canReplace:b,_hostedProductRecord:l}});return o.length===0?null:d(D,{title:e?.name?.toUpperCase()||"APPLIANCES",presentation:e?.presentation,gridClassName:"thumbnail-grid thumbnail-grid--hosted",beforeGrid:fe&&d("p",{className:"sidebar__hint",children:"Click on a highlighted slot in the scene to place the hostedProduct"}),children:o.map(t=>d(et,{hostedProduct:t,isSelected:fe?.id===t.id||String(Ae?.productId)===String(t.id),isPlaced:t.isPlaced,canReplace:t.canReplace,isDisabled:t.isDisabled,onClick:()=>ht(t,e)},t.optId??t.id))})},xe=(e,g)=>{if(!e)return null;const r=g||new Set;if(e.contentKind==="group"||Array.isArray(e.childOptionSetIds)&&e.childOptionSetIds.length>0){if(r.has(e.id))return null;const i=r.size;r.add(e.id);const n=w().features,o=e.childOptionSetIds&&e.childOptionSetIds.length?e.childOptionSetIds:n[e.id]?.childOptionSetIds||[],t=s=>{const a=n[s];if(!a)return null;let l=a.type;return(l==="layout_change"||l==="load_configuration")&&(l="layout_change"),{id:s,feature_id:s,name:a.name,type:l,contentKind:a.contentKind||"options",childOptionSetIds:a.childOptionSetIds||[],default_option_id:a.default_option_id??a.defaultOption,...a.presentation?{presentation:a.presentation}:{}}};return d(D,{labelKey:e.id,sectionRef:s=>de.current[e.id]=s,className:`sidebar__section sidebar__section--group ${G===e.id?"sidebar__section--highlighted":""}`,title:e.name?.toUpperCase(),presentation:e.presentation||"inline",flow:e.flow||"column",kind:"group",depth:i,children:o.map(s=>{const a=t(s);return a?d("div",{className:"sidebar__group-child",children:xe(a,r)},s):null})},e.id)}if(e.type==="layout_change")return d(D,{labelKey:e.id,sectionRef:i=>de.current[e.id]=i,className:`sidebar__section ${G===e.id?"sidebar__section--highlighted":""}`,title:e.name?.toUpperCase()||"LAYOUT",presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--layout",children:X(e.id,O(e)).map(i=>d(Ze,{option:q(e.id,i).disabled?{...i,...q(e.id,i)}:i,isSelected:L(e.id)===i.id,onClick:()=>{if(L(e.id)===i.id)return;const n=ce(),o=n.initialPerPieceOverrides||{},t=(_,m)=>{if(_===m)return!1;const c=_||{},v=m||{},I=Object.keys(c),K=Object.keys(v);if(I.length!==K.length)return!0;for(const R of I)if(c[R]!==v[R])return!0;return!1},a=((_,m)=>{if(_===m)return!1;const c=_||[],v=m||[];if(c.length!==v.length)return!0;for(let I=0;I<c.length;I++)if(c[I]!==v[I])return!0;return!1})(Y,o.sceneHostedProducts)||t(n.hostFinishes,o.hostFinishes)||t(n.hostStyles,o.hostStyles)||t(n.hostHandleTypes,o.hostHandleTypes)||t(n.hostWidths,o.hostWidths)||t(n.hostDoorTypes,o.hostDoorTypes)||t(n.hostProductOverrides,o.hostProductOverrides)||t(n.hostHardwareFinishes,o.hostHardwareFinishes),l=o.sceneSelections||{},h=W.some(_=>{if(_.type==="layout_change")return!1;const m=ct[_.id];if(!m)return!1;const c=l[_.id];return c!==void 0?m!==c:_.default_option_id?m!==_.default_option_id:Re[m]?.value!==null}),b=!!n.initialPieceConfigSnapshot&&!!n.pieceConfigSnapshot&&n.pieceConfigSnapshot!==n.initialPieceConfigSnapshot,y=(n.disabledWalls||[]).length>0;a||h||b||y?x({title:"Change Layout",message:"You will lose the existing configuration. Do you want to continue?",confirmText:"Yes",cancelText:"No",onConfirm:()=>{Lt(),le(e.id,i.id)},onCancel:()=>{}}):le(e.id,i.id)}},i.id))},e.id);if(e.type==="load_new_product"){const i=O(e),n=w().products;if(i.some(t=>{const s=t.value_product??t.valueProduct??(typeof t.value=="number"?t.value:null)??(typeof t.value=="string"&&n[t.value]?t.value:null);return s!=null&&n[s]?.category==="island"}))return d(tt,{optionSet:e,getOptionsForSet:O,feature:e,getOptionsForFeature:O,getSelection:L,onSelectionChange:le},e.id)}if(e.type==="finish_change"&&!T){const i=O(e);if(i.length>0&&i.some(o=>!!M?.[o.value]))return d(D,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--finish",children:X(e.id,i).map(o=>{const t=q(e.id,o);return d(ge,{option:t.disabled?{...o,...t}:o,material:M[o.value],isSelected:L(e.id)===o.id,onClick:()=>{le(e.id,o.id,e)}},o.id)})},e.id)}{const i=w().products,n=O(e);if(e.type==="appliance_selection"||n.some(t=>{const s=t.value_product??t.valueProduct;return s!=null&&Ot(i?.[s])}))return Ee(e)}if(e.type==="load_new_component"||e.type==="load_new_product"||e.type==="product_change"){let i=null;if((e.type==="load_new_product"||e.type==="product_change")&&T&&f!=null){const n=Ne(f),o=Xe(O(e),n,w().products);o&&(i=o.id)}return d(D,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--options",children:X(e.id,O(e)).map(n=>{const o=!Ke(e.id,n.id);return d(se,{option:o?{...n,disabled:!0,disabledReason:o?"Not available":null}:n,isSelected:i!=null?String(i)===String(n.id):String(L(e.id))===String(n.id),onClick:()=>Xt(e,n)},n.id)})},e.id)}if(e.type==="appliance_selection")return Ee(e);if(e.type==="finish_change"&&!T)return d(D,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--options",children:X(e.id,O(e)).map(i=>{const n=q(e.id,i);return d(se,{option:n.disabled?{...i,...n}:i,isSelected:L(e.id)===i.id,onClick:()=>{if(n.disabled)return;const o=$?.[e.id]||$?.[String(e.id)]||e;Oe({option:i,feature:{...e||{},...o},scope:T?"single":"all",pieceIndex:T?f:null}).scope||Ye(e.id,i.id)}},i.id)})},e.id);if(e.type==="finish_change"&&T){const i=O(e),n=i.length>0&&i.some(t=>!!M?.[t.value]),o=t=>{const s=$?.[e.id]||$?.[String(e.id)]||e;Oe({option:t,feature:{...e||{},...s},scope:T?"single":"all",pieceIndex:T?f:null}).scope||Ye(e.id,t.id)};return d(D,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:`thumbnail-grid ${n?"thumbnail-grid--finish":"thumbnail-grid--options"}`,children:X(e.id,i).map(t=>{const s=q(e.id,t),a=s.disabled?{...t,...s}:t;return n?d(ge,{option:a,material:M[t.value],isSelected:L(e.id)===t.id,onClick:()=>{s.disabled||o(t)}},t.id):d(se,{option:a,isSelected:L(e.id)===t.id,onClick:()=>{s.disabled||o(t)}},t.id)})},e.id)}return null},ne=()=>C(Z,{children:[d(qe,{name:"sidebar-top",ctx:{placementId:f??null}}),(()=>{const e=(()=>{if(!(T&&f!=null))return null;const i=w(),n=we(),o=n.productInstances?.[f];let t=o?.variantId??o?.productId;if(t==null&&String(f).endsWith("__host")){const h=String(f).replace(/__host$/,""),b=n.productInstances?.[h],y=i.getProduct?.(b?.variantId??b?.productId),A=y?.hostVariants??y?.host_variants,_=Array.isArray(A)?A.find(m=>m?.isDefault??m?.is_default)??A[0]:null;t=_?.hostVariantId??_?.host_variant_id??null}t=t??ce().hostProductOverrides?.[f]??f;const s=i.getProduct?.(t)||i.getProduct?.(f),a=s?.optionSets||s?.features_configuration_ids||[];if(!Array.isArray(a)||a.length===0)return null;const l=new Set;for(const h of a){const b=h&&typeof h=="object"?h.optionSetId??h.option_set_id??h.id??h.feature_id:h;b!=null&&l.add(String(b))}return l})(),g=new Set,r=Array.isArray(F)?new Set(F.map(String)):null;return W.filter(i=>{const n=String(i?.feature_id??i?.id??"");return!n||g.has(n)||(g.add(n),r&&!r.has(n)&&!r.has(String(i?.id))&&!r.has(String(i?.feature_id)))?!1:i?.type==="finish_change"?!0:!(e&&!e.has(n)&&!e.has(String(i?.id))&&!e.has(String(i?.feature_id)))}).map(i=>d("div",{children:xe(i)},i.id))})(),d(qe,{name:"sidebar-bottom",ctx:{placementId:f??null}})]}),gt=()=>{const e=f,g=yt(e),r=[...Ve(e)].filter(t=>!g||g.includes(String(t.optionSetId))).sort((t,s)=>(t.sequence??0)-(s.sequence??0)),i=Array.isArray(F)?new Set(F.map(String)):null;let n=r;if(i){const t=r.filter(s=>i.has(String(s.optionSetId)));t.length>0&&(n=t)}const o=ft(e)||{};return!n.length&&!_e?null:C(Z,{children:[_e&&d("div",{style:{display:"flex",alignItems:"center",gap:6,padding:"8px 12px",marginBottom:10,borderRadius:6,fontSize:13,background:"rgba(120,120,120,0.12)",borderLeft:"3px solid #888",color:"inherit"},children:"\u{1F512} This item is locked and can\u2019t be changed."}),d("div",{style:_e?{opacity:.5,pointerEvents:"none"}:void 0,children:n.map(t=>{const s=t.optionSetId,a=$[s]||$[String(s)]||{id:s,name:""},l=a.type,h={id:s,feature_id:s,name:a.name,options:a.options},b=new Set((t.available||[]).map(String)),y=O(h);if(!y.length)return null;const A=l==="load_new_product"||l==="product_change",_=/finish/i.test(String(l||"")),m=!A&&y.length>0&&(_?y.some(p=>!!M?.[p.value]):y.every(p=>!!M?.[p.value])),c=o[s]??o[String(s)]??t.default??null;let v=null;if(l==="load_new_product"||l==="product_change"){const p=Ne(e),H=Xe(y,p,w().products);H&&(v=H.id)}let I=null;if(m){const p=Qe?.[e]||{},H=new Set((a.material_targets??a.materialTargets??a.materials??[]).map(P=>String(P).toLowerCase())),k=new Set(Object.entries(p).filter(([P])=>H.size===0||H.has(String(P).toLowerCase())).map(([,P])=>String(P)));if(k.size>0){const P=y.find(j=>j.value!=null&&k.has(String(j.value)));P&&(I=P.id)}}const K=v??I??c,R=p=>{if(l&&/finish/i.test(String(l))){Oe({option:p,feature:a,scope:"single",pieceIndex:e});return}if(l==="load_new_product"){const k=p.value??p.valueText??p.value_text,P=w().products,j=k!=null?P[k]||P[String(k)]:null;j?.id!=null&&Ut(e,j.id)}const H=String(e).endsWith("__host")?String(e).replace(/__host$/,""):e;import("./a77b15c0d6.js").then(({selectOptionForProduct:k})=>k({placementId:H,optionSetId:s,optionId:p.id})).catch(()=>{})};return d(D,{labelKey:s,title:String(a.name||"").toUpperCase(),presentation:a.presentation,flow:a.flow,gridClassName:`thumbnail-grid ${m?"thumbnail-grid--finish":"thumbnail-grid--options"}`,children:X(s,y).map(p=>{const H=q(s,p),k=b.size>0&&!b.has(String(p.id)),P=H.disabled||k,j=H.disabledReason||(k?"Not available":null),Me=P?{...p,disabled:!0,disabledReason:j}:p;return m?d(ge,{option:Me,material:M[p.value],isSelected:String(K)===String(p.id),onClick:()=>{P||R(p)}},p.id):d(se,{option:Me,isSelected:String(K)===String(p.id),onClick:()=>{P||R(p)}},p.id)})},s)})})]})},V=Se!=null,Ue=V&&[...Ve(f)||[]].length>0,Pe=()=>Ue?gt()??ne():ne();return E?C("div",{className:"sidebar sidebar--embedded",style:oe?{opacity:.5,pointerEvents:"none"}:void 0,children:[V&&Ue&&te&&d("div",{className:"sidebar__mobile-header",children:C("button",{className:"sidebar__back-btn",onClick:ve,children:[d(Ce,{}),d("span",{children:"Selected"})]})}),d("div",{className:"sidebar__content",children:V?Pe():ne()}),d(me,{dialog:z,onClose:()=>x(null)})]}):it?nt?C(Z,{children:[V&&te&&d("div",{className:"sidebar__mobile-header",children:C("button",{className:"sidebar__back-btn",onClick:ve,children:[d(Ce,{}),d("span",{children:"Selected"})]})}),d("div",{className:"sidebar__content sidebar__content--mobile",children:V?Pe():ne()}),d(me,{dialog:z,onClose:()=>x(null)})]}):C(Z,{children:[C("div",{"data-sdk-overlay":!0,className:"sidebar-container",style:oe?{opacity:.5,pointerEvents:"none"}:void 0,children:[C("aside",{className:"sidebar sidebar--card",children:[d("div",{className:"sidebar__header",children:V?C("button",{className:"sidebar__back-btn",onClick:ve,children:[d(Ce,{}),d("span",{children:"Selected"})]}):C(Z,{children:[C("div",{className:"sidebar__logo",children:[ie?C(Z,{children:[d(vt,{className:"sidebar__logo-icon"}),d("span",{className:"sidebar__logo-divider"})]}):null,d("span",{className:"sidebar__logo-text",children:at||"Configurator"})]}),d("div",{className:"sidebar__header-actions"})]})}),d("div",{className:"sidebar__content",children:V?Pe():ne()})]}),Fe&&d("div",{className:"sidebar-chat-card",children:d(He,{})})]}),d(me,{dialog:z,onClose:()=>x(null)})]}):Fe?d("div",{"data-sdk-overlay":!0,className:"sidebar-container sidebar-container--chat-only",children:d("div",{className:"sidebar-chat-card",children:d(He,{})})}):null}var zi=on;export{zi as default};
1
+ import{Fragment as Q,jsx as d,jsxs as C}from"react/jsx-runtime";import{useMemo as We,useRef as Oe,useEffect as ue,useSyncExternalStore as bt}from"react";import{HOSTED_PLACEMENT_ID_PREFIX as ft}from"./23dc0ccf32.js";import"./4d7a0d1897.js";import"./ab6c80484f.js";import{subscribe as yt,getVersion as Ve,getPlacementBindings as Ke,getEffectiveSelections as vt,isOptionAvailable as je,isOptionVisible as Pt,getPlacementOSAllowlist as It}from"./817d930a49.js";import{ChevronLeft as ke,LogoIcon as Ct}from"./c5e990946e.js";import{useHasIcon as Ot}from"./09c4973968.js";import{getProductAllComponents as kt,pieceKindOf as wt}from"./9326c23506.js";import{isHostedProduct as Ht,isHostFloating as ze}from"./061b81ad81.js";import"./87dcc12b65.js";import"./ee242c0099.js";import{applyFinishClick as we}from"./dc2a1a0e13.js";import Tt from"./54f0fcf38b.js";import Ft from"./c4790179f1.js";import{useSystemConfig as Nt,useSceneFeaturesReader as At}from"./6855e6a3b1.js";import{getCatalog as w,useCatalogMaps as Dt}from"./1458417bdb.js";import{useUIState as Ge,useOptionGating as Lt,useHostedProductState as X,getUIState as pe,useUIRegion as Ye}from"./9840b9ce12.js";import{useCornerSlots as Rt,getBasePiecePositions as Bt,clearOverlapFlags as Et,appendSceneHostedProduct as xt}from"./367a479d3a.js";import{useSceneState as He,getSceneState as Te}from"./16a399703e.js";import{useSystem as Ut}from"./066fc9aa40.js";import{setSceneSelection as qe,clearSceneSelection as Mt,removeSceneInstance as $t,showInfo as J,clearSceneLoading as Wt,clearPendingHostedProduct as Vt,setPendingSlotPlacement as Kt,clearPendingSlotPlacement as jt,clearDeferredHostedProductPlacement as zt,deselect as Gt}from"./2cafe3274b.js";import Yt from"./6e2595aa36.js";import qt from"./2990ba64d6.js";import Xt from"./6ba86aa3b8.js";import{selectOption as Jt,selectProductOption as Qt}from"./dbd5ba1d07.js";import"./9526094bb7.js";import"./2774152dd2.js";import Zt from"./3fb3ab6757.js";import{resolveComponent as L,useComponentRegistry as en}from"./882bc739c8.js";import{SlotHost as Xe}from"./73f7d65985.js";import{resolveHostVariantId as Je}from"./be07a7f885.js";import{LayoutThumbnail as tn,FinishThumbnail as nn,OptionThumbnail as sn,AddProductToggle as on,HostedProductThumbnail as rn}from"./c12c112c6f.js";import"./239b619005.css";let Fe=null;function Yi(){return Fe||(Fe=w().listHostedProducts()),Fe}function Qe(R,Z,T){if(Z==null||!Array.isArray(R)||R.length===0)return null;const ee=S=>S.value_product??S.valueProduct??S.value,ie=S=>S==null?null:T[S]||T[String(S)]||null,j=S=>String(S??"").toLowerCase().replace(/\s+/g," ").trim(),B=R.find(S=>{const F=ee(S);return F!=null&&String(F)===String(Z)});if(B)return B;const u=ie(Z),ge=j(u?.name??u?.title);if(ge){const S=R.filter(F=>{const E=j(F.name??F.label??F.title);return E.length>0&&ge.includes(E)});if(S.length===1)return S[0]}const he=u?u.productGraph??u.product_graph??null:null;if(he!=null){const S=R.filter(F=>{const E=ie(ee(F)),me=E?E.productGraph??E.product_graph??null:null;return me!=null&&String(me)===String(he)});if(S.length===1)return S[0]}return null}function dn({embedded:R=!1,optionSetIds:Z=null,filterFeatureIds:T=null,backHeader:ee=!0}={}){T=Z??T;const ie=Ot("logo"),{confirmDialog:j,setConfirmDialog:B}=Yt(),u=Xt(),ge=u.finishes,he=u.widths,S=u.styles,F=u.handleTypes,E=u.hardwareFinishes,me=u.doorTypes,Ze=u.productOverrides,et=u.materialOverrides,ln=u.materials,an=u.freePieceTier,cn=u.freePieceWidthOption,un=u.setFinish,pn=u.setWidth,gn=u.setStyle,hn=u.setHandleType,mn=u.setHardwareFinish,Sn=u.setDoorType,_n=u.setProductOverride,bn=u.setMaterialOverride,fn=u.setFreePieceTier,yn=u.setFreePieceWidthOption;en();const N=L("OptionSetSection",Zt),se=L("OptionThumbnail",sn),Se=L("FinishThumbnail",nn),tt=L("LayoutThumbnail",tn),Ne=L("ChatBar",Tt),nt=L("HostedProductThumbnail",rn),it=L("AddProductToggle",on),_e=L("ConfirmDialog",Ft),{isMobile:st,selectedFeatureId:z,selectedElementType:vn,isLayoutLoading:oe}=Ge(),ot=Ye("sidebar"),Ae=Ye("chat"),{selectedId:be,locked:fe,instances:re,placementSelections:Pn}=He(),rt=$t,dt=bt(yt,Ve,Ve),De=e=>{if(e==null)return null;const g=re?.[e];let r=Ze?.[e]??g?.variantId??g?.productId??null;if(r==null&&String(e).endsWith("__host")){const i=w(),n=Te(),o=String(e).replace(/__host$/,""),t=n.productInstances?.[o],s=i.getProduct?.(t?.variantId??t?.productId);r=Je(s,t)}return r},{standalone:lt}=X(),{validCornerSlots:In,wallCornerCount:Cn}=Rt(),{pending:ye}=X(),{pendingSlot:Le}=X(),{placed:G}=X(),{scene:at,product:On,features:kn,rulesReady:ct,rulesTriggerIndex:wn}=Nt(),{name:ut}=Ut(),{deferred:Re}=X(),{occupiedSlots:Hn}=X(),{pieceConfigSnapshot:Tn}=Ge(),Fn=e=>G.some(g=>g.hostedProductId===e),de=Oe({}),H=be!=null,f=be??null;ue(()=>{z&&de.current[z]&&de.current[z].scrollIntoView({behavior:"smooth",block:"center"})},[z]);const Be=Oe(new Set);ue(()=>{const e=new Set((G||[]).map(t=>t.id)),g=Be.current,r=[...e].filter(t=>!g.has(t)),i=[...g].filter(t=>!e.has(t));if(Be.current=e,r.length===0&&i.length===0||oe)return;const n=r,o=i.length>0;import("./a77b15c0d6.js").then(({placeHostedProduct:t,refreshCanonicalState:s})=>{n.forEach(a=>t(a)),o&&n.length===0&&s()}).catch(()=>{})},[G,oe]),ue(()=>{if(!Re)return;const e=setTimeout(()=>{pe().deferred&&(zt(),Wt(),J("Could not place the product \u2014 please try again"))},1e4);return()=>clearTimeout(e)},[Re]);const{options:Ee,materials:x,features:U}=Dt(),{activeSceneConfigId:ve}=He(),xe=At(),{sceneSelections:pt}=He(),{disabled:Nn,hidden:Pe,managedOptionSets:An,featureToOptions:Dn}=Lt(),M=We(()=>ve?xe(ve):[],[ve,xe,at,dt]),Ln=We(()=>{const e=M.find(n=>n.type==="layout_change"),g=M.filter(n=>n.type==="finish_change"),r=M.filter(n=>n.type==="load_new_product"),i=M.find(n=>n.type==="appliance_selection");return{layoutFeature:e,finishFeatures:g,productFeatures:r,appliancesFeature:i}},[M]),gt=Oe(new Map),ht=`${Object.keys(U).length}_${Object.keys(Ee).length}`;ue(()=>{gt.current.clear()},[ht]);const{getOptionsForFeature:O,getSelection:A,getEffectiveSelection:Rn,optionDisabledPropsFor:Y,visibleOptions:q}=qt(),le=Jt,mt=(e,g)=>{const r=e?._hostedProductRecord||e;if(!r){J("No product data.");return}const i=e?._hostedProductRecord?e:{id:r.id,name:r.name,isPlaced:G?.some(o=>String(o.hostedProductId)===String(r.id)||String(o.hostedProductId)===String(r.optionId))||pe().standalone.some(o=>String(o.optionId)===String(r.optionId)||String(o.optionId)===String(r.id))};if(i.isPlaced){const o=Te().productInstances,t=Object.values(o).find(s=>String(s.variantId??s.productId)===String(r.id));t&&import("./a77b15c0d6.js").then(({removeProduct:s})=>s(t.id)).then(s=>{s&&s.applied&&(rt(t.id),J(`${i.name} removed`))}).catch(()=>{});return}if(String(ye?.id)===String(r.id)||String(Le?.productId)===String(r.id)){Vt(),jt();return}let n=r.modelUrl;if(!n&&r.id!=null&&(n=(kt(r.id)||[]).find(t=>!!t.url)?.url||null),ze(r)){const o=Bt(),t=Object.keys(o).filter(l=>wt(l)==="base"&&o[l]?.position).sort((l,h)=>l.localeCompare(h,void 0,{numeric:!0}))[0];if(!t){J(`Add a floor piece first \u2014 ${r.name} mounts above it.`);return}const s=o[t],a=`${ft}${r.id}-${Date.now()}`;xt({id:a,hostedProductId:r.id,name:r.name,modelUrl:n,position:[s.position[0],(s.position[1]||0)+1.5,s.position[2]],rotation:s.rotation||[0,0,0],scale:r.scale||[1,1,1],placement_type:"wall_mounted",replacedPiece:t}),J(`${r.name} added`);return}Kt({productId:r.id,variantId:r.id,name:r.name??"product",compatibleGraphIds:Array.isArray(r.compatibleSlots)?r.compatibleSlots:Array.isArray(r.compatible_slots)?r.compatible_slots:[]}),J(`Click a highlighted slot to place ${r.name}.`)},Ie=()=>{Gt(),Mt()},Ue=e=>{const g=e?.feature_id??e?.id;let r=e?O(e)||[]:[];const i=H&&Pe&&Pe.size>0;let n=r.filter(t=>Pt(g,t.id));i&&(n=n.filter(t=>!Pe.has(String(t.id))));const o=n.map(t=>{const s=[t.value_product,t.valueProduct,typeof t.value=="number"?t.value:null].filter(c=>c!=null);let a=null,l=null;for(const c of s){const v=w().getHostedProduct(c);if(v){l=v,a=c;break}}l||(l={id:a??t.id,optionId:t.id,name:t.name||t.displayName||t.label||`Option ${t.id}`,thumbnail:t.thumbnail||t.thumbnailUrl||t.thumbnail_url||t.imageUrl||t.image_url||null,placement_type:"replace_full"});const h=l.optionId??l.option_id??l.id??t.id,_=lt?.some(c=>String(c.optionId)===String(h)||String(c.optionId)===String(l.id))||G?.some(c=>String(c.hostedProductId)===String(h)||String(c.hostedProductId)===String(l.id))||Object.values(re||{}).some(c=>String(c.variantId??c.productId)===String(l.id));let P=!1;if(!_){const c=new Set((l.compatibleSlots??l.compatible_slots??[]).map(String)),v=w();P=ze(l)?Object.keys(re||{}).length>0:c.size>0&&Object.values(re||{}).some(I=>{const W=v.getProduct?.(I.variantId)||v.getProduct?.(I.productId),D=W?.product_graph??W?.productGraph;return D!=null&&c.has(String(D))})}const ne=!je(g,t.id),y=ne||!_&&!P,b=ne?"Not available":null;return{id:h,optId:t.id,name:l.name||String(h),thumbnail:l.thumbnail||l.thumbnailUrl||l.icon||null,description:l.description,isPlaced:_,isDisabled:y,disabledReason:b,canReplace:_,_hostedProductRecord:l}});return o.length===0?null:d(N,{title:e?.name?.toUpperCase()||"APPLIANCES",presentation:e?.presentation,gridClassName:"thumbnail-grid thumbnail-grid--hosted",beforeGrid:ye&&d("p",{className:"sidebar__hint",children:"Click on a highlighted slot in the scene to place the hostedProduct"}),children:o.map(t=>d(nt,{hostedProduct:t,isSelected:ye?.id===t.id||String(Le?.productId)===String(t.id),isPlaced:t.isPlaced,canReplace:t.canReplace,isDisabled:t.isDisabled,onClick:()=>mt(t,e)},t.optId??t.id))})},Me=(e,g)=>{if(!e)return null;const r=g||new Set;if(e.contentKind==="group"||Array.isArray(e.childOptionSetIds)&&e.childOptionSetIds.length>0){if(r.has(e.id))return null;const i=r.size;r.add(e.id);const n=w().features,o=e.childOptionSetIds&&e.childOptionSetIds.length?e.childOptionSetIds:n[e.id]?.childOptionSetIds||[],t=s=>{const a=n[s];if(!a)return null;let l=a.type;return(l==="layout_change"||l==="load_configuration")&&(l="layout_change"),{id:s,feature_id:s,name:a.name,type:l,contentKind:a.contentKind||"options",childOptionSetIds:a.childOptionSetIds||[],default_option_id:a.default_option_id??a.defaultOption,...a.presentation?{presentation:a.presentation}:{}}};return d(N,{labelKey:e.id,sectionRef:s=>de.current[e.id]=s,className:`sidebar__section sidebar__section--group ${z===e.id?"sidebar__section--highlighted":""}`,title:e.name?.toUpperCase(),presentation:e.presentation||"inline",flow:e.flow||"column",kind:"group",depth:i,children:o.map(s=>{const a=t(s);return a?d("div",{className:"sidebar__group-child",children:Me(a,r)},s):null})},e.id)}if(e.type==="layout_change")return d(N,{labelKey:e.id,sectionRef:i=>de.current[e.id]=i,className:`sidebar__section ${z===e.id?"sidebar__section--highlighted":""}`,title:e.name?.toUpperCase()||"LAYOUT",presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--layout",children:q(e.id,O(e)).map(i=>d(tt,{option:Y(e.id,i).disabled?{...i,...Y(e.id,i)}:i,isSelected:A(e.id)===i.id,onClick:()=>{if(A(e.id)===i.id)return;const n=pe(),o=n.initialPerPieceOverrides||{},t=(y,b)=>{if(y===b)return!1;const c=y||{},v=b||{},I=Object.keys(c),W=Object.keys(v);if(I.length!==W.length)return!0;for(const D of I)if(c[D]!==v[D])return!0;return!1},a=((y,b)=>{if(y===b)return!1;const c=y||[],v=b||[];if(c.length!==v.length)return!0;for(let I=0;I<c.length;I++)if(c[I]!==v[I])return!0;return!1})(G,o.sceneHostedProducts)||t(n.hostFinishes,o.hostFinishes)||t(n.hostStyles,o.hostStyles)||t(n.hostHandleTypes,o.hostHandleTypes)||t(n.hostWidths,o.hostWidths)||t(n.hostDoorTypes,o.hostDoorTypes)||t(n.hostProductOverrides,o.hostProductOverrides)||t(n.hostHardwareFinishes,o.hostHardwareFinishes),l=o.sceneSelections||{},h=M.some(y=>{if(y.type==="layout_change")return!1;const b=pt[y.id];if(!b)return!1;const c=l[y.id];return c!==void 0?b!==c:y.default_option_id?b!==y.default_option_id:Ee[b]?.value!==null}),_=!!n.initialPieceConfigSnapshot&&!!n.pieceConfigSnapshot&&n.pieceConfigSnapshot!==n.initialPieceConfigSnapshot,P=(n.disabledWalls||[]).length>0;a||h||_||P?B({title:"Change Layout",message:"You will lose the existing configuration. Do you want to continue?",confirmText:"Yes",cancelText:"No",onConfirm:()=>{Et(),le(e.id,i.id)},onCancel:()=>{}}):le(e.id,i.id)}},i.id))},e.id);if(e.type==="load_new_product"){const i=O(e),n=w().products;if(i.some(t=>{const s=t.value_product??t.valueProduct??(typeof t.value=="number"?t.value:null)??(typeof t.value=="string"&&n[t.value]?t.value:null);return s!=null&&n[s]?.category==="island"}))return d(it,{optionSet:e,getOptionsForSet:O,feature:e,getOptionsForFeature:O,getSelection:A,onSelectionChange:le},e.id)}if(e.type==="finish_change"&&!H){const i=O(e);if(i.length>0&&i.some(o=>!!x?.[o.value]))return d(N,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--finish",children:q(e.id,i).map(o=>{const t=Y(e.id,o);return d(Se,{option:t.disabled?{...o,...t}:o,material:x[o.value],isSelected:A(e.id)===o.id,onClick:()=>{le(e.id,o.id,e)}},o.id)})},e.id)}{const i=w().products,n=O(e);if(e.type==="appliance_selection"||n.some(t=>{const s=t.value_product??t.valueProduct;return s!=null&&Ht(i?.[s])}))return Ue(e)}if(e.type==="load_new_component"||e.type==="load_new_product"||e.type==="product_change"){let i=null;if((e.type==="load_new_product"||e.type==="product_change")&&H&&f!=null){const n=De(f),o=Qe(O(e),n,w().products);o&&(i=o.id)}return d(N,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--options",children:q(e.id,O(e)).map(n=>{const o=!je(e.id,n.id);return d(se,{option:o?{...n,disabled:!0,disabledReason:o?"Not available":null}:n,isSelected:i!=null?String(i)===String(n.id):String(A(e.id))===String(n.id),onClick:()=>Qt(e,n)},n.id)})},e.id)}if(e.type==="appliance_selection")return Ue(e);if(e.type==="finish_change"&&!H)return d(N,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:"thumbnail-grid thumbnail-grid--options",children:q(e.id,O(e)).map(i=>{const n=Y(e.id,i);return d(se,{option:n.disabled?{...i,...n}:i,isSelected:A(e.id)===i.id,onClick:()=>{if(n.disabled)return;const o=U?.[e.id]||U?.[String(e.id)]||e;we({option:i,feature:{...e||{},...o},scope:H?"single":"all",pieceIndex:H?f:null}).scope||qe(e.id,i.id)}},i.id)})},e.id);if(e.type==="finish_change"&&H){const i=O(e),n=i.length>0&&i.some(t=>!!x?.[t.value]),o=t=>{const s=U?.[e.id]||U?.[String(e.id)]||e;we({option:t,feature:{...e||{},...s},scope:H?"single":"all",pieceIndex:H?f:null}).scope||qe(e.id,t.id)};return d(N,{labelKey:e.id,title:e.name?.toUpperCase(),presentation:e.presentation,flow:e.flow,gridClassName:`thumbnail-grid ${n?"thumbnail-grid--finish":"thumbnail-grid--options"}`,children:q(e.id,i).map(t=>{const s=Y(e.id,t),a=s.disabled?{...t,...s}:t;return n?d(Se,{option:a,material:x[t.value],isSelected:A(e.id)===t.id,onClick:()=>{s.disabled||o(t)}},t.id):d(se,{option:a,isSelected:A(e.id)===t.id,onClick:()=>{s.disabled||o(t)}},t.id)})},e.id)}return null},te=()=>C(Q,{children:[d(Xe,{name:"sidebar-top",ctx:{placementId:f??null}}),(()=>{const e=(()=>{if(!(H&&f!=null))return null;const i=w(),n=Te(),o=n.productInstances?.[f];let t=o?.variantId??o?.productId;if(t==null&&String(f).endsWith("__host")){const h=String(f).replace(/__host$/,""),_=n.productInstances?.[h],P=i.getProduct?.(_?.variantId??_?.productId);t=Je(P,_)}t=t??pe().hostProductOverrides?.[f]??f;const s=i.getProduct?.(t)||i.getProduct?.(f),a=s?.optionSets||s?.features_configuration_ids||[];if(!Array.isArray(a)||a.length===0)return null;const l=new Set;for(const h of a){const _=h&&typeof h=="object"?h.optionSetId??h.option_set_id??h.id??h.feature_id:h;_!=null&&l.add(String(_))}return l})(),g=new Set,r=Array.isArray(T)?new Set(T.map(String)):null;return M.filter(i=>{const n=String(i?.feature_id??i?.id??"");return!n||g.has(n)||(g.add(n),r&&!r.has(n)&&!r.has(String(i?.id))&&!r.has(String(i?.feature_id)))?!1:i?.type==="finish_change"?!0:!(e&&!e.has(n)&&!e.has(String(i?.id))&&!e.has(String(i?.feature_id)))}).map(i=>d("div",{children:Me(i)},i.id))})(),d(Xe,{name:"sidebar-bottom",ctx:{placementId:f??null}})]}),St=()=>{const e=f,g=It(e),r=[...Ke(e)].filter(t=>!g||g.includes(String(t.optionSetId))).sort((t,s)=>(t.sequence??0)-(s.sequence??0)),i=Array.isArray(T)?new Set(T.map(String)):null;let n=r;if(i){const t=r.filter(s=>i.has(String(s.optionSetId)));t.length>0&&(n=t)}const o=vt(e)||{};return!n.length&&!fe?null:C(Q,{children:[fe&&d("div",{style:{display:"flex",alignItems:"center",gap:6,padding:"8px 12px",marginBottom:10,borderRadius:6,fontSize:13,background:"rgba(120,120,120,0.12)",borderLeft:"3px solid #888",color:"inherit"},children:"\u{1F512} This item is locked and can\u2019t be changed."}),d("div",{style:fe?{opacity:.5,pointerEvents:"none"}:void 0,children:n.map(t=>{const s=t.optionSetId,a=U[s]||U[String(s)]||{id:s,name:""},l=a.type,h={id:s,feature_id:s,name:a.name,options:a.options},_=new Set((t.available||[]).map(String)),P=O(h);if(!P.length)return null;const ne=l==="load_new_product"||l==="product_change",y=/finish/i.test(String(l||"")),b=!ne&&P.length>0&&(y?P.some(p=>!!x?.[p.value]):P.every(p=>!!x?.[p.value])),c=o[s]??o[String(s)]??t.default??null;let v=null;if(l==="load_new_product"||l==="product_change"){const p=De(e),k=Qe(P,p,w().products);k&&(v=k.id)}let I=null;if(b){const p=et?.[e]||{},k=new Set((a.material_targets??a.materialTargets??a.materials??[]).map(m=>String(m).toLowerCase())),V=new Set(Object.entries(p).filter(([m])=>k.size===0||k.has(String(m).toLowerCase())).map(([,m])=>String(m)));if(V.size>0){const m=P.find(K=>K.value!=null&&V.has(String(K.value)));m&&(I=m.id)}}const W=v??I??c,D=p=>{if(l&&/finish/i.test(String(l))){we({option:p,feature:a,scope:"single",pieceIndex:e});return}const k=String(e).endsWith("__host");if(l==="load_new_product"||k&&l==="product_change"){const m=p.value??p.valueText??p.value_text??p.valueProductVariantId??p.value_product_variant_id,K=w().products,ce=m!=null?K[m]||K[String(m)]:null;if(k){const $e=ce?.id??m;if($e==null)return;import("./a77b15c0d6.js").then(({changeHostVariantForProduct:_t})=>_t({placementId:String(e).replace(/__host$/,""),variantId:$e})).catch(()=>{});return}}const V=String(e).endsWith("__host")?String(e).replace(/__host$/,""):e;import("./a77b15c0d6.js").then(({selectOptionForProduct:m})=>m({placementId:V,optionSetId:s,optionId:p.id})).catch(()=>{})};return d(N,{labelKey:s,title:String(a.name||"").toUpperCase(),presentation:a.presentation,flow:a.flow,gridClassName:`thumbnail-grid ${b?"thumbnail-grid--finish":"thumbnail-grid--options"}`,children:q(s,P).map(p=>{const k=Y(s,p),V=_.size>0&&!_.has(String(p.id)),m=k.disabled||V,K=k.disabledReason||(V?"Not available":null),ce=m?{...p,disabled:!0,disabledReason:K}:p;return b?d(Se,{option:ce,material:x[p.value],isSelected:String(W)===String(p.id),onClick:()=>{m||D(p)}},p.id):d(se,{option:ce,isSelected:String(W)===String(p.id),onClick:()=>{m||D(p)}},p.id)})},s)})})]})},$=be!=null,ae=$&&[...Ke(f)||[]].length>0,Ce=()=>ae?St()??te():te();return R?C("div",{className:"sidebar sidebar--embedded",style:oe?{opacity:.5,pointerEvents:"none"}:void 0,children:[$&&ae&&ee&&d("div",{className:"sidebar__mobile-header",children:C("button",{className:"sidebar__back-btn",onClick:Ie,children:[d(ke,{}),d("span",{children:"Selected"})]})}),d("div",{className:"sidebar__content",children:$?Ce():te()}),d(_e,{dialog:j,onClose:()=>B(null)})]}):ot?st?C(Q,{children:[$&&ae&&ee&&d("div",{className:"sidebar__mobile-header",children:C("button",{className:"sidebar__back-btn",onClick:Ie,children:[d(ke,{}),d("span",{children:"Selected"})]})}),d("div",{className:"sidebar__content sidebar__content--mobile",children:$?Ce():te()}),d(_e,{dialog:j,onClose:()=>B(null)})]}):C(Q,{children:[C("div",{"data-sdk-overlay":!0,className:"sidebar-container",style:oe?{opacity:.5,pointerEvents:"none"}:void 0,children:[C("aside",{className:"sidebar sidebar--card",children:[d("div",{className:"sidebar__header",children:$&&ae?C("button",{className:"sidebar__back-btn",onClick:Ie,children:[d(ke,{}),d("span",{children:"Selected"})]}):C(Q,{children:[C("div",{className:"sidebar__logo",children:[ie?C(Q,{children:[d(Ct,{className:"sidebar__logo-icon"}),d("span",{className:"sidebar__logo-divider"})]}):null,d("span",{className:"sidebar__logo-text",children:ut||"Configurator"})]}),d("div",{className:"sidebar__header-actions"})]})}),d("div",{className:"sidebar__content",children:$?Ce():te()})]}),Ae&&d("div",{className:"sidebar-chat-card",children:d(Ne,{})})]}),d(_e,{dialog:j,onClose:()=>B(null)})]}):Ae?d("div",{"data-sdk-overlay":!0,className:"sidebar-container sidebar-container--chat-only",children:d("div",{className:"sidebar-chat-card",children:d(Ne,{})})}):null}var qi=dn;export{qi as default};
@@ -0,0 +1 @@
1
+ const s=t=>t?.hostVariantId??t?.host_variant_id??null;function e(t){const n=t?.hostVariants??t?.host_variants;return Array.isArray(n)?n:[]}function l(t,n){const i=e(t);if(!i.length)return null;const o=n?.hostVariantId??n?.host_variant_id??null;if(o!=null){const r=i.find(a=>String(s(a))===String(o));if(r)return r}return i.find(r=>r?.isDefault??r?.is_default)??i[0]??null}function u(t,n){return s(l(t,n))}export{e as hostVariantsOf,l as resolveHostEntry,u as resolveHostVariantId};
@@ -1 +1 @@
1
- import{jsx as A,jsxs as ot}from"react/jsx-runtime";import{useRef as H,useMemo as k,useEffect as G,useState as N,Suspense as $}from"react";import{useGLTF as q,Edges as J}from"@react-three/drei";import*as i from"three";import Q from"./9c6c598569.js";import F from"./872c4302e0.js";import Y from"./609e5e5d28.js";import{useComponentOverride as Z,_trackMount as K}from"./a3c983d431.js";import{getFlatMaterial as V}from"./c44d37da7a.js";import tt from"./983cbed22c.js";import{resolveMaterial as rt}from"./95a44ebec2.js";const et={"bottom-center":{x:"c",y:"min",z:"c"},"front-bottom-center":{x:"c",y:"min",z:"max"},"back-bottom-center":{x:"c",y:"min",z:"min"},"left-bottom-center":{x:"min",y:"min",z:"c"},"right-bottom-center":{x:"max",y:"min",z:"c"},"front-left-bottom-center":{x:"min",y:"min",z:"max"},"front-right-bottom-center":{x:"max",y:"min",z:"max"},"back-left-bottom-center":{x:"min",y:"min",z:"min"},"back-right-bottom-center":{x:"max",y:"min",z:"min"}};function nt({url:e,material:n,position:u,rotation:R,scale:W,skirt:w,onClick:p,isSelected:C,onMeasure:b,recalcPosition:D,slotName:y,slotKey:I,componentId:B,pivot:P,children:T}){const S=H(),{scene:d}=q(e,"/assets/draco/"),[E,z]=N(0),L=H(null);G(()=>{if(!D||!S.current){L.current=null,z(0);return}const r=S.current;r.updateWorldMatrix(!0,!0);const l=new i.Matrix4().copy(r.matrixWorld).invert(),a=r.parent?new i.Matrix4().copy(r.parent.matrixWorld).invert():new i.Matrix4,o=new i.Matrix4().multiplyMatrices(a,r.matrixWorld),s=new i.Box3,c=new i.Box3,v=new i.Matrix4;if(r.traverse(g=>{!g.isMesh||!g.geometry||(g.geometry.boundingBox||g.geometry.computeBoundingBox(),v.multiplyMatrices(o,new i.Matrix4().multiplyMatrices(l,g.matrixWorld)),c.copy(g.geometry.boundingBox).applyMatrix4(v),s.union(c))}),s.isEmpty())return;const t=(s.max.x-s.min.x)/2,x=(Array.isArray(u)&&u[0]||0)<0?-1:1;let f=L.current;if(L.current=t,f==null&&(f=.1),f==null){z(0);return}if(Math.abs(t-f)<1e-4)return;const h=x*(t-f);z(g=>g+h)},[d,D,u]),G(()=>{if(!b||!d)return;d.updateMatrixWorld(!0);const r=new i.Box3,l=new i.Box3;if(d.traverse(s=>{if(!s.isMesh||!s.geometry)return;const c=`${s.name||""} ${s.material?.name||""}`.toLowerCase();/shadow|contact[\s_-]?shadow|ao[\s_-]?(plane|map)|ground[\s_-]?plane/.test(c)||(s.geometry.boundingBox||s.geometry.computeBoundingBox(),l.copy(s.geometry.boundingBox).applyMatrix4(s.matrixWorld),r.union(l))}),r.isEmpty())return;const a=r.getSize(new i.Vector3),o=r.getCenter(new i.Vector3);(a.x>0||a.y>0||a.z>0)&&b({width:a.x,height:a.y,depth:a.z,cx:o.x,cy:o.y,cz:o.z})},[d,b]);const M=k(()=>{const r=d.clone(!0),l=y!=null&&String(y)!==""?String(y):null;l&&(r.name=l),r.userData={...r.userData,slotKey:I,componentId:B,slotName:l};let a=null;if(w){const o=new i.Box3().setFromObject(r);a=o.min.y+(o.max.y-o.min.y)*.12}return r.traverse(o=>{if(o.userData={...o.userData,slotKey:I,componentId:B,slotName:l},o.isMesh&&(o.castShadow=!0,o.receiveShadow=!0,n)){const s=n.clone();a!=null&&o.geometry?.attributes?.position&&s.color&&new i.Box3().setFromBufferAttribute(o.geometry.attributes.position).max.y<a&&s.color.multiplyScalar(.65),C&&(s.emissive=new i.Color("#ff6b35"),s.emissiveIntensity=1),o.material=s}}),r},[d,n,C,w,y,I,B]);G(()=>()=>{M.traverse(r=>{r.isMesh&&r.material&&r.material.dispose()})},[M]);const j=k(()=>{const r=et[P||"model-derived"];if(!r)return null;M.updateMatrixWorld(!0);const l=new i.Matrix4().copy(M.matrixWorld).invert(),a=new i.Box3,o=new i.Box3,s=new i.Matrix4;if(M.traverse(_=>{!_.isMesh||!_.geometry||(_.geometry.boundingBox||_.geometry.computeBoundingBox(),o.copy(_.geometry.boundingBox),s.multiplyMatrices(l,_.matrixWorld),o.applyMatrix4(s),a.union(o))}),a.isEmpty())return null;const{min:c,max:v}=a,t=(c.x+v.x)/2,m=(c.y+v.y)/2,x=(c.z+v.z)/2,f=r.x==="min"?c.x:r.x==="max"?v.x:t,h=r.y==="min"?c.y:m,g=r.z==="min"?c.z:r.z==="max"?v.z:x;return[-f,-h,-g]},[M,P]),O=D&&E&&Array.isArray(u)?[(u[0]||0)+E,u[1]||0,u[2]||0]:u;return ot("group",{ref:S,name:y!=null?String(y):void 0,userData:{slotKey:I,componentId:B,slotName:y!=null?String(y):void 0},position:O,rotation:R,scale:W,onClick:p,children:[j?A("group",{position:j,children:A("primitive",{object:M})}):A("primitive",{object:M}),T]})}function gt({geometry:e,material:n,position:u,onClick:R,isSelected:W}){const w=H(),p=k(()=>{if(W){const C=n.clone();return C.emissive=new i.Color("#ff6b35"),C.emissiveIntensity=1,C}return n},[n,W]);return G(()=>()=>{p!==n&&p.dispose()},[p,n]),A("mesh",{ref:w,geometry:e,material:p,position:u,onClick:R,castShadow:!0,receiveShadow:!0,children:W&&A(J,{scale:1.01,threshold:15,color:"#ff6b35",linewidth:3})})}const X={visible:!0,materialId:null};function U({component:e,componentState:n,instanceId:u,isSelected:R,onMeasure:W,onPick:w,slotName:p,slotKey:C,componentId:b,pivot:D,hiddenComponentIds:y,onDescendantMeasured:I,slotMaterials:B}){const P=Q(t=>t.selectInstance),T=F(t=>t.getMaterial),S=F(t=>t.getComponent),d=Z(p,e?.name??e?.componentName,b);d?.materialId&&(n={...n,materialId:d.materialId}),G(()=>K({name:e?.name??e?.componentName??null,slotName:p??null,componentId:b!=null?String(b):null,instanceId:u??null}),[e?.name,e?.componentName,p,b,u]);const{physicalMat:E}=Y(n.materialId,{getMaterial:T}),z=k(()=>{const t=n.variantId&&e.style_variants?e.style_variants[n.variantId]:null,m=e.variants,x=m&&typeof m=="object"?m.default||Object.values(m)[0]:null;return t||e.url||e.asset_url||e.modelPath||e.model_path||e.modelUrl||e.model_url||x||null},[e,n.variantId]),L=k(()=>{if(!z||typeof z!="string")return!1;const t=z.split(/[?#]/)[0].toLowerCase();return t.endsWith(".glb")||t.endsWith(".gltf")},[z]),M=k(()=>{if(E)return E;if(n.materialId){const t=T(n.materialId),m=rt({...n,materialId:n.materialId,definition:t},{THREE:i,Default:()=>t&&t.color?V({color:t.color||"#808080",roughness:t.roughness||.5,metalness:t.metalness||0}):null});if(m)return m;if(t&&t.color)return V({color:t.color||"#808080",roughness:t.roughness||.5,metalness:t.metalness||0})}return n.color?V({color:n.color,roughness:n.roughness??.5,metalness:n.metalness??0}):null},[n.materialId,n.color,n.roughness,n.metalness,T,E]),j=t=>{t.stopPropagation();const m=b??e?.id??null;if(w){w(m);return}P(u,m)},O=e.position||[0,0,0],r=e.rotation||e.orientation||[0,0,0],l=Math.PI/180,a=Array.isArray(r)&&r.length===3?e.rotationRad?[r[0],r[1],r[2]]:[r[0]*l,r[1]*l,r[2]*l]:[0,0,0];let o=e.scale||[1,1,1],s=O,c=a;if(d?.transform){const t=d.transform;t.position&&(s=[O[0]+t.position[0],O[1]+t.position[1],O[2]+t.position[2]]),t.rotation&&(c=[a[0]+t.rotation[0]*l,a[1]+t.rotation[1]*l,a[2]+t.rotation[2]*l]),t.scale&&(o=[o[0]*t.scale[0],o[1]*t.scale[1],o[2]*t.scale[2]])}const v=k(()=>{const t=Array.isArray(e.children)?e.children:[];if(!t.length)return null;const m=Array.isArray(y)&&y.length?new Set(y.map(x=>String(x))):null;return t.map(x=>{const f=x.componentId??x.component_id;if(m&&f!=null&&m.has(String(f)))return null;const h=f!=null?S(f):null;if(!h)return null;const g=String(h.materialSlot??h.material_slot??"").toLowerCase(),_=B&&g?B[g]:null;return A(U,{component:{...h,position:x.position,rotation:x.rotation,scale:x.scale},componentState:_?{...X,materialId:_}:X,instanceId:u,componentId:f,slotKey:h.materialSlot??h.name??String(f),slotName:h.name??null,onPick:w,hiddenComponentIds:y,slotMaterials:B,onMeasure:I,onDescendantMeasured:I},x.id??f)})},[e.children,S,u,w,y,I,B]);return d?.hidden?null:L?A(tt,{children:A($,{children:A(nt,{url:z,material:M,position:s,rotation:c,scale:o,skirt:e.skirt,onClick:j,isSelected:R,onMeasure:W,recalcPosition:e.recalcPosition,slotName:p,slotKey:C,componentId:b,pivot:D,children:v})})}):null}var dt=U;export{dt as default};
1
+ import{jsx as _,jsxs as st}from"react/jsx-runtime";import{useRef as H,useMemo as S,useEffect as D,useState as $,Suspense as q}from"react";import{useGLTF as J,Edges as Q}from"@react-three/drei";import*as u from"three";import Y from"./9c6c598569.js";import F from"./872c4302e0.js";import Z from"./609e5e5d28.js";import{useComponentOverride as K,_trackMount as tt}from"./a3c983d431.js";import{getFlatMaterial as V}from"./c44d37da7a.js";import rt from"./983cbed22c.js";import{resolveMaterial as et}from"./95a44ebec2.js";const nt={"bottom-center":{x:"c",y:"min",z:"c"},"front-bottom-center":{x:"c",y:"min",z:"max"},"back-bottom-center":{x:"c",y:"min",z:"min"},"left-bottom-center":{x:"min",y:"min",z:"c"},"right-bottom-center":{x:"max",y:"min",z:"c"},"front-left-bottom-center":{x:"min",y:"min",z:"max"},"front-right-bottom-center":{x:"max",y:"min",z:"max"},"back-left-bottom-center":{x:"min",y:"min",z:"min"},"back-right-bottom-center":{x:"max",y:"min",z:"min"}};function X(r){r.updateMatrixWorld(!0);const n=new u.Matrix4().copy(r.matrixWorld).invert(),a=new u.Box3,w=new u.Box3,v=new u.Matrix4;return r.traverse(c=>{if(!c.isMesh||!c.geometry)return;const y=`${c.name||""} ${c.material?.name||""}`.toLowerCase();/shadow|contact[\s_-]?shadow|ao[\s_-]?(plane|map)|ground[\s_-]?plane/.test(y)||(c.geometry.boundingBox||c.geometry.computeBoundingBox(),w.copy(c.geometry.boundingBox),v.multiplyMatrices(n,c.matrixWorld),w.applyMatrix4(v),a.union(w))}),a}function ot({url:r,material:n,position:a,rotation:w,scale:v,skirt:c,onClick:y,isSelected:A,onMeasure:d,recalcPosition:T,slotName:f,slotKey:C,componentId:z,pivot:P,children:L}){const W=H(),{scene:h}=J(r,"/assets/draco/"),[E,B]=$(0),G=H(null);D(()=>{if(!T||!W.current){G.current=null,B(0);return}const e=W.current;e.updateWorldMatrix(!0,!0);const i=new u.Matrix4().copy(e.matrixWorld).invert(),s=e.parent?new u.Matrix4().copy(e.parent.matrixWorld).invert():new u.Matrix4,o=new u.Matrix4().multiplyMatrices(s,e.matrixWorld),m=new u.Box3,R=new u.Box3,t=new u.Matrix4;if(e.traverse(p=>{!p.isMesh||!p.geometry||(p.geometry.boundingBox||p.geometry.computeBoundingBox(),t.multiplyMatrices(o,new u.Matrix4().multiplyMatrices(i,p.matrixWorld)),R.copy(p.geometry.boundingBox).applyMatrix4(t),m.union(R))}),m.isEmpty())return;const l=(m.max.x-m.min.x)/2,b=(Array.isArray(a)&&a[0]||0)<0?-1:1;let g=G.current;if(G.current=l,g==null&&(g=.1),g==null){B(0);return}if(Math.abs(l-g)<1e-4)return;const j=b*(l-g);B(p=>p+j)},[h,T,a]);const I=S(()=>{const e=h.clone(!0),i=f!=null&&String(f)!==""?String(f):null;i&&(e.name=i),e.userData={...e.userData,slotKey:C,componentId:z,slotName:i};let s=null;if(c){const o=new u.Box3().setFromObject(e);s=o.min.y+(o.max.y-o.min.y)*.12}return e.traverse(o=>{if(o.userData={...o.userData,slotKey:C,componentId:z,slotName:i},o.isMesh&&(o.castShadow=!0,o.receiveShadow=!0,n)){const m=n.clone();s!=null&&o.geometry?.attributes?.position&&m.color&&new u.Box3().setFromBufferAttribute(o.geometry.attributes.position).max.y<s&&m.color.multiplyScalar(.65),A&&(m.emissive=new u.Color("#ff6b35"),m.emissiveIntensity=1),o.material=m}}),e},[h,n,A,c,f,C,z]);D(()=>()=>{I.traverse(e=>{e.isMesh&&e.material&&e.material.dispose()})},[I]);const O=S(()=>{const e=nt[P||"model-derived"];if(!e)return null;const i=X(I);if(i.isEmpty())return null;const{min:s,max:o}=i,m=(s.x+o.x)/2,R=(s.y+o.y)/2,t=(s.z+o.z)/2,l=e.x==="min"?s.x:e.x==="max"?o.x:m,x=e.y==="min"?s.y:R,b=e.z==="min"?s.z:e.z==="max"?o.z:t;return[-l,-x,-b]},[I,P]);D(()=>{if(!d||!h)return;const e=X(h);if(e.isEmpty())return;const i=e.getSize(new u.Vector3),s=e.getCenter(new u.Vector3),o=O||[0,0,0];(i.x>0||i.y>0||i.z>0)&&d({width:i.x,height:i.y,depth:i.z,cx:s.x+o[0],cy:s.y+o[1],cz:s.z+o[2]})},[h,d,O]);const k=H(d);k.current=d,D(()=>()=>{try{k.current?.(null)}catch{}},[]);const M=T&&E&&Array.isArray(a)?[(a[0]||0)+E,a[1]||0,a[2]||0]:a;return st("group",{ref:W,name:f!=null?String(f):void 0,userData:{slotKey:C,componentId:z,slotName:f!=null?String(f):void 0},position:M,rotation:w,scale:v,onClick:y,children:[O?_("group",{position:O,children:_("primitive",{object:I})}):_("primitive",{object:I}),L]})}function dt({geometry:r,material:n,position:a,onClick:w,isSelected:v}){const c=H(),y=S(()=>{if(v){const A=n.clone();return A.emissive=new u.Color("#ff6b35"),A.emissiveIntensity=1,A}return n},[n,v]);return D(()=>()=>{y!==n&&y.dispose()},[y,n]),_("mesh",{ref:c,geometry:r,material:y,position:a,onClick:w,castShadow:!0,receiveShadow:!0,children:v&&_(Q,{scale:1.01,threshold:15,color:"#ff6b35",linewidth:3})})}const U={visible:!0,materialId:null};function N({component:r,componentState:n,instanceId:a,isSelected:w,onMeasure:v,onPick:c,slotName:y,slotKey:A,componentId:d,pivot:T,hiddenComponentIds:f,onDescendantMeasured:C,slotMaterials:z}){const P=Y(t=>t.selectInstance),L=F(t=>t.getMaterial),W=F(t=>t.getComponent),h=K(y,r?.name??r?.componentName,d);h?.materialId&&(n={...n,materialId:h.materialId}),D(()=>tt({name:r?.name??r?.componentName??null,slotName:y??null,componentId:d!=null?String(d):null,instanceId:a??null}),[r?.name,r?.componentName,y,d,a]);const{physicalMat:E}=Z(n.materialId,{getMaterial:L}),B=S(()=>{const t=n.variantId&&r.style_variants?r.style_variants[n.variantId]:null,l=r.variants,x=l&&typeof l=="object"?l.default||Object.values(l)[0]:null;return t||r.url||r.asset_url||r.modelPath||r.model_path||r.modelUrl||r.model_url||x||null},[r,n.variantId]),G=S(()=>{if(!B||typeof B!="string")return!1;const t=B.split(/[?#]/)[0].toLowerCase();return t.endsWith(".glb")||t.endsWith(".gltf")},[B]),I=S(()=>{if(E)return E;if(n.materialId){const t=L(n.materialId),l=et({...n,materialId:n.materialId,definition:t},{THREE:u,Default:()=>t&&t.color?V({color:t.color||"#808080",roughness:t.roughness||.5,metalness:t.metalness||0}):null});if(l)return l;if(t&&t.color)return V({color:t.color||"#808080",roughness:t.roughness||.5,metalness:t.metalness||0})}return n.color?V({color:n.color,roughness:n.roughness??.5,metalness:n.metalness??0}):null},[n.materialId,n.color,n.roughness,n.metalness,L,E]),O=t=>{t.stopPropagation();const l=d??r?.id??null;if(c){c(l);return}P(a,l)},k=r.position||[0,0,0],M=r.rotation||r.orientation||[0,0,0],e=Math.PI/180,i=Array.isArray(M)&&M.length===3?r.rotationRad?[M[0],M[1],M[2]]:[M[0]*e,M[1]*e,M[2]*e]:[0,0,0];let s=r.scale||[1,1,1],o=k,m=i;if(h?.transform){const t=h.transform;t.position&&(o=[k[0]+t.position[0],k[1]+t.position[1],k[2]+t.position[2]]),t.rotation&&(m=[i[0]+t.rotation[0]*e,i[1]+t.rotation[1]*e,i[2]+t.rotation[2]*e]),t.scale&&(s=[s[0]*t.scale[0],s[1]*t.scale[1],s[2]*t.scale[2]])}const R=S(()=>{const t=Array.isArray(r.children)?r.children:[];if(!t.length)return null;const l=Array.isArray(f)&&f.length?new Set(f.map(x=>String(x))):null;return t.map(x=>{const b=x.componentId??x.component_id;if(l&&b!=null&&l.has(String(b)))return null;const g=b!=null?W(b):null;if(!g)return null;const j=String(g.materialSlot??g.material_slot??"").toLowerCase(),p=z&&j?z[j]:null;return _(N,{component:{...g,position:x.position,rotation:x.rotation,scale:x.scale},componentState:p?{...U,materialId:p}:U,instanceId:a,componentId:b,slotKey:g.materialSlot??g.name??String(b),slotName:g.name??null,onPick:c,hiddenComponentIds:f,slotMaterials:z,onMeasure:C,onDescendantMeasured:C},x.id??b)})},[r.children,W,a,c,f,C,z]);return h?.hidden?null:G?_(rt,{children:_(q,{children:_(ot,{url:B,material:I,position:o,rotation:m,scale:s,skirt:r.skirt,onClick:O,isSelected:w,onMeasure:v,recalcPosition:r.recalcPosition,slotName:y,slotKey:A,componentId:d,pivot:T,children:R})})}):null}var ht=N;export{ht as default};
@@ -1,4 +1,4 @@
1
- import{useMemo as _,useSyncExternalStore as ee}from"react";import{useCopilotAction as D,useCopilotReadable as U,useCopilotAdditionalInstructions as te}from"@copilotkit/react-core";import ne from"./d94df858ea.js";import q from"./8f60e5059a.js";import v from"./9c6c598569.js";import $ from"./872c4302e0.js";import G from"./be337ddda5.js";import{isAddFeature as ie}from"./8c27edda0f.js";import{getPlacementBindings as Y,getEffectiveSelections as ae,subscribe as oe,getVersion as K}from"./817d930a49.js";import{selectOption as se}from"./dbd5ba1d07.js";import{getLastEvaluation as H}from"./9f474b5d1a.js";const X="Adding pieces is not available for the current product.";function j(g=2){return new Promise(A=>{let f=g;const h=()=>{f-=1,f<=0?A():requestAnimationFrame(h)};requestAnimationFrame(h)})}async function re({instanceId:g,featureKey:A,optionKey:f}){if(g==null)return{ok:!1,msg:"No piece is selected. Select a piece first (selectPiece)."};const h=await import("./a77b15c0d6.js"),C=$.getState().features||{},P=$.getState().options||{},W=$.getState().products||{};try{v.getState().selectInstance?.(g)}catch{}try{await h.reevaluateForFocus()}catch{}await j(2);let V=h.getPlacementBindings(g)||[];if(V.length||(await j(2),V=h.getPlacementBindings(g)||[]),!V.length)return{ok:!1,msg:"This piece has no editable options yet \u2014 try selecting it again."};const E=s=>String((C[s]||C[String(s)]||{}).name||""),x=s=>String((C[s]||C[String(s)]||{}).type||""),F=String(A).toLowerCase(),b=V.find(s=>{const T=E(s.optionSetId).toLowerCase();return String(s.optionSetId)===String(A)||T===F||T&&(T.includes(F)||F.includes(T))});if(!b){const s=V.map(T=>E(T.optionSetId)).filter(Boolean).join(", ");return{ok:!1,msg:`"${A}" isn't an option on the selected piece. Available: ${s||"(none)"}.`}}const S=(b.available||[]).map(s=>P[s]||P[String(s)]).filter(Boolean),L=String(f).toLowerCase(),y=S.find(s=>String(s.id)===String(f)||String(s.name).toLowerCase()===L||String(s.name).toLowerCase().includes(L)||L.includes(String(s.name).toLowerCase()));if(!y)return{ok:!1,msg:`"${f}" not available for ${E(b.optionSetId)||"that feature"}. Available: ${S.map(s=>s.name).join(", ")||"(none)"}.`};const R=E(b.optionSetId)||"Feature",N=/finish/i.test(x(b.optionSetId))||/finish|colou?r|material/i.test(R);try{if(N){const{applyFinishClick:s}=await import("./dc2a1a0e13.js"),T=C[b.optionSetId]||C[String(b.optionSetId)]||{},M=s({option:y,feature:{...T,id:b.optionSetId,name:T.name||R},scope:"single",pieceIndex:g});if(!M||M.ok===!1)return{ok:!1,msg:`Couldn't apply ${y.name} \u2014 ${R} has no matching material slot on this piece.`}}else{const s=y.value;s!=null&&!!(W[s]||W[String(s)])?await h.changeProductVariant({placementId:g,variantId:s}):await h.selectOptionForProduct({placementId:g,optionSetId:b.optionSetId,optionId:y.id})}}catch(s){return{ok:!1,msg:`Couldn't change ${R}: ${s?.message||"engine error"}.`}}return{ok:!0,msg:`${R} changed to ${y.name} for the selected piece.`}}async function ce(g,A){const f=A!=null?String(A).match(/\d+(?:\.\d+)?/g):null;if(!f||!f.length||g==null)return{ok:!1,reason:"no-size"};const h=await import("./a77b15c0d6.js"),C=$.getState().features||{},P=$.getState().options||{},W=$.getState().products||{};try{v.getState().selectInstance?.(g)}catch{}try{await h.reevaluateForFocus()}catch{}await j(2);const E=(h.getPlacementBindings(g)||[]).find(S=>{const L=C[S.optionSetId]||C[String(S.optionSetId)];return/width|frame|size/i.test(String(L?.name||""))});if(!E)return{ok:!1,reason:"no-binding"};const x=(E.available||[]).map(S=>P[S]||P[String(S)]).filter(Boolean),F=x.find(S=>f.every(L=>String(S.name).includes(L)))||x.find(S=>String(S.name).includes(f[f.length-1]));if(!F)return{ok:!1,reason:"no-match",available:x.map(S=>S.name)};try{const S=F.value;S!=null&&!!(W[S]||W[String(S)])?await h.changeProductVariant({placementId:g,variantId:S}):await h.selectOptionForProduct({placementId:g,optionSetId:E.optionSetId,optionId:F.id})}catch{return{ok:!1,reason:"apply-failed"}}return{ok:!0,featureName:(C[E.optionSetId]||C[String(E.optionSetId)])?.name||"size",matchedName:F.name}}function le(){try{te({instructions:`
1
+ import{useMemo as B,useSyncExternalStore as ee}from"react";import{useCopilotAction as D,useCopilotReadable as U,useCopilotAdditionalInstructions as te}from"@copilotkit/react-core";import ne from"./d94df858ea.js";import N from"./8f60e5059a.js";import v from"./9c6c598569.js";import $ from"./872c4302e0.js";import G from"./be337ddda5.js";import{isAddFeature as ie}from"./8c27edda0f.js";import{getPlacementBindings as Y,getEffectiveSelections as ae,subscribe as oe,getVersion as _}from"./817d930a49.js";import{selectOption as se}from"./dbd5ba1d07.js";import{getLastEvaluation as H}from"./9f474b5d1a.js";import{resolveHostVariantId as re}from"./be07a7f885.js";const K="Adding pieces is not available for the current product.";function q(g=2){return new Promise(A=>{let f=g;const h=()=>{f-=1,f<=0?A():requestAnimationFrame(h)};requestAnimationFrame(h)})}async function ce({instanceId:g,featureKey:A,optionKey:f}){if(g==null)return{ok:!1,msg:"No piece is selected. Select a piece first (selectPiece)."};const h=await import("./a77b15c0d6.js"),C=$.getState().features||{},P=$.getState().options||{},M=$.getState().products||{};try{v.getState().selectInstance?.(g)}catch{}try{await h.reevaluateForFocus()}catch{}await q(2);let j=h.getPlacementBindings(g)||[];if(j.length||(await q(2),j=h.getPlacementBindings(g)||[]),!j.length)return{ok:!1,msg:"This piece has no editable options yet \u2014 try selecting it again."};const E=s=>String((C[s]||C[String(s)]||{}).name||""),V=s=>String((C[s]||C[String(s)]||{}).type||""),F=String(A).toLowerCase(),b=j.find(s=>{const T=E(s.optionSetId).toLowerCase();return String(s.optionSetId)===String(A)||T===F||T&&(T.includes(F)||F.includes(T))});if(!b){const s=j.map(T=>E(T.optionSetId)).filter(Boolean).join(", ");return{ok:!1,msg:`"${A}" isn't an option on the selected piece. Available: ${s||"(none)"}.`}}const S=(b.available||[]).map(s=>P[s]||P[String(s)]).filter(Boolean),L=String(f).toLowerCase(),y=S.find(s=>String(s.id)===String(f)||String(s.name).toLowerCase()===L||String(s.name).toLowerCase().includes(L)||L.includes(String(s.name).toLowerCase()));if(!y)return{ok:!1,msg:`"${f}" not available for ${E(b.optionSetId)||"that feature"}. Available: ${S.map(s=>s.name).join(", ")||"(none)"}.`};const x=E(b.optionSetId)||"Feature",O=/finish/i.test(V(b.optionSetId))||/finish|colou?r|material/i.test(x);try{if(O){const{applyFinishClick:s}=await import("./dc2a1a0e13.js"),T=C[b.optionSetId]||C[String(b.optionSetId)]||{},R=s({option:y,feature:{...T,id:b.optionSetId,name:T.name||x},scope:"single",pieceIndex:g});if(!R||R.ok===!1)return{ok:!1,msg:`Couldn't apply ${y.name} \u2014 ${x} has no matching material slot on this piece.`}}else{const s=y.value;s!=null&&!!(M[s]||M[String(s)])?await h.changeProductVariant({placementId:g,variantId:s}):await h.selectOptionForProduct({placementId:g,optionSetId:b.optionSetId,optionId:y.id})}}catch(s){return{ok:!1,msg:`Couldn't change ${x}: ${s?.message||"engine error"}.`}}return{ok:!0,msg:`${x} changed to ${y.name} for the selected piece.`}}async function le(g,A){const f=A!=null?String(A).match(/\d+(?:\.\d+)?/g):null;if(!f||!f.length||g==null)return{ok:!1,reason:"no-size"};const h=await import("./a77b15c0d6.js"),C=$.getState().features||{},P=$.getState().options||{},M=$.getState().products||{};try{v.getState().selectInstance?.(g)}catch{}try{await h.reevaluateForFocus()}catch{}await q(2);const E=(h.getPlacementBindings(g)||[]).find(S=>{const L=C[S.optionSetId]||C[String(S.optionSetId)];return/width|frame|size/i.test(String(L?.name||""))});if(!E)return{ok:!1,reason:"no-binding"};const V=(E.available||[]).map(S=>P[S]||P[String(S)]).filter(Boolean),F=V.find(S=>f.every(L=>String(S.name).includes(L)))||V.find(S=>String(S.name).includes(f[f.length-1]));if(!F)return{ok:!1,reason:"no-match",available:V.map(S=>S.name)};try{const S=F.value;S!=null&&!!(M[S]||M[String(S)])?await h.changeProductVariant({placementId:g,variantId:S}):await h.selectOptionForProduct({placementId:g,optionSetId:E.optionSetId,optionId:F.id})}catch{return{ok:!1,reason:"apply-failed"}}return{ok:!0,featureName:(C[E.optionSetId]||C[String(E.optionSetId)])?.name||"size",matchedName:F.name}}function de(){try{te({instructions:`
2
2
  You help the user customize the 3D product in the scene. Act immediately \u2014 never ask
3
3
  follow-up questions; infer the best option from the catalogs and execute.
4
4
 
@@ -57,4 +57,4 @@ Match names/options against the catalogs; always pick the closest rather than re
57
57
  NEVER refuse a change by claiming it's "already set" to that value. When the user asks
58
58
  to set a feature to a value, ALWAYS call the tool to apply it \u2014 applying an already-set
59
59
  value is harmless. The current values in sceneInventory.selectedFeatures may be
60
- approximate (per-piece finishes especially), so do not skip the action based on them.`})}catch{}const g=ne(e=>e.sceneSelections),A=v(e=>e.activeSceneConfigId),f=$(e=>e.features),h=$(e=>e.options),C=v(e=>e.productInstances),P=v(e=>e.selectedInstanceId),W=G(e=>e.sceneConfigurations),V=G(e=>e.getSceneFeatures),E=q(e=>e.hostMaterialOverrides),x=ee(oe,K,K),F=$(e=>e.systemUiToggles)||{},b=F.walls!==!1,S=F.dimensions!==!1,L=A?V(A)||[]:[],y=_(()=>L.map(e=>{const t=e.feature_id||e.id,l=f[t]||f[String(t)];let i=(l?.options||[]).map(n=>{const o=typeof n=="string"||typeof n=="number"?n:n?.id,u=h[o]||h[String(o)];return u?{id:u.id,name:u.name}:null}).filter(Boolean);i.length===0&&(i=Object.values(h).filter(n=>n?.optionSetId==t||n?.option_set_id==t||n?.optionSet==t||n?.feature_id==t).sort((n,o)=>(n?.sequence||0)-(o?.sequence||0)).map(n=>({id:n.id,name:n.name})));const d=g[e.id]??g[String(e.id)]??g[t]??g[String(t)]??null,m=d!=null?i.find(n=>String(n.id)===String(d))?.name??null:null;return{sceneFeatureId:e.id,featureId:t,name:e.name||l?.name||t,current:m,currentSelection:d,options:i}}),[L,f,h,g]);U({description:"Scene-wide features and their options for the current product (from the live catalog \u2014 any configurator). Use featureKey when calling selectOption.",value:y});const R=_(()=>{const e=C||{},t=$.getState().products||{},l=n=>{const o=t[n?.variantId]||t[n?.productId]||t[String(n?.variantId)]||t[String(n?.productId)];return String(o?.name||n?.name||"")},i=Object.entries(e).map(([n,o])=>{const u=(Y(n)||[]).map(r=>(f[r.optionSetId]||f[String(r.optionSetId)]||{}).name).filter(Boolean);return{id:n,name:l(o),selected:String(n)===String(P),features:u}});let d=null;if(P!=null){const n=Y(P)||[],o=ae(P)||{},u=E?.[P]||{};d=n.map(r=>{const a=f[r.optionSetId]||f[String(r.optionSetId)],I=a?.name||String(r.optionSetId),c=(r.available||[]).map(w=>h[w]||h[String(w)]).filter(Boolean),k=/finish/i.test(String(a?.type||""))||/finish|colou?r|material/i.test(I);let p=null;if(k){const w=new Set(Object.values(u).map(String));if(p=c.find(O=>O.value!=null&&w.has(String(O.value)))?.name??null,p==null){const O=y.find(B=>String(B.featureId)===String(r.optionSetId)),z=O?g[O.sceneFeatureId]:null;p=z!=null?(h[z]||h[String(z)])?.name??null:null}}else{const w=o[r.optionSetId]??o[String(r.optionSetId)];p=w!=null?(h[w]||h[String(w)])?.name??null:null}return{feature:I,current:p,options:c.map(w=>w.name)}})}const m=i.find(n=>n.selected)?.name||null;return{pieces:i,selectedPiece:m,selectedFeatures:d,note:P==null?'NOTHING is selected. For a "change/delete the selected piece" request, first call selectPiece(description) to select the piece the user means, or reply that no piece is currently selected. Do NOT claim any current value or that something is "already set".':`"${m}" is selected; its changeable features are in selectedFeatures.`}},[C,P,f,h,g,y,E,x]);U({description:"Pieces in the scene (each with its feature names), which is selected, and the selected piece's current values + options. To change a feature of a piece that isn't selected (e.g. a hosted product's option), find the piece in pieces[] whose features include it and selectPiece it \u2014 or just call updatePieceFeature(featureKey, optionKey); it auto-targets the piece that has that feature when only one does.",value:R});const N=_(()=>{const e=new Set((L||[]).filter(t=>ie(t,{productSelected:!1})).map(t=>String(t.feature_id||t.id)));return y.filter(t=>e.has(String(t.featureId))).filter(t=>Array.isArray(t.options)&&t.options.length>0)},[L,y]),s=N.length>0,T=N.map(e=>`${e.name}: ${e.options.map(t=>t.name).join(", ")}`).join("; "),M=N.map(e=>e.name);U({description:"Kinds of pieces that can be ADDED for this product, with their options. Use these exact names as pieceType when calling addPiece.",value:N.map(e=>({pieceType:e.name,options:e.options.map(t=>t.name)}))});const Q=y.map(e=>`${e.name} (e.g. ${e.options.slice(0,3).map(t=>t.name).join(", ")})`).join(", "),J=y.slice(0,4).map(e=>`"${e.name}"`).join(", "),Z=y.flatMap(e=>e.options.slice(0,1)).slice(0,4).map(e=>`"${e.name}"`).join(", ");D({name:"selectOption",description:`Change a scene-wide feature option (finish, layout, door style, handle, \u2026). Features: ${Q}.`,parameters:[{name:"featureKey",type:"string",description:`The feature name or id. Examples: ${J}.`,required:!0},{name:"optionKey",type:"string",description:`The option name or id. Examples: ${Z}.`,required:!0}],handler:async({featureKey:e,optionKey:t})=>{const l=String(e).toLowerCase(),i=y.find(a=>String(a.sceneFeatureId)===String(e)||String(a.featureId)===String(e)||String(a.sceneFeatureId).toLowerCase()===l||String(a.featureId).toLowerCase()===l||String(a.name).toLowerCase()===l||String(a.name).toLowerCase().includes(l)||l.includes(String(a.name).toLowerCase()));if(!i)return`Feature "${e}" not found. Available: ${y.map(a=>a.name).join(", ")}`;const d=String(t).toLowerCase(),m=i.options.find(a=>String(a.id)===String(t)||String(a.id).toLowerCase()===d||String(a.name).toLowerCase()===d||String(a.name).toLowerCase().includes(d)||d.includes(String(a.name).toLowerCase()));if(!m)return`Option "${t}" not found for ${i.name}. Available: ${i.options.map(a=>a.name).join(", ")}`;const n=f[i.featureId]||f[String(i.featureId)]||{id:i.featureId},o=H();let u=!1;try{u=await se(i.featureId,m.id,n),await j(2)}catch(a){return`Could not change ${i.name}: ${a?.message||a}`}const r=H();if(r&&r!==o&&r.rejected){const a=r.errors?.[0]?.message||r.code||"the engine refused it";return`${i.name} could not be changed to ${m.name}: ${a}`}return u===!1?`${i.name} could not be changed to ${m.name}.`:`${i.name} changed to ${m.name}.`}}),D({name:"addPiece",available:s?"enabled":"disabled",description:s?`Add a new piece to the scene. Choose a pieceType and an option (free pieces / corners / hosted products are pieceTypes here too). Available \u2014 ${T}.`:X,parameters:[{name:"pieceType",type:"string",required:!1,description:`Which kind of piece. Valid: ${M.join(", ")||"(none)"}. Optional when there's only one.`,...M.length?{enum:M}:{}},{name:"option",type:"string",required:!0,description:"The option to add \u2014 name or id."},{name:"size",type:"string",required:!1,description:'Optional size/width, e.g. "18" or "30x18". Applied after adding if the piece has a size option.'}],handler:async({pieceType:e,option:t,size:l})=>{if(!s)return X;let i=null;if(e!=null&&String(e).trim()!==""){const c=String(e).trim().toLowerCase();i=N.find(k=>String(k.name).toLowerCase()===c||String(k.featureId).toLowerCase()===c||String(k.name).toLowerCase().includes(c)||c.includes(String(k.name).toLowerCase()))}if(!i&&N.length===1&&(i=N[0]),!i)return`Which piece type? Choose one of: ${M.join(", ")}.`;const d=String(t).trim().toLowerCase(),m=i.options.find(c=>String(c.id)===String(t)||String(c.name).toLowerCase()===d||String(c.name).toLowerCase().includes(d)||d.includes(String(c.name).toLowerCase()));if(!m)return`Option "${t}" not found for ${i.name}. Available: ${i.options.map(c=>c.name).join(", ")}.`;let n,o;const u=new Set(Object.keys(v.getState().productInstances||{}));try{n=await import("./a77b15c0d6.js"),o=await n.addProductFromOption({optionSetId:i.featureId,optionId:m.id})}catch(c){return`Couldn't add ${m.name}: ${c?.message||"the engine is unavailable"}.`}await j(2);let r=o?.addedPlacements?.[0]?.id??null;r==null&&(r=Object.keys(v.getState().productInstances||{}).find(c=>!u.has(c))??null);const a=`Added ${m.name} (${i.name}) to the scene.`;if(l==null||String(l).trim()===""||r==null)return a;const I=await ce(r,l);return I.ok?`Added ${m.name} (${i.name}) and set ${I.featureName} to ${I.matchedName}.`:I.reason==="no-match"?`${a} Couldn't match size "${l}" \u2014 available: ${(I.available||[]).join(", ")||"(none)"}.`:a}}),D({name:"selectPiece",description:'Select a piece in the scene so it can be changed or deleted. Match by product name / description (e.g. "left chaise", "the elevated piece", "the hosted product").',parameters:[{name:"description",type:"string",required:!0,description:"The piece's product name or a description of it."}],handler:async({description:e})=>{const t=v.getState().productInstances||{},l=$.getState().products||{},i=Object.entries(t).map(([o,u])=>{const r=l[u?.variantId]||l[u?.productId]||l[String(u?.variantId)]||l[String(u?.productId)];return{id:o,name:String(r?.name||u?.name||o)}});if(!i.length)return"There are no pieces in the scene to select.";const d=String(e).toLowerCase().trim(),m=d.split(/\s+/).filter(o=>o.length>2),n=i.find(o=>o.name.toLowerCase()===d)||i.find(o=>o.name.toLowerCase().includes(d))||i.find(o=>d.includes(o.name.toLowerCase()))||i.find(o=>m.some(u=>o.name.toLowerCase().includes(u)));if(!n)return`Couldn't find a piece matching "${e}". In the scene: ${i.map(o=>o.name).join(", ")}.`;try{v.getState().selectInstance?.(n.id)}catch{}return await j(2),`Selected ${n.name}. You can now change or delete it.`}}),D({name:"updatePieceFeature",description:"Change a feature (width, door, handle, finish, size, \u2026) on the CURRENTLY SELECTED piece. Select one first with selectPiece. See sceneInventory for the selected piece's features and options.",parameters:[{name:"featureKey",type:"string",required:!0,description:"The feature name (or id) to change \u2014 from the selected piece's features."},{name:"optionKey",type:"string",required:!0,description:"The option name (or id) to select."}],handler:async({featureKey:e,optionKey:t})=>{let l=v.getState().selectedInstanceId;if(l==null){const d=await import("./a77b15c0d6.js"),m=v.getState().productInstances||{},n=$.getState().products||{},o=$.getState().features||{},u=String(e).toLowerCase(),r=Object.keys(m).filter(a=>(d.getPlacementBindings(a)||[]).some(I=>{const c=String((o[I.optionSetId]||o[String(I.optionSetId)]||{}).name||"").toLowerCase();return c&&(c===u||c.includes(u)||u.includes(c))}));if(r.length===1)l=r[0];else if(r.length>1){const a=r.map(I=>{const c=m[I];return(n[c?.variantId]||n[c?.productId])?.name||I});return`Several pieces have a "${e}" option (${a.join(", ")}). Say which one (e.g. by its name), then I'll change it.`}}const i=await re({instanceId:l,featureKey:e,optionKey:t});return await j(2),i.msg}}),D({name:"deleteSelectedPiece",description:"Delete the currently selected piece from the scene. Select one first with selectPiece if needed.",parameters:[],handler:async()=>{const e=v.getState().selectedInstanceId;if(e==null)return"No piece is selected. Select one first (selectPiece).";try{await(await import("./a77b15c0d6.js")).removeProduct(e)}catch(t){return`Couldn't delete the selected piece: ${t?.message||"the engine is unavailable"}.`}try{v.getState().removeProductInstance?.(e)}catch{}try{v.getState().selectInstance?.(null)}catch{}return await j(2),"Deleted the selected piece."}}),D({name:"movePiece",description:"Move/reorder the CURRENTLY SELECTED piece one position left or right within its run. Select a piece first with selectPiece if needed. (Pieces snap into a sequenced run, so this reorders rather than free-positions.)",parameters:[{name:"direction",type:"string",required:!0,enum:["left","right"],description:'"left" or "right".'}],handler:async({direction:e})=>{const t=v.getState(),l=t.selectedInstanceId;if(l==null)return"No piece is selected. Select one first (selectPiece), then say which way to move it.";const i=t.productInstances||{},d=i[l];if(!d)return"The selected piece is no longer in the scene.";const m=p=>p?.placementGroup??p?.placement_group??null,n=p=>{const w=Number(p?.sequence);return Number.isFinite(w)?w:null},o=m(d),u=Object.entries(i).filter(([,p])=>m(p)===o&&n(p)!=null).map(([p,w])=>({id:p,seq:n(w)})).sort((p,w)=>p.seq-w.seq),r=u.findIndex(p=>String(p.id)===String(l));if(r<0||u.length<2)return"There is nothing to reorder \u2014 the selected piece has no neighbours in its run.";const a=/right|next|forward|end/i.test(String(e)),I=a?u[r+1]:u[r-1];if(!I)return a?"The piece is already at the right end of its run.":"The piece is already at the left end of its run.";let c=d?.positionedAbove!=null?String(d.positionedAbove):null,k=null;if(c){const p=i[c];k=p?p.variantId??p.productId??null:null}else{const p=$.getState(),w=p.getProduct?.(d?.variantId)||p.getProduct?.(d?.productId),O=w?.hostVariants??w?.host_variants;if(Array.isArray(O)&&O.length){const z=O.find(B=>B?.isDefault??B?.is_default)||O[0];k=z?.hostVariantId??z?.host_variant_id??null}}try{await(await import("./a77b15c0d6.js")).moveProduct({placementId:l,sequence:Math.round(I.seq),hostPlacementId:c,hostVariantId:k})}catch(p){return`Couldn't move the piece: ${p?.message||"the engine is unavailable"}.`}return await j(2),`Moved the selected piece one position to the ${a?"right":"left"}.`}}),D({name:"toggleFullscreen",description:"Toggle fullscreen for the 3D scene.",parameters:[{name:"enabled",type:"boolean",required:!0,description:"true = enter, false = exit."}],handler:async({enabled:e})=>{const t=document.querySelector(".scene-canvas");return t?e&&!document.fullscreenElement?(await t.requestFullscreen?.(),"Entered fullscreen."):!e&&document.fullscreenElement?(await document.exitFullscreen?.(),"Exited fullscreen."):e?"Already in fullscreen.":"Not in fullscreen.":"Could not find the scene element."}}),D({name:"switchView",description:"Switch between 2D top-down and 3D perspective view.",parameters:[{name:"view",type:"string",required:!0,enum:["2D","3D"],description:'"2D" or "3D".'}],handler:async({view:e})=>{const t=e==="3D";return q.getState().is3D===t?`Already in ${e} view.`:(v.getState().setCameraPosition(t?[4,4,6]:[0,10,.1]),q.getState().toggleView(),`Switched to ${e} view.`)}}),D({name:"resetCamera",description:"Reset the camera to the default 3D view.",parameters:[],handler:async()=>(v.getState().setCameraPosition([4,4,6]),q.getState().is3D||q.getState().toggleView(),"Camera reset.")}),D({name:"toggleDimensions",available:S?"enabled":"disabled",description:S?"Show or hide the dimension overlay.":"This product has no dimension overlay to show or hide.",parameters:[{name:"show",type:"boolean",required:!0,description:"true = show, false = hide."}],handler:async({show:e})=>S?q.getState().showDimensions===e?e?"Dimensions already visible.":"Dimensions already hidden.":(q.getState().toggleDimensions(),e?"Dimensions shown.":"Dimensions hidden."):"This product has no dimension overlay."}),D({name:"toggleWalls",available:b?"enabled":"disabled",description:b?"Show or hide the room walls in the scene.":"This product has no room walls to show or hide.",parameters:[{name:"show",type:"boolean",required:!0,description:"true = show walls, false = hide walls."}],handler:async({show:e})=>b?q.getState().showWalls===e?e?"Walls already visible.":"Walls already hidden.":(q.getState().toggleWalls(),e?"Walls shown.":"Walls hidden."):"This product has no walls to toggle."})}export{le as default};
60
+ approximate (per-piece finishes especially), so do not skip the action based on them.`})}catch{}const g=ne(e=>e.sceneSelections),A=v(e=>e.activeSceneConfigId),f=$(e=>e.features),h=$(e=>e.options),C=v(e=>e.productInstances),P=v(e=>e.selectedInstanceId),M=G(e=>e.sceneConfigurations),j=G(e=>e.getSceneFeatures),E=N(e=>e.hostMaterialOverrides),V=ee(oe,_,_),F=$(e=>e.systemUiToggles)||{},b=F.walls!==!1,S=F.dimensions!==!1,L=A?j(A)||[]:[],y=B(()=>L.map(e=>{const t=e.feature_id||e.id,d=f[t]||f[String(t)];let i=(d?.options||[]).map(n=>{const o=typeof n=="string"||typeof n=="number"?n:n?.id,u=h[o]||h[String(o)];return u?{id:u.id,name:u.name}:null}).filter(Boolean);i.length===0&&(i=Object.values(h).filter(n=>n?.optionSetId==t||n?.option_set_id==t||n?.optionSet==t||n?.feature_id==t).sort((n,o)=>(n?.sequence||0)-(o?.sequence||0)).map(n=>({id:n.id,name:n.name})));const c=g[e.id]??g[String(e.id)]??g[t]??g[String(t)]??null,m=c!=null?i.find(n=>String(n.id)===String(c))?.name??null:null;return{sceneFeatureId:e.id,featureId:t,name:e.name||d?.name||t,current:m,currentSelection:c,options:i}}),[L,f,h,g]);U({description:"Scene-wide features and their options for the current product (from the live catalog \u2014 any configurator). Use featureKey when calling selectOption.",value:y});const x=B(()=>{const e=C||{},t=$.getState().products||{},d=n=>{const o=t[n?.variantId]||t[n?.productId]||t[String(n?.variantId)]||t[String(n?.productId)];return String(o?.name||n?.name||"")},i=Object.entries(e).map(([n,o])=>{const u=(Y(n)||[]).map(r=>(f[r.optionSetId]||f[String(r.optionSetId)]||{}).name).filter(Boolean);return{id:n,name:d(o),selected:String(n)===String(P),features:u}});let c=null;if(P!=null){const n=Y(P)||[],o=ae(P)||{},u=E?.[P]||{};c=n.map(r=>{const a=f[r.optionSetId]||f[String(r.optionSetId)],I=a?.name||String(r.optionSetId),l=(r.available||[]).map(w=>h[w]||h[String(w)]).filter(Boolean),k=/finish/i.test(String(a?.type||""))||/finish|colou?r|material/i.test(I);let p=null;if(k){const w=new Set(Object.values(u).map(String));if(p=l.find(W=>W.value!=null&&w.has(String(W.value)))?.name??null,p==null){const W=y.find(Z=>String(Z.featureId)===String(r.optionSetId)),z=W?g[W.sceneFeatureId]:null;p=z!=null?(h[z]||h[String(z)])?.name??null:null}}else{const w=o[r.optionSetId]??o[String(r.optionSetId)];p=w!=null?(h[w]||h[String(w)])?.name??null:null}return{feature:I,current:p,options:l.map(w=>w.name)}})}const m=i.find(n=>n.selected)?.name||null;return{pieces:i,selectedPiece:m,selectedFeatures:c,note:P==null?'NOTHING is selected. For a "change/delete the selected piece" request, first call selectPiece(description) to select the piece the user means, or reply that no piece is currently selected. Do NOT claim any current value or that something is "already set".':`"${m}" is selected; its changeable features are in selectedFeatures.`}},[C,P,f,h,g,y,E,V]);U({description:"Pieces in the scene (each with its feature names), which is selected, and the selected piece's current values + options. To change a feature of a piece that isn't selected (e.g. a hosted product's option), find the piece in pieces[] whose features include it and selectPiece it \u2014 or just call updatePieceFeature(featureKey, optionKey); it auto-targets the piece that has that feature when only one does.",value:x});const O=B(()=>{const e=new Set((L||[]).filter(t=>ie(t,{productSelected:!1})).map(t=>String(t.feature_id||t.id)));return y.filter(t=>e.has(String(t.featureId))).filter(t=>Array.isArray(t.options)&&t.options.length>0)},[L,y]),s=O.length>0,T=O.map(e=>`${e.name}: ${e.options.map(t=>t.name).join(", ")}`).join("; "),R=O.map(e=>e.name);U({description:"Kinds of pieces that can be ADDED for this product, with their options. Use these exact names as pieceType when calling addPiece.",value:O.map(e=>({pieceType:e.name,options:e.options.map(t=>t.name)}))});const X=y.map(e=>`${e.name} (e.g. ${e.options.slice(0,3).map(t=>t.name).join(", ")})`).join(", "),Q=y.slice(0,4).map(e=>`"${e.name}"`).join(", "),J=y.flatMap(e=>e.options.slice(0,1)).slice(0,4).map(e=>`"${e.name}"`).join(", ");D({name:"selectOption",description:`Change a scene-wide feature option (finish, layout, door style, handle, \u2026). Features: ${X}.`,parameters:[{name:"featureKey",type:"string",description:`The feature name or id. Examples: ${Q}.`,required:!0},{name:"optionKey",type:"string",description:`The option name or id. Examples: ${J}.`,required:!0}],handler:async({featureKey:e,optionKey:t})=>{const d=String(e).toLowerCase(),i=y.find(a=>String(a.sceneFeatureId)===String(e)||String(a.featureId)===String(e)||String(a.sceneFeatureId).toLowerCase()===d||String(a.featureId).toLowerCase()===d||String(a.name).toLowerCase()===d||String(a.name).toLowerCase().includes(d)||d.includes(String(a.name).toLowerCase()));if(!i)return`Feature "${e}" not found. Available: ${y.map(a=>a.name).join(", ")}`;const c=String(t).toLowerCase(),m=i.options.find(a=>String(a.id)===String(t)||String(a.id).toLowerCase()===c||String(a.name).toLowerCase()===c||String(a.name).toLowerCase().includes(c)||c.includes(String(a.name).toLowerCase()));if(!m)return`Option "${t}" not found for ${i.name}. Available: ${i.options.map(a=>a.name).join(", ")}`;const n=f[i.featureId]||f[String(i.featureId)]||{id:i.featureId},o=H();let u=!1;try{u=await se(i.featureId,m.id,n),await q(2)}catch(a){return`Could not change ${i.name}: ${a?.message||a}`}const r=H();if(r&&r!==o&&r.rejected){const a=r.errors?.[0]?.message||r.code||"the engine refused it";return`${i.name} could not be changed to ${m.name}: ${a}`}return u===!1?`${i.name} could not be changed to ${m.name}.`:`${i.name} changed to ${m.name}.`}}),D({name:"addPiece",available:s?"enabled":"disabled",description:s?`Add a new piece to the scene. Choose a pieceType and an option (free pieces / corners / hosted products are pieceTypes here too). Available \u2014 ${T}.`:K,parameters:[{name:"pieceType",type:"string",required:!1,description:`Which kind of piece. Valid: ${R.join(", ")||"(none)"}. Optional when there's only one.`,...R.length?{enum:R}:{}},{name:"option",type:"string",required:!0,description:"The option to add \u2014 name or id."},{name:"size",type:"string",required:!1,description:'Optional size/width, e.g. "18" or "30x18". Applied after adding if the piece has a size option.'}],handler:async({pieceType:e,option:t,size:d})=>{if(!s)return K;let i=null;if(e!=null&&String(e).trim()!==""){const l=String(e).trim().toLowerCase();i=O.find(k=>String(k.name).toLowerCase()===l||String(k.featureId).toLowerCase()===l||String(k.name).toLowerCase().includes(l)||l.includes(String(k.name).toLowerCase()))}if(!i&&O.length===1&&(i=O[0]),!i)return`Which piece type? Choose one of: ${R.join(", ")}.`;const c=String(t).trim().toLowerCase(),m=i.options.find(l=>String(l.id)===String(t)||String(l.name).toLowerCase()===c||String(l.name).toLowerCase().includes(c)||c.includes(String(l.name).toLowerCase()));if(!m)return`Option "${t}" not found for ${i.name}. Available: ${i.options.map(l=>l.name).join(", ")}.`;let n,o;const u=new Set(Object.keys(v.getState().productInstances||{}));try{n=await import("./a77b15c0d6.js"),o=await n.addProductFromOption({optionSetId:i.featureId,optionId:m.id})}catch(l){return`Couldn't add ${m.name}: ${l?.message||"the engine is unavailable"}.`}await q(2);let r=o?.addedPlacements?.[0]?.id??null;r==null&&(r=Object.keys(v.getState().productInstances||{}).find(l=>!u.has(l))??null);const a=`Added ${m.name} (${i.name}) to the scene.`;if(d==null||String(d).trim()===""||r==null)return a;const I=await le(r,d);return I.ok?`Added ${m.name} (${i.name}) and set ${I.featureName} to ${I.matchedName}.`:I.reason==="no-match"?`${a} Couldn't match size "${d}" \u2014 available: ${(I.available||[]).join(", ")||"(none)"}.`:a}}),D({name:"selectPiece",description:'Select a piece in the scene so it can be changed or deleted. Match by product name / description (e.g. "left chaise", "the elevated piece", "the hosted product").',parameters:[{name:"description",type:"string",required:!0,description:"The piece's product name or a description of it."}],handler:async({description:e})=>{const t=v.getState().productInstances||{},d=$.getState().products||{},i=Object.entries(t).map(([o,u])=>{const r=d[u?.variantId]||d[u?.productId]||d[String(u?.variantId)]||d[String(u?.productId)];return{id:o,name:String(r?.name||u?.name||o)}});if(!i.length)return"There are no pieces in the scene to select.";const c=String(e).toLowerCase().trim(),m=c.split(/\s+/).filter(o=>o.length>2),n=i.find(o=>o.name.toLowerCase()===c)||i.find(o=>o.name.toLowerCase().includes(c))||i.find(o=>c.includes(o.name.toLowerCase()))||i.find(o=>m.some(u=>o.name.toLowerCase().includes(u)));if(!n)return`Couldn't find a piece matching "${e}". In the scene: ${i.map(o=>o.name).join(", ")}.`;try{v.getState().selectInstance?.(n.id)}catch{}return await q(2),`Selected ${n.name}. You can now change or delete it.`}}),D({name:"updatePieceFeature",description:"Change a feature (width, door, handle, finish, size, \u2026) on the CURRENTLY SELECTED piece. Select one first with selectPiece. See sceneInventory for the selected piece's features and options.",parameters:[{name:"featureKey",type:"string",required:!0,description:"The feature name (or id) to change \u2014 from the selected piece's features."},{name:"optionKey",type:"string",required:!0,description:"The option name (or id) to select."}],handler:async({featureKey:e,optionKey:t})=>{let d=v.getState().selectedInstanceId;if(d==null){const c=await import("./a77b15c0d6.js"),m=v.getState().productInstances||{},n=$.getState().products||{},o=$.getState().features||{},u=String(e).toLowerCase(),r=Object.keys(m).filter(a=>(c.getPlacementBindings(a)||[]).some(I=>{const l=String((o[I.optionSetId]||o[String(I.optionSetId)]||{}).name||"").toLowerCase();return l&&(l===u||l.includes(u)||u.includes(l))}));if(r.length===1)d=r[0];else if(r.length>1){const a=r.map(I=>{const l=m[I];return(n[l?.variantId]||n[l?.productId])?.name||I});return`Several pieces have a "${e}" option (${a.join(", ")}). Say which one (e.g. by its name), then I'll change it.`}}const i=await ce({instanceId:d,featureKey:e,optionKey:t});return await q(2),i.msg}}),D({name:"deleteSelectedPiece",description:"Delete the currently selected piece from the scene. Select one first with selectPiece if needed.",parameters:[],handler:async()=>{const e=v.getState().selectedInstanceId;if(e==null)return"No piece is selected. Select one first (selectPiece).";try{await(await import("./a77b15c0d6.js")).removeProduct(e)}catch(t){return`Couldn't delete the selected piece: ${t?.message||"the engine is unavailable"}.`}try{v.getState().removeProductInstance?.(e)}catch{}try{v.getState().selectInstance?.(null)}catch{}return await q(2),"Deleted the selected piece."}}),D({name:"movePiece",description:"Move/reorder the CURRENTLY SELECTED piece one position left or right within its run. Select a piece first with selectPiece if needed. (Pieces snap into a sequenced run, so this reorders rather than free-positions.)",parameters:[{name:"direction",type:"string",required:!0,enum:["left","right"],description:'"left" or "right".'}],handler:async({direction:e})=>{const t=v.getState(),d=t.selectedInstanceId;if(d==null)return"No piece is selected. Select one first (selectPiece), then say which way to move it.";const i=t.productInstances||{},c=i[d];if(!c)return"The selected piece is no longer in the scene.";const m=p=>p?.placementGroup??p?.placement_group??null,n=p=>{const w=Number(p?.sequence);return Number.isFinite(w)?w:null},o=m(c),u=Object.entries(i).filter(([,p])=>m(p)===o&&n(p)!=null).map(([p,w])=>({id:p,seq:n(w)})).sort((p,w)=>p.seq-w.seq),r=u.findIndex(p=>String(p.id)===String(d));if(r<0||u.length<2)return"There is nothing to reorder \u2014 the selected piece has no neighbours in its run.";const a=/right|next|forward|end/i.test(String(e)),I=a?u[r+1]:u[r-1];if(!I)return a?"The piece is already at the right end of its run.":"The piece is already at the left end of its run.";let l=c?.positionedAbove!=null?String(c.positionedAbove):null,k=null;if(l){const p=i[l];k=p?p.variantId??p.productId??null:null}else{const p=$.getState(),w=p.getProduct?.(c?.variantId)||p.getProduct?.(c?.productId);k=re(w,c)}try{await(await import("./a77b15c0d6.js")).moveProduct({placementId:d,sequence:Math.round(I.seq),hostPlacementId:l,hostVariantId:k})}catch(p){return`Couldn't move the piece: ${p?.message||"the engine is unavailable"}.`}return await q(2),`Moved the selected piece one position to the ${a?"right":"left"}.`}}),D({name:"toggleFullscreen",description:"Toggle fullscreen for the 3D scene.",parameters:[{name:"enabled",type:"boolean",required:!0,description:"true = enter, false = exit."}],handler:async({enabled:e})=>{const t=document.querySelector(".scene-canvas");return t?e&&!document.fullscreenElement?(await t.requestFullscreen?.(),"Entered fullscreen."):!e&&document.fullscreenElement?(await document.exitFullscreen?.(),"Exited fullscreen."):e?"Already in fullscreen.":"Not in fullscreen.":"Could not find the scene element."}}),D({name:"switchView",description:"Switch between 2D top-down and 3D perspective view.",parameters:[{name:"view",type:"string",required:!0,enum:["2D","3D"],description:'"2D" or "3D".'}],handler:async({view:e})=>{const t=e==="3D";return N.getState().is3D===t?`Already in ${e} view.`:(v.getState().setCameraPosition(t?[4,4,6]:[0,10,.1]),N.getState().toggleView(),`Switched to ${e} view.`)}}),D({name:"resetCamera",description:"Reset the camera to the default 3D view.",parameters:[],handler:async()=>(v.getState().setCameraPosition([4,4,6]),N.getState().is3D||N.getState().toggleView(),"Camera reset.")}),D({name:"toggleDimensions",available:S?"enabled":"disabled",description:S?"Show or hide the dimension overlay.":"This product has no dimension overlay to show or hide.",parameters:[{name:"show",type:"boolean",required:!0,description:"true = show, false = hide."}],handler:async({show:e})=>S?N.getState().showDimensions===e?e?"Dimensions already visible.":"Dimensions already hidden.":(N.getState().toggleDimensions(),e?"Dimensions shown.":"Dimensions hidden."):"This product has no dimension overlay."}),D({name:"toggleWalls",available:b?"enabled":"disabled",description:b?"Show or hide the room walls in the scene.":"This product has no room walls to show or hide.",parameters:[{name:"show",type:"boolean",required:!0,description:"true = show walls, false = hide walls."}],handler:async({show:e})=>b?N.getState().showWalls===e?e?"Walls already visible.":"Walls already hidden.":(N.getState().toggleWalls(),e?"Walls shown.":"Walls hidden."):"This product has no walls to toggle."})}export{de as default};
@@ -1 +1 @@
1
- import{Fragment as g,jsx as e,jsxs as f}from"react/jsx-runtime";import{memo as T,useEffect as _,useMemo as p,useRef as O,lazy as m,Suspense as w}from"react";import*as A from"three";import{Environment as I}from"@react-three/drei";import{useThree as N}from"@react-three/fiber";import{RectAreaLightUniformsLib as z}from"three/examples/jsm/lights/RectAreaLightUniformsLib.js";import k from"./983cbed22c.js";import{applyEnvironmentToRenderer as P}from"./4e7d0a0d4a.js";import{getApiBaseUrl as U}from"./8ade32d067.js";const F=(()=>{let t=null;const o=()=>t||(t=import("@react-three/postprocessing"));return{EffectComposer:m(()=>o().then(n=>({default:n.EffectComposer}))),Bloom:m(()=>o().then(n=>({default:n.Bloom}))),SSAO:m(()=>o().then(n=>({default:n.SSAO}))),FXAA:m(()=>o().then(n=>({default:n.FXAA}))),N8AO:m(()=>o().then(n=>({default:n.N8AO})))}})(),{EffectComposer:W,Bloom:D,SSAO:X,FXAA:G,N8AO:H}=F,$=m(()=>Promise.all([import("@react-three/postprocessing"),import("postprocessing")]).then(([t,o])=>{const n={ACESFilmic:o.ToneMappingMode.ACES_FILMIC,Reinhard:o.ToneMappingMode.REINHARD,Linear:o.ToneMappingMode.LINEAR,Cineon:o.ToneMappingMode.OPTIMIZED_CINEON,AgX:o.ToneMappingMode.AGX,Neutral:o.ToneMappingMode.NEUTRAL};return{default:({name:d})=>{const i=d?n[d]:void 0;return i===void 0?null:e(t.ToneMapping,{mode:i})}}}));let M=!1;function j(){if(!M){try{z.init()}catch{}M=!0}}function x(t){if(!t||/^([a-z]+:)?\/\//i.test(t)||t.startsWith("data:")||t.startsWith("blob:"))return t;const o=U()||"";return t.startsWith("/")?`${o}${t}`:`${o}/${t}`}function S(t,o){return o?512:typeof t.shadow_map_size=="number"?t.shadow_map_size:2048}function Y({env:t,isMobile:o,is3D:n,reducedQuality:l,captureMode:d}){const{gl:i,invalidate:s}=N();_(()=>{t&&Object.keys(t).length>0&&(P(t,i),s())},[t,i,s]);const c=p(()=>{if(!t)return[];if(Array.isArray(t.lights))return t.lights;const a=[];if(t.ambient_light&&a.push({type:"ambient",...t.ambient_light}),Array.isArray(t.directional_lights))for(const u of t.directional_lights)a.push({type:"directional",...u});return a},[t]);p(()=>c.some(a=>a?.type==="rect_area"),[c])&&j();const h=p(()=>{if(!t?.hdr)return null;const a=t.hdr,u=o?a.url_1k??a.url1k??a.url??null:a.url_2k??a.url2k??a.url??null;return u?{url:x(u),intensity:typeof a.intensity=="number"?a.intensity:1,rotation_deg:typeof a.rotation_deg=="number"?a.rotation_deg:0,as_background:!!a.as_background}:null},[t?.hdr,o]),b=p(()=>[0,A.MathUtils.degToRad(h?.rotation_deg??0),0],[h?.rotation_deg]);if(!t||Object.keys(t).length===0)return null;let y=null;h?.as_background||(y=t.background?.color??"#ffffff");const E=t.background?.color??"#ffffff",R=typeof t.shadows?.bias=="number"?t.shadows.bias:15e-5,B=typeof t.shadows?.radius=="number"?t.shadows.radius:typeof t.ground?.shadow_blur=="number"?t.ground.shadow_blur:null,C=typeof t.shadows?.normal_bias=="number"?t.shadows.normal_bias:null;return f(g,{children:[h&&e(k,{children:e(w,{fallback:e("color",{attach:"background",args:[E]}),children:e(I,{files:h.url,background:h.as_background,environmentIntensity:h.intensity,environmentRotation:b,backgroundRotation:b})})}),y&&e("color",{attach:"background",args:[y]}),c.map((a,u)=>!a||a.enabled===!1?null:e(J,{light:a,is3D:n,reducedQuality:l,globalShadowBias:R,globalShadowRadius:B,globalShadowNormalBias:C},u)),e(q,{ground:t.ground,is3D:n,reducedQuality:l,captureMode:d}),e(Z,{postProcessing:t.post_processing,toneMapping:t.tone_mapping??t.toneMapping,is3D:n,reducedQuality:l,captureMode:d})]})}function q({ground:t,is3D:o,reducedQuality:n,captureMode:l}){if(l||!t||t.enabled!==!0)return null;const d=t.floor_color??t.color??"#ffffff",i=typeof t.size=="number"?t.size:21,s=n?-.05:o?-.005:-.02,c=typeof t.shadow_opacity=="number"?t.shadow_opacity:.5,r=t.shadow_color??"#000000";return f(g,{children:[f("mesh",{rotation:[-Math.PI/2,0,0],position:[0,s,0],renderOrder:n?-1:0,children:[e("circleGeometry",{args:[i,64]}),e("meshBasicMaterial",{color:d,toneMapped:!1,depthWrite:!n,polygonOffset:!0,polygonOffsetFactor:2,polygonOffsetUnits:2})]}),o&&c>0&&f("mesh",{rotation:[-Math.PI/2,0,0],position:[0,s+5e-4,0],receiveShadow:!0,children:[e("circleGeometry",{args:[i,64]}),e("shadowMaterial",{transparent:!0,opacity:c,color:r})]})]})}function Z({postProcessing:t,toneMapping:o,is3D:n,reducedQuality:l,captureMode:d}){if(d||!n||!t)return null;const i=t.bloom,s=t.ssao,c=t.fxaa,r=t.n8ao;return!i&&!s&&!c&&!r?null:e(k,{children:e(w,{fallback:null,children:f(W,{children:[i&&e(D,{intensity:typeof i?.intensity=="number"?i.intensity:.5,luminanceThreshold:typeof i?.threshold=="number"?i.threshold:.9,luminanceSmoothing:typeof i?.smoothing=="number"?i.smoothing:.025,mipmapBlur:!0}),r&&e(H,{aoRadius:typeof r?.radius=="number"?r.radius:l?.3:.5,intensity:typeof r?.intensity=="number"?r.intensity:l?1:1.5,distanceFalloff:typeof r?.falloff=="number"?r.falloff:.5,quality:l?"low":"medium"}),s&&!r&&e(X,{intensity:typeof s?.intensity=="number"?s.intensity:1,radius:typeof s?.radius=="number"?s.radius:.1,samples:l?9:16}),c&&e(G,{}),e($,{name:o})]})})})}function J({light:t,is3D:o,reducedQuality:n,globalShadowBias:l,globalShadowRadius:d,globalShadowNormalBias:i}){const s=O();_(()=>{t.target&&s.current&&s.current.position.set(t.target[0],t.target[1],t.target[2])},[t.target]);const c=r=>r?{"shadow-bias":typeof t.bias=="number"?t.bias:l,"shadow-normalBias":typeof t.normal_bias=="number"?t.normal_bias:i??.1,"shadow-radius":typeof t.radius=="number"?t.radius:d??4,"shadow-mapSize-width":S(t,n),"shadow-mapSize-height":S(t,n),"shadow-camera-far":t.shadow_camera_far??500,"shadow-camera-near":t.shadow_camera_near??.5,"shadow-camera-left":t.shadow_camera_left??-5,"shadow-camera-right":t.shadow_camera_right??5,"shadow-camera-top":t.shadow_camera_top??5,"shadow-camera-bottom":t.shadow_camera_bottom??-5}:{};switch(t.type){case"ambient":return e("ambientLight",{color:t.color,intensity:t.intensity??1});case"directional":{const r=o&&!!t.cast_shadow,h=t.position??[0,5,5];return f(g,{children:[e("directionalLight",{color:t.color,intensity:t.intensity??1,position:h,castShadow:r,...c(r)}),t.target&&e("object3D",{ref:s})]})}case"point":{const r=o&&!!t.cast_shadow;return e("pointLight",{color:t.color,intensity:t.intensity??1,position:t.position??[0,5,0],distance:t.distance??0,decay:t.decay??2,castShadow:r,...c(r)})}case"spot":{const r=o&&!!t.cast_shadow;return f(g,{children:[e("spotLight",{color:t.color,intensity:t.intensity??1,position:t.position??[0,5,0],distance:t.distance??0,angle:A.MathUtils.degToRad(t.angle_deg??30),penumbra:t.penumbra??0,decay:t.decay??2,castShadow:r,...c(r)}),t.target&&e("object3D",{ref:s})]})}case"hemisphere":return e("hemisphereLight",{color:t.sky_color??t.color,groundColor:t.ground_color,intensity:t.intensity??1,position:t.position??[0,5,0]});case"rect_area":return e("rectAreaLight",{color:t.color,intensity:t.intensity??1,width:t.width??1,height:t.height??1,position:t.position??[0,5,0],rotation:t.rotation??[0,0,0]});default:return null}}var nt=T(Y);export{nt as default};
1
+ import{Fragment as g,jsx as e,jsxs as f}from"react/jsx-runtime";import{memo as T,useEffect as _,useMemo as p,useRef as O,lazy as m,Suspense as w}from"react";import*as A from"three";import{Environment as I}from"@react-three/drei";import{useThree as N}from"@react-three/fiber";import{RectAreaLightUniformsLib as P}from"three/examples/jsm/lights/RectAreaLightUniformsLib.js";import k from"./983cbed22c.js";import{applyEnvironmentToRenderer as z}from"./4e7d0a0d4a.js";import{getApiBaseUrl as U}from"./8ade32d067.js";const F=(()=>{let t=null;const o=()=>t||(t=import("@react-three/postprocessing"));return{EffectComposer:m(()=>o().then(n=>({default:n.EffectComposer}))),Bloom:m(()=>o().then(n=>({default:n.Bloom}))),SSAO:m(()=>o().then(n=>({default:n.SSAO}))),FXAA:m(()=>o().then(n=>({default:n.FXAA}))),N8AO:m(()=>o().then(n=>({default:n.N8AO})))}})(),{EffectComposer:W,Bloom:D,SSAO:X,FXAA:G,N8AO:H}=F,$=m(()=>Promise.all([import("@react-three/postprocessing"),import("postprocessing")]).then(([t,o])=>{const n={ACESFilmic:o.ToneMappingMode.ACES_FILMIC,Reinhard:o.ToneMappingMode.REINHARD,Linear:o.ToneMappingMode.LINEAR,Cineon:o.ToneMappingMode.OPTIMIZED_CINEON,AgX:o.ToneMappingMode.AGX,Neutral:o.ToneMappingMode.NEUTRAL};return{default:({name:d})=>{const i=d?n[d]:void 0;return i===void 0?null:e(t.ToneMapping,{mode:i})}}}));let M=!1;function j(){if(!M){try{P.init()}catch{}M=!0}}function x(t){if(!t||/^([a-z]+:)?\/\//i.test(t)||t.startsWith("data:")||t.startsWith("blob:"))return t;const o=U()||"";return t.startsWith("/")?`${o}${t}`:`${o}/${t}`}function S(t,o){return o?512:typeof t.shadow_map_size=="number"?t.shadow_map_size:2048}function Y({env:t,isMobile:o,is3D:n,reducedQuality:l,captureMode:d}){const{gl:i,invalidate:s}=N();_(()=>{t&&Object.keys(t).length>0&&(z(t,i),s())},[t,i,s]);const c=p(()=>{if(!t)return[];if(Array.isArray(t.lights))return t.lights;const a=[];if(t.ambient_light&&a.push({type:"ambient",...t.ambient_light}),Array.isArray(t.directional_lights))for(const u of t.directional_lights)a.push({type:"directional",...u});return a},[t]);p(()=>c.some(a=>a?.type==="rect_area"),[c])&&j();const h=p(()=>{if(!t?.hdr)return null;const a=t.hdr,u=o?a.url_1k??a.url1k??a.url??null:a.url_2k??a.url2k??a.url??null;return u?{url:x(u),intensity:typeof a.intensity=="number"?a.intensity:1,rotation_deg:typeof a.rotation_deg=="number"?a.rotation_deg:0,as_background:!!a.as_background}:null},[t?.hdr,o]),b=p(()=>[0,A.MathUtils.degToRad(h?.rotation_deg??0),0],[h?.rotation_deg]);if(!t||Object.keys(t).length===0)return null;let y=null;h?.as_background||(y=t.background?.color??"#ffffff");const E=t.background?.color??"#ffffff",R=typeof t.shadows?.bias=="number"?t.shadows.bias:15e-5,B=typeof t.shadows?.radius=="number"?t.shadows.radius:typeof t.ground?.shadow_blur=="number"?t.ground.shadow_blur:null,C=typeof t.shadows?.normal_bias=="number"?t.shadows.normal_bias:null;return f(g,{children:[h&&e(k,{children:e(w,{fallback:h?.as_background?e("color",{attach:"background",args:[E]}):null,children:e(I,{files:h.url,background:h.as_background,environmentIntensity:h.intensity,environmentRotation:b,backgroundRotation:b})})}),y&&e("color",{attach:"background",args:[y]}),c.map((a,u)=>!a||a.enabled===!1?null:e(J,{light:a,is3D:n,reducedQuality:l,globalShadowBias:R,globalShadowRadius:B,globalShadowNormalBias:C},u)),e(q,{ground:t.ground,is3D:n,reducedQuality:l,captureMode:d}),e(Z,{postProcessing:t.post_processing,toneMapping:t.tone_mapping??t.toneMapping,is3D:n,reducedQuality:l,captureMode:d})]})}function q({ground:t,is3D:o,reducedQuality:n,captureMode:l}){if(l||!t||t.enabled!==!0)return null;const d=t.floor_color??t.color??"#ffffff",i=typeof t.size=="number"?t.size:21,s=n?-.05:o?-.005:-.02,c=typeof t.shadow_opacity=="number"?t.shadow_opacity:.5,r=t.shadow_color??"#000000";return f(g,{children:[f("mesh",{rotation:[-Math.PI/2,0,0],position:[0,s,0],renderOrder:n?-1:0,children:[e("circleGeometry",{args:[i,64]}),e("meshBasicMaterial",{color:d,toneMapped:!1,depthWrite:!n,polygonOffset:!0,polygonOffsetFactor:2,polygonOffsetUnits:2})]}),o&&c>0&&f("mesh",{rotation:[-Math.PI/2,0,0],position:[0,s+5e-4,0],receiveShadow:!0,children:[e("circleGeometry",{args:[i,64]}),e("shadowMaterial",{transparent:!0,opacity:c,color:r})]})]})}function Z({postProcessing:t,toneMapping:o,is3D:n,reducedQuality:l,captureMode:d}){if(d||!n||!t)return null;const i=t.bloom,s=t.ssao,c=t.fxaa,r=t.n8ao;return!i&&!s&&!c&&!r?null:e(k,{children:e(w,{fallback:null,children:f(W,{enableNormalPass:!!(s&&!r),children:[i&&e(D,{intensity:typeof i?.intensity=="number"?i.intensity:.5,luminanceThreshold:typeof i?.threshold=="number"?i.threshold:.9,luminanceSmoothing:typeof i?.smoothing=="number"?i.smoothing:.025,mipmapBlur:!0}),r&&e(H,{aoRadius:typeof r?.radius=="number"?r.radius:l?.3:.5,intensity:typeof r?.intensity=="number"?r.intensity:l?1:1.5,distanceFalloff:typeof r?.falloff=="number"?r.falloff:.5,quality:l?"low":"medium"}),s&&!r&&e(X,{intensity:typeof s?.intensity=="number"?s.intensity:1,radius:typeof s?.radius=="number"?s.radius:.1,samples:l?9:16}),c&&e(G,{}),e($,{name:o})]})})})}function J({light:t,is3D:o,reducedQuality:n,globalShadowBias:l,globalShadowRadius:d,globalShadowNormalBias:i}){const s=O();_(()=>{t.target&&s.current&&s.current.position.set(t.target[0],t.target[1],t.target[2])},[t.target]);const c=r=>r?{"shadow-bias":typeof t.bias=="number"?t.bias:l,"shadow-normalBias":typeof t.normal_bias=="number"?t.normal_bias:i??.1,"shadow-radius":typeof t.radius=="number"?t.radius:d??4,"shadow-mapSize-width":S(t,n),"shadow-mapSize-height":S(t,n),"shadow-camera-far":t.shadow_camera_far??500,"shadow-camera-near":t.shadow_camera_near??.5,"shadow-camera-left":t.shadow_camera_left??-5,"shadow-camera-right":t.shadow_camera_right??5,"shadow-camera-top":t.shadow_camera_top??5,"shadow-camera-bottom":t.shadow_camera_bottom??-5}:{};switch(t.type){case"ambient":return e("ambientLight",{color:t.color,intensity:t.intensity??1});case"directional":{const r=o&&!!t.cast_shadow,h=t.position??[0,5,5];return f(g,{children:[e("directionalLight",{color:t.color,intensity:t.intensity??1,position:h,castShadow:r,...c(r)}),t.target&&e("object3D",{ref:s})]})}case"point":{const r=o&&!!t.cast_shadow;return e("pointLight",{color:t.color,intensity:t.intensity??1,position:t.position??[0,5,0],distance:t.distance??0,decay:t.decay??2,castShadow:r,...c(r)})}case"spot":{const r=o&&!!t.cast_shadow;return f(g,{children:[e("spotLight",{color:t.color,intensity:t.intensity??1,position:t.position??[0,5,0],distance:t.distance??0,angle:A.MathUtils.degToRad(t.angle_deg??30),penumbra:t.penumbra??0,decay:t.decay??2,castShadow:r,...c(r)}),t.target&&e("object3D",{ref:s})]})}case"hemisphere":return e("hemisphereLight",{color:t.sky_color??t.color,groundColor:t.ground_color,intensity:t.intensity??1,position:t.position??[0,5,0]});case"rect_area":return e("rectAreaLight",{color:t.color,intensity:t.intensity??1,width:t.width??1,height:t.height??1,position:t.position??[0,5,0],rotation:t.rotation??[0,0,0]});default:return null}}var nt=T(Y);export{nt as default};
@@ -1 +1 @@
1
- import y from"./872c4302e0.js";import F from"./9c6c598569.js";import L from"./d94df858ea.js";import V from"./8f60e5059a.js";import j from"./be337ddda5.js";import{applyFinishClick as X,normalizeMaterialTargets as z}from"./dc2a1a0e13.js";import{executeLayoutChange as Z}from"./9526094bb7.js";import{clearSceneLoadingAfterRender as $}from"./2774152dd2.js";import"./9326c23506.js";import"./061b81ad81.js";import{isOptionAvailable as U,isOptionVisible as ee}from"./817d930a49.js";import{runIntent as x,INTENTS as H}from"./6d238282c1.js";import{emitEvent as k,EVENTS as D}from"./2e366d7386.js";import{isAddFeature as te}from"./8c27edda0f.js";import{armHostedProduct as ne}from"./ab6c80484f.js";function oe(e,t,s){const o=y.getState(),{options:a,features:i,materials:c}=o,r=F.getState(),h=(r.selectedInstanceId??null)!=null,S=V.getState(),{hostStyles:d,hostHandleTypes:E,freePieceTier:N,setFreePieceTier:A,setSceneLoading:P,showInfo:G,clearSelectedFeature:W,clearPendingHostedProduct:Y}=S,I=r.activeSceneConfigId,b=L.getState().setSceneSelection,O=j.getState(),_=I?O.getSceneFeatures?.(I)||[]:[],m={layoutFeature:_.find(l=>l.type==="layout_change"),finishFeatures:_.filter(l=>l.type==="finish_change"),productFeatures:_.filter(l=>l.type==="load_new_product"),appliancesFeature:_.find(l=>l.type==="appliance_selection")};if(!e||!t)return!1;const T=i||{},g=e.id??e.feature_id??Object.keys(T).find(l=>T[l]===e);return g==null?!1:(import("./a77b15c0d6.js").then(({selectOptionForScene:l})=>l({optionSetId:g,optionId:s})).catch(()=>{}),!0)}function M(e,t,s=null,o=null){const a=y.getState(),i=s??a.features?.[e]??a.features?.[String(e)]??null;let c=o??a.options?.[t]??a.options?.[String(t)]??null;return!c&&Array.isArray(i?.options)&&(c=i.options.find(r=>r&&typeof r=="object"&&String(r.id)===String(t))??null),{optionSetName:i?.name??null,optionName:c?.name??c?.label??null}}function Oe(e,t,s){return x({type:H.OPTION_SELECT,optionSetId:e,optionId:t,optionSetType:s?.type??null,featureId:e,featureType:s?.type??null},()=>{const o=se(e,t,s);return k(D.OPTION_SELECTED,{optionSetId:e,optionId:t,featureType:s?.type??null,...M(e,t,s)}),o})}function se(e,t,s){const o=s?.type;if(o==="appliance_selection"){const n=y.getState(),u=n.options||{},v=u[t]||u[String(t)]||null,f=v?.value??v?.valueText??t,Q=n.getProduct?.(f)||n.products?.[f]||{id:f};return ne(Q)}if(o==="product_change"||o==="load_new_component"||o==="load_new_product"){const n=y.getState().options||{},u=n[t]||n[String(t)]||{id:t};return R(s,u)}const a=y.getState(),{options:i,features:c,materials:r}=a,p=F.getState(),h=p.selectedInstanceId??null,S=h!=null,d=V.getState(),{hostStyles:E,hostHandleTypes:N,freePieceTier:A,setFreePieceTier:P,setSceneLoading:G,showInfo:W,clearSelectedFeature:Y,clearPendingHostedProduct:I}=d,b=p.activeSceneConfigId,O=L.getState().setSceneSelection,_=j.getState(),m=b?_.getSceneFeatures?.(b)||[]:[],T={layoutFeature:m.find(n=>n.type==="layout_change"),finishFeatures:m.filter(n=>n.type==="finish_change"),productFeatures:m.filter(n=>n.type==="load_new_product"),appliancesFeature:m.find(n=>n.type==="appliance_selection")},g=i[t];if(g&&!ee(e,t)||g&&!U(e,t))return;const l=c?.[e]||c?.[String(e)]||s||{},C={...s||{},...l},B=z(g?.materialSlots??g?.material_slots),J=z(C?.material_targets??C?.materialTargets??C?.materials);if(B.length>0||J.length>0)return X({option:g,feature:C,scope:S?"single":"all",pieceIndex:S?h:null}),!0;let w="Updating...";const q=T.layoutFeature?.id===e,K=T.productFeatures?.some(n=>n.id===e);if(q)w="Changing layout...";else if(K){w=i[t]?.value===null?"Removing island...":"Adding island...";const u=i[t]?.tier??i[t]?.islandTier??null;(u==="single"||u==="double")&&P(u)}if(G(!0,w),q){const n=x({type:H.LAYOUT_CHANGE,optionSetId:e,optionId:t,featureId:e},()=>(requestAnimationFrame(()=>{Z(t,m),O(e,t),import("./a77b15c0d6.js").then(({applyLayoutPreset:u,refreshCanonicalState:v})=>setTimeout(()=>{const f=F.getState().activeSceneConfigId;f!=null?u(f):v()},400)).catch(()=>{})}),!0));return n!==!0&&G(!1),n===!0}return O(e,t),$(),!0}function Ce(e,t){return x({type:H.OPTION_SELECT,optionSetId:e?.id??e?.feature_id??null,optionId:t?.id??null,optionSetType:e?.type??null,featureId:e?.id??e?.feature_id??null,featureType:e?.type??null},()=>{const s=R(e,t);return k(D.OPTION_SELECTED,{optionSetId:e?.id??e?.feature_id??null,optionId:t?.id??null,featureType:e?.type??null,...M(e?.id??e?.feature_id,t?.id,e,t)}),s})}function R(e,t){const o=F.getState().selectedInstanceId??null,a=o!=null,i=L.getState().setSceneSelection;if(U(e?.id,t?.id))if(te(e,{productSelected:a}))i(e.id,t.id);else if(e.type==="load_new_product"&&a&&o!=null&&!String(o).endsWith("__host")){const c=y.getState(),r=t.value??t.valueText??t.value_text,p=r!=null?c.getProduct?.(r)||c.products?.[r]||c.products?.[String(r)]:null,h=p?.id??r,S=p?.productGraph??p?.product_graph??null,d=F.getState().productInstances?.[o]||null,E=d?.placementGroup??p?.placementGroup??p?.placement_group??null,N=d&&Number.isFinite(Number(d.sequence))?Number(d.sequence):void 0,A=Array.isArray(d?.position)?d.position:void 0;import("./a77b15c0d6.js").then(({addProduct:P})=>P({productGraphId:S,variantId:h,placementGroup:E,sequence:N,position:A,replace:!0,replacePlacementId:o})).catch(()=>{})}else a&&o!=null&&!String(o).endsWith("__host")?import("./a77b15c0d6.js").then(({selectOptionForProduct:c})=>c({placementId:o,optionSetId:t.optionSetId??t.option_set_id??e.feature_id??e.id,optionId:t.id})).catch(()=>{}):(oe(e,t,t.id),i(e.id,t.id))}export{oe as applyGlobalSwapViaGroup,Oe as selectOption,Ce as selectProductOption};
1
+ import m from"./872c4302e0.js";import v from"./9c6c598569.js";import x from"./d94df858ea.js";import q from"./8f60e5059a.js";import j from"./be337ddda5.js";import{applyFinishClick as X,normalizeMaterialTargets as z}from"./dc2a1a0e13.js";import{executeLayoutChange as Z}from"./9526094bb7.js";import{clearSceneLoadingAfterRender as ee}from"./2774152dd2.js";import"./9326c23506.js";import"./061b81ad81.js";import{isOptionAvailable as U,isOptionVisible as te}from"./817d930a49.js";import{runIntent as L,INTENTS as H}from"./6d238282c1.js";import{emitEvent as W,EVENTS as k}from"./2e366d7386.js";import{isAddFeature as ne}from"./8c27edda0f.js";import{getPlacementBinding as oe}from"./817d930a49.js";function D(e,t){if(e==null||t==null)return!1;try{return!!oe(e,t)}catch{return!1}}import{armHostedProduct as se}from"./ab6c80484f.js";function ce(e,t,s){const o=m.getState(),{options:p,features:i,materials:a}=o,c=v.getState(),u=(c.selectedInstanceId??null)!=null,g=q.getState(),{hostStyles:f,hostHandleTypes:_,freePieceTier:w,setFreePieceTier:N,setSceneLoading:O,showInfo:F,clearSelectedFeature:B,clearPendingHostedProduct:Y}=g,A=c.activeSceneConfigId,G=x.getState().setSceneSelection,C=j.getState(),h=A?C.getSceneFeatures?.(A)||[]:[],y={layoutFeature:h.find(l=>l.type==="layout_change"),finishFeatures:h.filter(l=>l.type==="finish_change"),productFeatures:h.filter(l=>l.type==="load_new_product"),appliancesFeature:h.find(l=>l.type==="appliance_selection")};if(!e||!t)return!1;const P=i||{},S=e.id??e.feature_id??Object.keys(P).find(l=>P[l]===e);return S==null?!1:(import("./a77b15c0d6.js").then(({selectOptionForScene:l})=>l({optionSetId:S,optionId:s})).catch(()=>{}),!0)}function M(e,t,s=null,o=null){const p=m.getState(),i=s??p.features?.[e]??p.features?.[String(e)]??null;let a=o??p.options?.[t]??p.options?.[String(t)]??null;return!a&&Array.isArray(i?.options)&&(a=i.options.find(c=>c&&typeof c=="object"&&String(c.id)===String(t))??null),{optionSetName:i?.name??null,optionName:a?.name??a?.label??null}}function Ee(e,t,s){return L({type:H.OPTION_SELECT,optionSetId:e,optionId:t,optionSetType:s?.type??null,featureId:e,featureType:s?.type??null},()=>{const o=ie(e,t,s);return W(k.OPTION_SELECTED,{optionSetId:e,optionId:t,featureType:s?.type??null,...M(e,t,s)}),o})}function ie(e,t,s){const o=s?.type;if(o==="appliance_selection"){const n=m.getState(),d=n.options||{},I=d[t]||d[String(t)]||null,T=I?.value??I?.valueText??t,Q=n.getProduct?.(T)||n.products?.[T]||{id:T};return se(Q)}if(o==="product_change"||o==="load_new_component"||o==="load_new_product"){const n=m.getState().options||{},d=n[t]||n[String(t)]||{id:t};return R(s,d)}const p=m.getState(),{options:i,features:a,materials:c}=p,r=v.getState(),u=r.selectedInstanceId??null,g=u!=null,f=q.getState(),{hostStyles:_,hostHandleTypes:w,freePieceTier:N,setFreePieceTier:O,setSceneLoading:F,showInfo:B,clearSelectedFeature:Y,clearPendingHostedProduct:A}=f,G=r.activeSceneConfigId,C=x.getState().setSceneSelection,h=j.getState(),y=G?h.getSceneFeatures?.(G)||[]:[],P={layoutFeature:y.find(n=>n.type==="layout_change"),finishFeatures:y.filter(n=>n.type==="finish_change"),productFeatures:y.filter(n=>n.type==="load_new_product"),appliancesFeature:y.find(n=>n.type==="appliance_selection")},S=i[t];if(S&&!te(e,t)||S&&!U(e,t))return;const l=a?.[e]||a?.[String(e)]||s||{},E={...s||{},...l},$=z(S?.materialSlots??S?.material_slots),J=z(E?.material_targets??E?.materialTargets??E?.materials);if($.length>0||J.length>0){const n=g&&D(u,e);return X({option:S,feature:E,scope:n?"single":"all",pieceIndex:n?u:null}),!0}let b="Updating...";const V=P.layoutFeature?.id===e,K=P.productFeatures?.some(n=>n.id===e);if(V)b="Changing layout...";else if(K){b=i[t]?.value===null?"Removing island...":"Adding island...";const d=i[t]?.tier??i[t]?.islandTier??null;(d==="single"||d==="double")&&O(d)}if(F(!0,b),V){const n=L({type:H.LAYOUT_CHANGE,optionSetId:e,optionId:t,featureId:e},()=>(requestAnimationFrame(()=>{Z(t,y),C(e,t),import("./a77b15c0d6.js").then(({applyLayoutPreset:d,refreshCanonicalState:I})=>setTimeout(()=>{const T=v.getState().activeSceneConfigId;T!=null?d(T):I()},400)).catch(()=>{})}),!0));return n!==!0&&F(!1),n===!0}return C(e,t),ee(),!0}function Ie(e,t){return L({type:H.OPTION_SELECT,optionSetId:e?.id??e?.feature_id??null,optionId:t?.id??null,optionSetType:e?.type??null,featureId:e?.id??e?.feature_id??null,featureType:e?.type??null},()=>{const s=R(e,t);return W(k.OPTION_SELECTED,{optionSetId:e?.id??e?.feature_id??null,optionId:t?.id??null,featureType:e?.type??null,...M(e?.id??e?.feature_id,t?.id,e,t)}),s})}function R(e,t){const o=v.getState().selectedInstanceId??null,p=t?.optionSetId??t?.option_set_id??e?.feature_id??e?.id,i=o!=null&&D(o,p),a=x.getState().setSceneSelection;if(i&&String(o).endsWith("__host")&&(e?.type==="load_new_product"||e?.type==="product_change")){const c=m.getState(),r=t?.value??t?.valueText??t?.value_text??t?.valueProductVariantId??t?.value_product_variant_id??null,g=(r!=null?c.getProduct?.(r)||c.products?.[r]||c.products?.[String(r)]:null)?.id??r;return g==null?!1:(import("./a77b15c0d6.js").then(({changeHostVariantForProduct:f})=>f({placementId:String(o).replace(/__host$/,""),variantId:g})).catch(()=>{}),!0)}if(U(e?.id,t?.id))if(ne(e,{productSelected:i}))a(e.id,t.id);else if(e.type==="load_new_product"&&i&&o!=null&&!String(o).endsWith("__host")){const c=m.getState(),r=t.value??t.valueText??t.value_text,u=r!=null?c.getProduct?.(r)||c.products?.[r]||c.products?.[String(r)]:null,g=u?.id??r,f=u?.productGraph??u?.product_graph??null,_=v.getState().productInstances?.[o]||null,w=_?.placementGroup??u?.placementGroup??u?.placement_group??null,N=_&&Number.isFinite(Number(_.sequence))?Number(_.sequence):void 0,O=Array.isArray(_?.position)?_.position:void 0;import("./a77b15c0d6.js").then(({addProduct:F})=>F({productGraphId:f,variantId:g,placementGroup:w,sequence:N,position:O,replace:!0,replacePlacementId:o})).catch(()=>{})}else i&&o!=null&&!String(o).endsWith("__host")?import("./a77b15c0d6.js").then(({selectOptionForProduct:c})=>c({placementId:o,optionSetId:t.optionSetId??t.option_set_id??e.feature_id??e.id,optionId:t.id})).catch(()=>{}):(ce(e,t,t.id),a(e.id,t.id))}export{ce as applyGlobalSwapViaGroup,Ee as selectOption,Ie as selectProductOption,D as selectionOwnsOptionSet};
@@ -1 +1 @@
1
- import b from"./8f60e5059a.js";import M from"./d94df858ea.js";import m from"./872c4302e0.js";import D,{deriveSceneFeatures as L}from"./be337ddda5.js";import I from"./9c6c598569.js";function w(t){return Array.isArray(t)?t:typeof t=="string"&&t.trim()?[t]:t&&typeof t=="object"?Object.keys(t):[]}function F({placementId:t,optionSetId:o,optionId:r}){o==null||r==null||import("./a77b15c0d6.js").then(e=>{t!=null?e.selectOptionForProduct?.({placementId:t,optionSetId:o,optionId:r}):e.selectOptionForScene?.({optionSetId:o,optionId:r})}).catch(()=>{})}function N(){const t=M.getState().sceneSelections||{},o=m.getState().options||{},r=m.getState().products||{},e=D.getState().sceneConfigurations||{},a=I.getState().activeSceneConfigId,h=e[a];for(const v of L(h)){if(v?.type!=="load_new_product")continue;const g=t?.[v.id],f=g!=null?o?.[g]?.value:null;if(f==null)continue;const _=r[f]||r[String(f)];if(!_)continue;if(String(_.placement_group??_.placementGroup??"").includes("freestanding"))return f}return null}function $({option:t,feature:o,scope:r,pieceIndex:e}){if(!t)return{ok:!1,scope:null,wrote:0};if(t.value==null)return{ok:!1,scope:null,wrote:0};const a=o?.id??o?.feature_id;if(a==null)return{ok:!1,scope:null,wrote:0};const h=w(t?.materialSlots??t?.material_slots),v=w(o?.material_targets??o?.materialTargets??o?.materials),g=(h.length>0?h:v).map(n=>String(n).toLowerCase()).filter(Boolean);if(g.length===0)return{ok:!1,scope:null,wrote:0};const f=r==="single"||r==="all"?r:e?"single":"all";if(f==="single"&&!e)return{ok:!1,scope:null,wrote:0};if(f==="single"){const n=b.getState(),p=m.getState().products||{},l=m.getState().components||{},c=I.getState().productInstances?.[e];let i=n.hostProductOverrides?.[e]??n.basePiecePositions?.[e]?.productId??c?.variantId??c?.productId;if(i==null&&String(e).endsWith("__host")){const u=I.getState(),s=m.getState(),d=String(e).replace(/__host$/,""),k=u.productInstances?.[d],P=s.getProduct?.(k?.variantId??k?.productId),O=P?.hostVariants??P?.host_variants,j=Array.isArray(O)?O.find(A=>A?.isDefault??A?.is_default)??O[0]:null;i=j?.hostVariantId??j?.host_variant_id??null}i=i??N();const G=(i!=null?p[i]||p[String(i)]:null)?.components_configuration||{},T=new Set(g);let y=0;const B=Object.values(G).reduce((u,s)=>Array.isArray(s)?[...u,...s.map(d=>d?.componentId).filter(Boolean)]:(s&&typeof s=="object"&&s.componentId!=null&&u.push(s.componentId),u),[]);for(const u of B){const s=l[u]||l[String(u)],d=String(s?.materialSlot??s?.material_slot??"").toLowerCase();d&&T.has(d)&&(n.setHostMaterialOverride(e,d,t.value),y++)}return y>0&&F({placementId:e,optionSetId:Number(a),optionId:t.id}),{ok:y>0,scope:"single",wrote:y}}M.getState().setSceneSelection(a,t.id);const S={...b.getState().hostMaterialOverrides};let C=0;for(const n of Object.keys(S)){const p=S[n]||{};let l=null;for(const c of g)p[c]!=null&&(l||(l={...p}),delete l[c],C++);l&&(S[n]=l)}C>0&&b.setState({hostMaterialOverrides:S});try{const n=I.getState(),p=n.placementSelections||{};for(const[l,c]of Object.entries(p))if(c&&Object.prototype.hasOwnProperty.call(c,String(a))){const i={...c};delete i[String(a)],n.setPlacementSelections?.(l,i)}}catch{}return F({optionSetId:Number(a),optionId:t.id}),{ok:!0,scope:"all",wrote:0}}export{$ as applyFinishClick,w as normalizeMaterialTargets};
1
+ import b from"./8f60e5059a.js";import k from"./d94df858ea.js";import m from"./872c4302e0.js";import G,{deriveSceneFeatures as T}from"./be337ddda5.js";import _ from"./9c6c598569.js";import{resolveHostVariantId as B}from"./be07a7f885.js";function P(t){return Array.isArray(t)?t:typeof t=="string"&&t.trim()?[t]:t&&typeof t=="object"?Object.keys(t):[]}function j({placementId:t,optionSetId:o,optionId:s}){o==null||s==null||import("./a77b15c0d6.js").then(e=>{t!=null?e.selectOptionForProduct?.({placementId:t,optionSetId:o,optionId:s}):e.selectOptionForScene?.({optionSetId:o,optionId:s})}).catch(()=>{})}function H(){const t=k.getState().sceneSelections||{},o=m.getState().options||{},s=m.getState().products||{},e=G.getState().sceneConfigurations||{},a=_.getState().activeSceneConfigId,h=e[a];for(const v of T(h)){if(v?.type!=="load_new_product")continue;const g=t?.[v.id],f=g!=null?o?.[g]?.value:null;if(f==null)continue;const y=s[f]||s[String(f)];if(!y)continue;if(String(y.placement_group??y.placementGroup??"").includes("freestanding"))return f}return null}function W({option:t,feature:o,scope:s,pieceIndex:e}){if(!t)return{ok:!1,scope:null,wrote:0};if(t.value==null)return{ok:!1,scope:null,wrote:0};const a=o?.id??o?.feature_id;if(a==null)return{ok:!1,scope:null,wrote:0};const h=P(t?.materialSlots??t?.material_slots),v=P(o?.material_targets??o?.materialTargets??o?.materials),g=(h.length>0?h:v).map(n=>String(n).toLowerCase()).filter(Boolean);if(g.length===0)return{ok:!1,scope:null,wrote:0};const f=s==="single"||s==="all"?s:e?"single":"all";if(f==="single"&&!e)return{ok:!1,scope:null,wrote:0};if(f==="single"){const n=b.getState(),p=m.getState().products||{},l=m.getState().components||{},c=_.getState().productInstances?.[e];let i=n.hostProductOverrides?.[e]??n.basePiecePositions?.[e]?.productId??c?.variantId??c?.productId;if(i==null&&String(e).endsWith("__host")){const u=_.getState(),r=m.getState(),d=String(e).replace(/__host$/,""),O=u.productInstances?.[d],A=r.getProduct?.(O?.variantId??O?.productId);i=B(A,O)}i=i??H();const M=(i!=null?p[i]||p[String(i)]:null)?.components_configuration||{},w=new Set(g);let I=0;const F=Object.values(M).reduce((u,r)=>Array.isArray(r)?[...u,...r.map(d=>d?.componentId).filter(Boolean)]:(r&&typeof r=="object"&&r.componentId!=null&&u.push(r.componentId),u),[]);for(const u of F){const r=l[u]||l[String(u)],d=String(r?.materialSlot??r?.material_slot??"").toLowerCase();d&&w.has(d)&&(n.setHostMaterialOverride(e,d,t.value),I++)}return I>0&&j({placementId:e,optionSetId:Number(a),optionId:t.id}),{ok:I>0,scope:"single",wrote:I}}k.getState().setSceneSelection(a,t.id);const S={...b.getState().hostMaterialOverrides};let C=0;for(const n of Object.keys(S)){const p=S[n]||{};let l=null;for(const c of g)p[c]!=null&&(l||(l={...p}),delete l[c],C++);l&&(S[n]=l)}C>0&&b.setState({hostMaterialOverrides:S});try{const n=_.getState(),p=n.placementSelections||{};for(const[l,c]of Object.entries(p))if(c&&Object.prototype.hasOwnProperty.call(c,String(a))){const i={...c};delete i[String(a)],n.setPlacementSelections?.(l,i)}}catch{}return j({optionSetId:Number(a),optionId:t.id}),{ok:!0,scope:"all",wrote:0}}export{W as applyFinishClick,P as normalizeMaterialTargets};
@@ -1 +1 @@
1
- import{shouldBlockRequest as y,requestBlockedError as S}from"./631a9f7fac.js";import{authHeaders as v,isAuthFailure as w,reportAuthFailure as b,reportForbidden as k,getChannelId as p}from"./431a2d8618.js";import{ensureSessionToken as m,hasTokenProvider as E}from"./33fa2c8ca2.js";import{applyRequestInterceptors as O,applyResponseInterceptors as P,performRequest as T}from"./a3f18e76fe.js";import{getApiBaseUrl as C}from"./8ade32d067.js";import{assertLicensed as A}from"./fe235d7160.js";function g(e={}){const o=p();return o!=null?{...e,channelId:o}:e}async function d(e,o,{signal:i}={},a=!1){if(await A(e),y(e))throw S(e);await m();const r=O({path:e,url:`${C()}${e}`,method:"POST",headers:{"Content-Type":"application/json",...v(e)},body:o,init:void 0}),f=Date.now(),n=await T(r,c=>fetch(c.url,{method:"POST",headers:c.headers,body:JSON.stringify(c.body),signal:i}));if(w(n)){if(!a&&E())return await m({force:!0}),d(e,o,{signal:i},!0);await b(n,{url:e,method:"POST"})}n.status===403&&await k(n,{url:e,method:"POST"});let t=null;try{t=await n.json()}catch{t=null}const u=P({status:n.status,ok:n.ok,data:t||{},duration:Date.now()-f},r);return{status:u.status,ok:u.ok,data:u.data||{}}}async function j({systemId:e,presetId:o}={}){const{status:i,ok:a,data:r}=await d("/api/v1/configurations/initial/",g({systemId:e,...o!=null?{presetId:o}:{}}));if(!a)throw new Error(`initial configuration failed: ${i}`);return r}async function q({systemId:e,catalogVersion:o,state:i,mutation:a,idempotencyKey:r},{signal:f}={}){const{status:n,data:t}=await d("/api/v1/configurations/evaluate/",g({systemId:e,catalogVersion:o,state:i,mutation:a,...r?{idempotencyKey:r}:{}}),{signal:f}),u=new Set(["CONSTRAINT_NOT_IMPLEMENTED","STALE_SELECTION"]),c=s=>s&&typeof s=="object"?s.code??s.type:s,h=(t.warnings??[]).filter(s=>!u.has(String(c(s)??"").toUpperCase())),l=t.errorResponse&&typeof t.errorResponse=="object"?t.errorResponse:t;return{status:n,applied:n===200,rejected:n===422,staleCatalog:n===409||t.refetchCatalog===!0,blockingMutation:(l.blockingMutation??t.blockingMutation)===!0,code:l.code??t.code??null,system:t.system??null,pricing:t.pricing??null,resolvedState:t.resolvedState??null,optionVisibility:t.optionVisibility??null,optionSetVisibility:t.optionSetVisibility??null,optionAvailability:t.optionAvailability??null,defaultOptionOverrides:t.defaultOptionOverrides??null,fired:t.fired??[],removedPlacements:t.removedPlacements??null,addedPlacements:t.addedPlacements??null,messages:t.messages??l.messages??[],events:t.events??[],customEffects:t.customEffects??t.custom_effects??[],customDiagnostics:t.customDiagnostics??t.custom_diagnostics??l.customDiagnostics??[],errors:l.errors??t.errors??[],warnings:h,catalogVersion:t.catalogVersion??o??null,refetchCatalog:t.refetchCatalog===!0||n===409,previousState:l.previousState??t.previousState??null,schemaVersion:t.schemaVersion??null}}async function M(e){if(!Array.isArray(e)||e.length===0)return null;const o=p(),i={...o!=null?{channel:o}:{},items:e};try{const{ok:a,data:r}=await d("/api/v1/pricing/calculate/",i);return a?r:null}catch{return null}}export{M as calculatePricing,q as evaluateConfiguration,j as fetchInitialConfiguration};
1
+ import{shouldBlockRequest as y,requestBlockedError as v}from"./631a9f7fac.js";import{authHeaders as S,isAuthFailure as w,reportAuthFailure as O,reportForbidden as b,getChannelId as p}from"./431a2d8618.js";import{ensureSessionToken as m,hasTokenProvider as k}from"./33fa2c8ca2.js";import{applyRequestInterceptors as E,applyResponseInterceptors as P,performRequest as T}from"./a3f18e76fe.js";import{getApiBaseUrl as C}from"./8ade32d067.js";import{assertLicensed as A}from"./fe235d7160.js";function g(e={}){const o=p();return o!=null?{...e,channelId:o}:e}async function d(e,o,{signal:i}={},s=!1){if(await A(e),y(e))throw v(e);await m();const r=E({path:e,url:`${C()}${e}`,method:"POST",headers:{"Content-Type":"application/json",...S(e)},body:o,init:void 0}),f=Date.now(),n=await T(r,c=>fetch(c.url,{method:"POST",headers:c.headers,body:JSON.stringify(c.body),signal:i}));if(w(n)){if(!s&&k())return await m({force:!0}),d(e,o,{signal:i},!0);await O(n,{url:e,method:"POST"})}n.status===403&&await b(n,{url:e,method:"POST"});let t=null;try{t=await n.json()}catch{t=null}const u=P({status:n.status,ok:n.ok,data:t||{},duration:Date.now()-f},r);return{status:u.status,ok:u.ok,data:u.data||{}}}async function j({systemId:e,presetId:o}={}){const{status:i,ok:s,data:r}=await d("/api/v1/configurations/initial/",g({systemId:e,...o!=null?{presetId:o}:{}}));if(!s)throw new Error(`initial configuration failed: ${i}`);return r}async function q({systemId:e,catalogVersion:o,state:i,mutation:s,idempotencyKey:r},{signal:f}={}){const{status:n,data:t}=await d("/api/v1/configurations/evaluate/",g({systemId:e,catalogVersion:o,state:i,mutation:s,...r?{idempotencyKey:r}:{}}),{signal:f}),u=new Set(["CONSTRAINT_NOT_IMPLEMENTED","STALE_SELECTION"]),c=a=>a&&typeof a=="object"?a.code??a.type:a,h=(t.warnings??[]).filter(a=>!u.has(String(c(a)??"").toUpperCase())),l=t.errorResponse&&typeof t.errorResponse=="object"?t.errorResponse:t;return{status:n,applied:n===200,rejected:n===422,staleCatalog:n===409||t.refetchCatalog===!0,blockingMutation:(l.blockingMutation??t.blockingMutation)===!0,code:l.code??t.code??null,system:t.system??null,pricing:t.pricing??null,resolvedState:t.resolvedState??null,optionVisibility:t.optionVisibility??null,optionSetVisibility:t.optionSetVisibility??null,optionAvailability:t.optionAvailability??null,defaultOptionOverrides:t.defaultOptionOverrides??null,fired:t.fired??[],selectionOverrides:t.selectionOverrides??[],removedPlacements:t.removedPlacements??null,addedPlacements:t.addedPlacements??null,messages:t.messages??l.messages??[],events:t.events??[],customEffects:t.customEffects??t.custom_effects??[],customDiagnostics:t.customDiagnostics??t.custom_diagnostics??l.customDiagnostics??[],errors:l.errors??t.errors??[],warnings:h,catalogVersion:t.catalogVersion??o??null,refetchCatalog:t.refetchCatalog===!0||n===409,previousState:l.previousState??t.previousState??null,schemaVersion:t.schemaVersion??null}}async function M(e){if(!Array.isArray(e)||e.length===0)return null;const o=p(),i={...o!=null?{channel:o}:{},items:e};try{const{ok:s,data:r}=await d("/api/v1/pricing/calculate/",i);return s?r:null}catch{return null}}export{M as calculatePricing,q as evaluateConfiguration,j as fetchInitialConfiguration};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imagineio/configurator-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Configurator SDK — backend Configuration Engine client, state stores, shared 3D scene primitives, and pluggable placement (strategy + type). Drives every configurator (kitchen, sectional, …) from one self-contained surface.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "type": "module",