(()=>{ 'use strict'; const escapeHTML=value=>String(value??'').replace(/[&<>"']/g,ch=>({ '&':'&','<':'<','>':'>','"':'"',"'":''' })[ch]); const escapeAttr=escapeHTML; // Personal UI preferences must never be included in a company payload. const personalStorageKey=name=>{ const cloud=window.SunCloudV2,user=cloud?.getSession?.()?.user?.id,ws=cloud?.getWorkspace?.()?.id; return user&&ws?'caterium:personal:'+encodeURIComponent(user)+':'+encodeURIComponent(ws)+':'+encodeURIComponent(name):''; }; const idToken=value=>String(value??'').replace(/[^a-zA-Z0-9_-]/g,''); const jsArg=value=>escapeHTML(JSON.stringify(String(value??''))); // Existing trial databases and saved offers still reference the PNG originals. // Resolve only our ten bundled demo assets; never rewrite customer photos. const demoNames='berry-dessert|bruschetta-tomato|caprese|cheese-fruit|chicken-sandwich|meat-assortment|mushroom-tartlet|salmon-cream|turkey-wrap|vegetables-hummus'; const demoPath=new RegExp('^/(demo/images/(?:'+demoNames+'))\\.png$'); const imageAssetSrc=value=>{ const src=String(value??'').trim(); try{const url=new URL(src,document.baseURI);const match=url.pathname.match(demoPath);if(url.origin===location.origin&&match)return match[1]+'.webp'+url.search+url.hash;}catch(_){} return src; }; const safeImageSrc=value=>{ const s=imageAssetSrc(value); if(!s)return ''; if(/^data:image\/(?:png|jpe?g|webp|gif);base64,[a-z0-9+/=\s]+$/i.test(s))return s; if(/^(?:\.\/|\.\.\/|\/)?[a-z0-9_./-]+\.(?:png|jpe?g|webp|gif)(?:[?#][^\s]*)?$/i.test(s))return s; if(/^blob:[a-z0-9-]+:/i.test(s))return s; return ''; }; const setText=(node,value)=>{if(node)node.textContent=String(value??'');return node}; const insertBefore=(parent,node,reference=null)=>{ if(!parent||!node)return node; if(reference&&reference.parentNode===parent)parent.insertBefore(node,reference);else parent.appendChild(node); return node; }; window.SunSafe=Object.freeze({escapeHTML,escapeAttr,personalStorageKey,idToken,jsArg,safeImageSrc,imageAssetSrc,setText,insertBefore}); // Small bootstrap for account/profile UI. Keeping it here makes the account // center available on every Caterium screen without touching the legacy monolith. if(!document.getElementById('cateriumAccountCenterV1780Script')){ const script=document.createElement('script'); script.id='cateriumAccountCenterV1780Script'; script.src='core/account-center-v1780.js?v=20260920-employee-session'; script.async=true; document.head.appendChild(script); } })();