@saasquatch/squatch-js 2.8.3-9 → 2.8.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +9 -2
  2. package/babelregister.js +0 -1
  3. package/coverage/base.css +224 -0
  4. package/coverage/block-navigation.js +87 -0
  5. package/coverage/clover.xml +996 -0
  6. package/coverage/coverage-final.json +26 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/prettify.css +1 -0
  9. package/coverage/prettify.js +2 -0
  10. package/coverage/sort-arrow-sprite.png +0 -0
  11. package/coverage/sorter.js +210 -0
  12. package/demo/perf-benchmark.ts +363 -0
  13. package/demo/perf-compare.html +870 -0
  14. package/demo/perf-deploy/vercel.json +17 -0
  15. package/demo/perf-frame.html +417 -0
  16. package/demo/perf-server.ts +131 -0
  17. package/dist/ErrorTemplate-DUNm11h9.js +124 -0
  18. package/dist/ErrorTemplate-DUNm11h9.js.map +1 -0
  19. package/dist/ErrorTemplate-DumOlC5f.cjs +109 -0
  20. package/dist/ErrorTemplate-DumOlC5f.cjs.map +1 -0
  21. package/dist/SkeletonTemplate-B3Bk4NFu.cjs +243 -0
  22. package/dist/SkeletonTemplate-B3Bk4NFu.cjs.map +1 -0
  23. package/dist/SkeletonTemplate-Day_0iMM.js +246 -0
  24. package/dist/SkeletonTemplate-Day_0iMM.js.map +1 -0
  25. package/dist/squatch.cjs.js +20 -329
  26. package/dist/squatch.cjs.js.map +1 -1
  27. package/dist/squatch.esm.js +417 -764
  28. package/dist/squatch.esm.js.map +1 -1
  29. package/dist/squatch.js +149 -110
  30. package/dist/squatch.js.map +1 -1
  31. package/dist/squatch.min.js +2 -2
  32. package/dist/utils/cookieUtils.d.ts +1 -0
  33. package/dist/widgets/EmbedWidget.d.ts +1 -1
  34. package/dist/widgets/ErrorTemplate.d.ts +9 -0
  35. package/dist/widgets/PopupWidget.d.ts +1 -4
  36. package/dist/widgets/SkeletonTemplate.d.ts +1 -2
  37. package/dist/widgets/Widget.d.ts +19 -11
  38. package/package.json +11 -15
  39. package/vite-env.d.ts +2 -1
  40. package/vite.config.ts +17 -0
  41. package/babel.config.js +0 -8
  42. package/jest.config.ts +0 -200
@@ -1,5 +1,5 @@
1
- (function(u,g){typeof exports=="object"&&typeof module<"u"?g(exports):(u=typeof globalThis<"u"?globalThis:u||self,g(u.squatch={}))})(this,(function(u){"use strict";var st=Object.defineProperty;var rt=(u,g,A)=>g in u?st(u,g,{enumerable:!0,configurable:!0,writable:!0,value:A}):u[g]=A;var l=(u,g,A)=>rt(u,typeof g!="symbol"?g+"":g,A);var fe;let g=null;function A(o){const e=o.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");g=new RegExp(`^${e}$`)}function Ee(){g=null}function E(o){const t=(...e)=>{g&&g.test(o)&&console.log(`[${o}]`,...e)};return Object.defineProperty(t,"enabled",{get(){return!!(g&&g.test(o))}}),t}/*! js-cookie v3.0.5 | MIT */function O(o){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var n in e)o[n]=e[n]}return o}var xe={read:function(o){return o[0]==='"'&&(o=o.slice(1,-1)),o.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(o){return encodeURIComponent(o).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};function Y(o,t){function e(i,s,r){if(!(typeof document>"u")){r=O({},t,r),typeof r.expires=="number"&&(r.expires=new Date(Date.now()+r.expires*864e5)),r.expires&&(r.expires=r.expires.toUTCString()),i=encodeURIComponent(i).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var a="";for(var d in r)r[d]&&(a+="; "+d,r[d]!==!0&&(a+="="+r[d].split(";")[0]));return document.cookie=i+"="+o.write(s,i)+a}}function n(i){if(!(typeof document>"u"||arguments.length&&!i)){for(var s=document.cookie?document.cookie.split("; "):[],r={},a=0;a<s.length;a++){var d=s[a].split("="),c=d.slice(1).join("=");try{var h=decodeURIComponent(d[0]);if(r[h]=o.read(c,h),i===h)break}catch{}}return i?r[i]:r}}return Object.create({set:e,get:n,remove:function(i,s){e(i,"",O({},s,{expires:-1}))},withAttributes:function(i){return Y(this.converter,O({},this.attributes,i))},withConverter:function(i){return Y(O({},this.converter,i),this.attributes)}},{attributes:{value:Object.freeze(t)},converter:{value:Object.freeze(o)}})}var D=Y(xe,{path:"/"});const I="https://app.referralsaasquatch.com",K="https://fast.ssqt.io/npm",j="squatch",Z="impact";function W(o){if(typeof o!="object")throw new Error("config must be an object");const t=window.squatchTenant,e=ee(),n={tenantAlias:(o==null?void 0:o.tenantAlias)||t,domain:(o==null?void 0:o.domain)||(e==null?void 0:e.domain),npmCdn:(o==null?void 0:o.npmCdn)||(e==null?void 0:e.npmCdn),debug:(o==null?void 0:o.debug)||(e==null?void 0:e.debug)};if(typeof n.tenantAlias!="string")throw new Error("tenantAlias not provided");const i=n.tenantAlias,s=typeof n.domain=="string"&&n.domain||I,r=typeof n.debug=="boolean"&&n.debug||!1,a=typeof n.npmCdn=="string"&&n.npmCdn||K;return{tenantAlias:i,domain:s,debug:r,npmCdn:a}}function _(o){return typeof o=="object"&&!Array.isArray(o)&&o!==null}function Ce(o){if(o&&/^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(o))return o}function se(o){if(!_(o))throw new Error("Widget properties must be an object");if(!(o!=null&&o.user))throw new Error("Required properties missing.");return o}function re(o){if(!_(o))throw new Error("Widget properties must be an object");return o}function $(){return window.impactToken||window.squatchToken}function ee(){return window.impactConfig||window.squatchConfig}function N(o){console.log("[DEBUG] parseErrorResponse - raw responseText:",o);try{const t=JSON.parse(o);if(console.log("[DEBUG] parseErrorResponse - parsed JSON:",t),t&&typeof t=="object")return console.log("[DEBUG] parseErrorResponse - returning parsed object with apiErrorCode:",t.apiErrorCode),t}catch(t){console.log("[DEBUG] parseErrorResponse - JSON parse failed:",t)}return{message:o}}async function Ae(o,t,e,n){const i=n||$(),s={Accept:"application/json","Content-Type":"application/json",...i?{Authorization:`Bearer ${i}`}:{},"X-SaaSquatch-Referrer":window?window.location.href:""};try{const r=await fetch(o,{method:"POST",body:JSON.stringify({query:t,variables:e}),headers:s});if(!r.ok)throw N(await r.text());return await r.json()}catch(r){throw r}}async function Ie(o,t=""){const e={Accept:"application/json","Content-Type":"application/json"},n=t||$();n?(e["X-SaaSquatch-User-Token"]=n,console.log("[DEBUG] doGet - Adding token to headers:",n)):console.log("[DEBUG] doGet - No token found, proceeding without authentication header.");try{const i=await fetch(o,{method:"GET",credentials:"include",headers:e}),s=await i.text();if(!i.ok)throw N(s);return s&&JSON.parse(s)}catch(i){throw i}}async function te(o,t,e){const n={Accept:"application/json","Content-Type":"application/json"},i=e||$();i?(console.log("[DEBUG] doPost - Adding token to headers:",i),n["X-SaaSquatch-User-Token"]=i):console.log("[DEBUG] doPost - No token found, proceeding without authentication header.");try{const s=await fetch(o,{method:"POST",body:t,headers:n}),r=await s.text();if(!s.ok)throw N(r);return r&&JSON.parse(r)}catch(s){throw s}}async function _e(o,t,e){const n={Accept:"application/json","Content-Type":"application/json","X-SaaSquatch-Referrer":window?window.location.href:""},i=e||$();i&&(n["X-SaaSquatch-User-Token"]=i);try{const s=await fetch(o,{headers:n,method:"PUT",credentials:"include",body:t}),r=await s.text();if(!s.ok)throw N(r);return r&&JSON.parse(r)}catch(s){throw s}}const Te=`\n query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {\n renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {\n template\n user {\n id\n accountId\n }\n jsOptions\n widgetConfig {\n values\n }\n }\n }\n`;class F{constructor(t){l(this,"tenantAlias");l(this,"domain");l(this,"npmCdn");l(this,"referralCookie",this.squatchReferralCookie);const n=W(t);this.tenantAlias=n.tenantAlias,this.domain=n.domain,this.npmCdn=n.npmCdn}upsertUser(t){const n=se(t),{widgetType:i,engagementMedium:s="POPUP",jwt:r,locale:a,user:d}=n,c=encodeURIComponent(this.tenantAlias),h=d.accountId?encodeURIComponent(d.accountId):null,p=d.id?encodeURIComponent(d.id):null,m=We({widgetType:i,engagementMedium:s,locale:a}),w=`/api/v1/${c}/widget/account/${h}/user/${p}/upsert${m}`,f=this.domain+w,b=(D||window.Cookies).get("_saasquatch");return b&&(d.cookies=b),_e(f,JSON.stringify(d),r)}render(t){const n=re(t),{widgetType:i,engagementMedium:s="POPUP",jwt:r,user:a}=n,d=encodeURIComponent(this.tenantAlias),c=a!=null&&a.accountId?encodeURIComponent(a.accountId):null,h=a!=null&&a.id?encodeURIComponent(a.id):null,p=n.locale??Ce(navigator.language.replace(/\-/g,"_")),m=`/api/v1/${d}/graphql`,w=this.domain+m;return new Promise((async(f,b)=>{var x;try{const y=await Ae(w,Te,{user:h&&c?{id:h,accountId:c}:null,engagementMedium:s,widgetType:i,locale:p},r);f((x=y==null?void 0:y.data)==null?void 0:x.renderWidget)}catch(y){b(y)}}))}async squatchReferralCookie(){const t=encodeURIComponent(this.tenantAlias),e=(D||window.Cookies).get("_saasquatch")||"",n=e?`?cookies=${encodeURIComponent(e)}`:"",i=`${this.domain}/a/${t}/widgets/squatchcookiejson${n}`,s=await Ie(i);return Promise.resolve({...s,encodedCookie:e})}}function We({widgetType:o,engagementMedium:t,locale:e}){const n=new URLSearchParams;return n.append("engagementMedium",t),o&&n.append("widgetType",o),e&&n.append("locale",e),`?${n.toString()}`
1
+ (function(g,p){typeof exports=="object"&&typeof module<"u"?p(exports):(g=typeof globalThis<"u"?globalThis:g||self,p(g.squatch={}))})(this,(function(g){"use strict";var st=Object.defineProperty;var rt=(g,p,I)=>p in g?st(g,p,{enumerable:!0,configurable:!0,writable:!0,value:I}):g[p]=I;var l=(g,p,I)=>rt(g,typeof p!="symbol"?p+"":p,I);var me;let p=null;function I(o){const e=o.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");p=new RegExp(`^${e}$`)}function ke(){p=null}function v(o){const t=(...e)=>{p&&p.test(o)&&console.log(`[${o}]`,...e)};return Object.defineProperty(t,"enabled",{get(){return!!(p&&p.test(o))}}),t}const C=v("squatch-js");function Y(o){const t=document.cookie.match(new RegExp("(?:^|; )"+o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"=([^;]*)"));return t?decodeURIComponent(t[1]):void 0}function Ee(o,t,e){let n=`${encodeURIComponent(o)}=${encodeURIComponent(t)}`;{const i=new Date;i.setTime(i.getTime()+e.expires*864e5),n+=`; expires=${i.toUTCString()}`}e.path&&(n+=`; path=${e.path}`),e.domain&&(n+=`; domain=${e.domain}`),e.sameSite&&(n+=`; SameSite=${e.sameSite}`),document.cookie=n}const oe=o=>typeof o=="object"&&!Array.isArray(o),se=(o,t)=>{const e=i=>oe(t[i])&&o.hasOwnProperty(i)&&oe(o[i]),n=Object.getOwnPropertyNames(t).map((i=>({[i]:e(i)?se(o[i],t[i]):t[i]}))).reduce(((i,s)=>({...i,...s})),{});return{...o,...n}};function j(o){const t=atob(o.replace(/_/g,"/").replace(/-/g,"+")),e=new Uint8Array(t.length);for(let n=0;n<t.length;n++)e[n]=t.charCodeAt(n);return new TextDecoder("utf8").decode(e)}function re(o){const t=(new TextEncoder).encode(o),e=Array.from(t,(n=>String.fromCodePoint(n))).join("");return btoa(e).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function xe(){var o,t,e="weird_get_top_level_domain=cookie",n=document.location.hostname.split(".");for(o=n.length-1;o>=0;o--)if(t=n.slice(o).join("."),document.cookie=e+";domain=."+t+";",document.cookie.indexOf(e)>-1)return document.cookie=e.split("=")[0]+"=;domain=."+t+";expires=Thu, 01 Jan 1970 00:00:01 GMT;",t}function Ce(){const o=window.location.search,e=new URLSearchParams(o).get("_saasquatch")||"";if(e){let n="",i="",s="";try{n=JSON.parse(j(e))}catch(r){C("Unable to decode params",r);return}try{i=JSON.parse(j(Y("_saasquatch"))),C("existing cookie",i)}catch(r){C("Unable to retrieve cookie",r)}try{const r=xe();if(C("domain retrieved:",r),i){const a=se(i,n);s=re(JSON.stringify(a)),C("cookie to store:",a)}else s=re(JSON.stringify(n)),C("cookie to store:",n);Ee("_saasquatch",s,{expires:365,secure:!1,sameSite:"Lax",domain:r,path:"/"})}catch(r){C("Unable to set cookie",r)}}}const A="https://app.referralsaasquatch.com",Z="https://fast.ssqt.io/npm",D="squatch",K="impact";function $(o){if(typeof o!="object")throw new Error("config must be an object");const t=window.squatchTenant,e=ee(),n={tenantAlias:(o==null?void 0:o.tenantAlias)||t,domain:(o==null?void 0:o.domain)||(e==null?void 0:e.domain),npmCdn:(o==null?void 0:o.npmCdn)||(e==null?void 0:e.npmCdn),debug:(o==null?void 0:o.debug)||(e==null?void 0:e.debug)};if(typeof n.tenantAlias!="string")throw new Error("tenantAlias not provided");const i=n.tenantAlias,s=typeof n.domain=="string"&&n.domain||A,r=typeof n.debug=="boolean"&&n.debug||!1,a=typeof n.npmCdn=="string"&&n.npmCdn||Z;return{tenantAlias:i,domain:s,debug:r,npmCdn:a}}function _(o){return typeof o=="object"&&!Array.isArray(o)&&o!==null}function Ie(o){if(o&&/^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(o))return o}function ae(o){if(!_(o))throw new Error("Widget properties must be an object");if(!(o!=null&&o.user))throw new Error("Required properties missing.");return o}function de(o){if(!_(o))throw new Error("Widget properties must be an object");return o}function W(){return window.impactToken||window.squatchToken}function ee(){return window.impactConfig||window.squatchConfig}const ce=v("squatch-js:io");function N(o){let t,e,n,i=o;try{const r=JSON.parse(o);r&&typeof r=="object"&&(t=r.apiErrorCode,e=r.rsCode,n=r.statusCode,i=r.message||o)}catch{}const s=new Error(i);return t&&(s.apiErrorCode=t),e&&(s.rsCode=e),n!==void 0&&(s.statusCode=n),s}async function Ae(o,t,e,n){const i=n||W(),s={Accept:"application/json","Content-Type":"application/json",...i?{Authorization:`Bearer ${i}`}:{},"X-SaaSquatch-Referrer":window?window.location.href:""};try{const r=await fetch(o,{method:"POST",body:JSON.stringify({query:t,variables:e}),headers:s});if(!r.ok)throw N(await r.text());return await r.json()}catch(r){throw r}}async function _e(o,t=""){const e={Accept:"application/json","Content-Type":"application/json"},n=t||W();n?e["X-SaaSquatch-User-Token"]=n:ce("[DEBUG] doGet - No token found, proceeding without authentication header.");try{const i=await fetch(o,{method:"GET",credentials:"include",headers:e}),s=await i.text();if(!i.ok)throw N(s);return s&&JSON.parse(s)}catch(i){throw i}}async function te(o,t,e){const n={Accept:"application/json","Content-Type":"application/json"},i=e||W();i?n["X-SaaSquatch-User-Token"]=i:ce("[DEBUG] doPost - No token found, proceeding without authentication header.");try{const s=await fetch(o,{method:"POST",body:t,headers:n}),r=await s.text();if(!s.ok)throw N(r);return r&&JSON.parse(r)}catch(s){throw s}}async function Te(o,t,e){const n={Accept:"application/json","Content-Type":"application/json","X-SaaSquatch-Referrer":window?window.location.href:""},i=e||W();i&&(n["X-SaaSquatch-User-Token"]=i);try{const s=await fetch(o,{headers:n,method:"PUT",credentials:"include",body:t}),r=await s.text();if(!s.ok)throw N(r);return r&&JSON.parse(r)}catch(s){throw s}}const Se=`\n query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {\n renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {\n template\n user {\n id\n accountId\n }\n jsOptions\n widgetConfig {\n values\n }\n }\n }\n`;class F{constructor(t){l(this,"tenantAlias");l(this,"domain");l(this,"npmCdn");l(this,"referralCookie",this.squatchReferralCookie);const n=$(t);this.tenantAlias=n.tenantAlias,this.domain=n.domain,this.npmCdn=n.npmCdn}upsertUser(t){const n=ae(t),{widgetType:i,engagementMedium:s="POPUP",jwt:r,locale:a,user:d}=n,c=encodeURIComponent(this.tenantAlias),h=d.accountId?encodeURIComponent(d.accountId):null,u=d.id?encodeURIComponent(d.id):null,m=$e({widgetType:i,engagementMedium:s,locale:a}),w=`/api/v1/${c}/widget/account/${h}/user/${u}/upsert${m}`,f=this.domain+w,E=Y("_saasquatch");return E&&(d.cookies=E),Te(f,JSON.stringify(d),r)}render(t){const n=de(t),{widgetType:i,engagementMedium:s="POPUP",jwt:r,user:a}=n,d=encodeURIComponent(this.tenantAlias),c=a!=null&&a.accountId?encodeURIComponent(a.accountId):null,h=a!=null&&a.id?encodeURIComponent(a.id):null,u=n.locale??Ie(navigator.language.replace(/\-/g,"_")),m=`/api/v1/${d}/graphql`,w=this.domain+m;return new Promise((async(f,E)=>{var x;try{const y=await Ae(w,Se,{user:h&&c?{id:h,accountId:c}:null,engagementMedium:s,widgetType:i,locale:u},r);f((x=y==null?void 0:y.data)==null?void 0:x.renderWidget)}catch(y){E(y)}}))}async squatchReferralCookie(){const t=encodeURIComponent(this.tenantAlias),e=Y("_saasquatch")||"",n=e?`?cookies=${encodeURIComponent(e)}`:"",i=`${this.domain}/a/${t}/widgets/squatchcookiejson${n}`,s=await _e(i);return Promise.resolve({...s,encodedCookie:e})}}function $e({widgetType:o,engagementMedium:t,locale:e}){const n=new URLSearchParams;return n.append("engagementMedium",t),o&&n.append("widgetType",o),e&&n.append("locale",e),`?${n.toString()}`
2
2
  /*!
3
3
  * domready (c) Dustin Diaz 2014 - License MIT
4
4
  *
5
- */}function ne(o,t){let e=[],n,i=o,s=i.documentElement.doScroll,r="DOMContentLoaded",a=(s?/^loaded|^c/:/^loaded|^i|^c/).test(i.readyState);return a||i.addEventListener(r,n=()=>{for(i.removeEventListener(r,n),a=!0;n=e.shift();)n()}),a?setTimeout(t,0):e.push(t)}function B({value:o,unit:t}){switch(t){case"px":return`${o}px`;case"%":return`${o}%`;default:return`${o}px`}}class ae{constructor(t){l(this,"domain");var i;const n=$e(t);this.domain=(n==null?void 0:n.domain)||((i=ee())==null?void 0:i.domain)||I}pushAnalyticsLoadEvent(t){if(!t.externalUserId||!t.externalAccountId)return;const e=encodeURIComponent(t.tenantAlias),n=encodeURIComponent(t.externalAccountId),i=encodeURIComponent(t.externalUserId),s=encodeURIComponent(t.engagementMedium),r=t.programId?`&programId=${encodeURIComponent(t.programId)}`:"",a=`/a/${e}/widgets/analytics/loaded?externalAccountId=${n}&externalUserId=${i}&engagementMedium=${s}${r}`,d=this.domain+a;return te(d,JSON.stringify({}))}pushAnalyticsShareClickedEvent(t){const e=encodeURIComponent(t.tenantAlias),n=encodeURIComponent(t.externalAccountId),i=encodeURIComponent(t.externalUserId),s=encodeURIComponent(t.engagementMedium),r=encodeURIComponent(t.shareMedium),a=`/a/${e}/widgets/analytics/shared?externalAccountId=${n}&externalUserId=${i}&engagementMedium=${s}&shareMedium=${r}`,d=this.domain+a;return te(d,JSON.stringify({}))}}function $e(o){if(!_(o))throw new Error("'options' should be an object");return o}const de=({type:o="verified-access",height:t="500px"})=>{const e="#e0e0e0";return`\n <style>\n * {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n .widget-container {\n background: white;\n width: 100%;\n padding: 40px;\n box-sizing: border-box;\n overflow: hidden; \n }\n\n @keyframes shimmer {\n 0% { background-position: -100% 0; }\n 100% { background-position: 100% 0; }\n }\n\n .skeleton {\n background: ${e};\n background: linear-gradient(\n 90deg,\n ${e} 25%,\n #f5f5f5 50%,\n ${e} 75%\n );\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite linear;\n border-radius: 6px;\n margin-bottom: 12px;\n }\n\n /* Typography Skeletons */\n .sk-title-lg { height: 36px; width: 80%; margin-bottom: 16px; }\n .sk-title-md { height: 28px; width: 30%; margin-bottom: 20px; margin-top: 40px; }\n .sk-text { height: 16px; width: 90%; margin-bottom: 8px; }\n .sk-text-short { width: 40%; }\n .sk-label { height: 14px; width: 25%; margin-bottom: 10px; }\n\n /* Layouts */\n .hero-section {\n display: flex;\n gap: 40px;\n margin-bottom: 40px;\n padding-bottom: 40px;\n flex-direction: row;\n height: 100%;\n /* Removed border-bottom */\n }\n \n .hero-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n \n .hero-image {\n flex: 1;\n height: 300px;\n border-radius: 12px;\n }\n\n /* -- Specific Instant Access Overrides -- */\n .instant-access-layout {\n margin-bottom: 0;\n padding-bottom: 0;\n align-items: center; \n }\n .ia-image {\n height: 400px; \n }\n .ia-center {\n margin-left: auto;\n margin-right: auto;\n }\n .ia-content {\n align-items: center; \n text-align: center;\n }\n .sk-btn-action {\n height: 45px;\n width: 140px;\n border-radius: 6px;\n margin: 24px auto;\n }\n .input-group {\n display: flex;\n gap: 10px;\n width: 100%;\n max-width: 400px;\n }\n .sk-btn-copy {\n height: 50px;\n width: 120px;\n border-radius: 8px;\n }\n /* ------------------------------------- */\n\n .share-section { margin-bottom: 40px; }\n .sk-input { height: 50px; width: 100%; border-radius: 8px; margin-bottom: 16px; }\n \n .social-buttons { display: flex; gap: 12px; }\n .sk-btn-social { flex: 1; height: 50px; border-radius: 8px; }\n\n .stats-section {\n display: flex;\n gap: 24px;\n margin-bottom: 40px;\n padding: 30px 0;\n /* Removed border-top and border-bottom */\n }\n .stat-card { flex: 1; display: flex; flex-direction: column; align-items: center; }\n .stat-divider { padding-left: 24px; }\n .sk-stat-num { height: 48px; width: 120px; margin-bottom: 8px; }\n .sk-stat-label { height: 18px; width: 80px; }\n\n /* Table Styles */\n .table-header { display: flex; gap: 16px; margin-bottom: 16px; }\n .sk-th { height: 16px; }\n .table-row { \n display: flex; \n align-items: center; \n gap: 16px; \n padding: 16px 0; \n /* Removed border-bottom */\n }\n \n .col-user { flex: 2; }\n .col-status { flex: 1; }\n .col-reward { flex: 2; }\n .col-date { flex: 1; }\n\n .sk-badge { height: 28px; width: 90px; border-radius: 14px; }\n .sk-reward-block { height: 36px; width: 100%; border-radius: 6px; }\n\n .pagination { display: flex; justify-content: flex-end; gap: 8px; margin-top: 24px; }\n .sk-btn-page { height: 36px; width: 64px; border-radius: 6px; margin-bottom: 0; }\n\n @media (max-width: 768px) {\n body { padding: 20px; }\n .widget-container { padding: 24px; }\n\n .hero-section { flex-direction: column-reverse; gap: 24px; }\n .instant-access-layout { flex-direction: column; }\n \n .hero-image { height: 220px; width: 100%; }\n .sk-title-lg { width: 100%; }\n\n .col-date { display: none; }\n }\n </style>\n\n <div class="widget-container">\n ${o==="verified-access"?`\n <div class="hero-section">\n <div class="hero-content">\n <div class="skeleton sk-title-lg"></div>\n <div class="skeleton sk-text"></div>\n <div class="skeleton sk-text sk-text-short"></div>\n </div>\n <div class="skeleton hero-image"></div>\n </div>\n\n <div class="share-section">\n <div class="skeleton sk-label"></div>\n <div class="skeleton sk-input"></div>\n <div class="social-buttons">\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n </div>\n </div>\n\n <div class="skeleton sk-title-md" style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"></div>\n <div class="skeleton sk-text" style="width: 60%; margin-left: auto; margin-right: auto"></div>\n\n <div class="stats-section">\n <div class="stat-card">\n <div class="skeleton sk-stat-num"></div>\n <div class="skeleton sk-stat-label"></div>\n </div>\n <div class="stat-card stat-divider">\n <div class="skeleton sk-stat-num"></div>\n <div class="skeleton sk-stat-label"></div>\n </div>\n </div>\n\n <div class="skeleton sk-title-md"></div>\n\n <div class="table-header">\n <div class="skeleton sk-th col-user"></div>\n <div class="skeleton sk-th col-status"></div>\n <div class="skeleton sk-th col-reward"></div>\n <div class="skeleton sk-th col-date"></div>\n </div>\n\n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 70%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n \n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 60%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n\n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 75%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n\n <div class="pagination">\n <div class="skeleton sk-btn-page"></div>\n <div class="skeleton sk-btn-page"></div>\n </div>\n `:`\n <div class="hero-section instant-access-layout">\n <div class="skeleton hero-image ia-image"></div>\n \n <div class="hero-content ia-content">\n <div class="skeleton sk-title-lg ia-center"></div>\n <div class="skeleton sk-text ia-center"></div>\n \n <div class="skeleton sk-btn-action"></div>\n\n <div class="skeleton sk-label"></div>\n <div class="input-group">\n <div class="skeleton sk-input"></div>\n <div class="skeleton sk-btn-copy"></div>\n </div>\n\n <div class="skeleton sk-text-short ia-center" style="margin-top: 20px; width: 30%"></div>\n <div class="skeleton sk-text-short ia-center" style="width: 20%"></div>\n </div>\n </div>\n `}\n </div>\n `},Ue=Object.freeze(Object.defineProperty({__proto__:null,getSkeleton:de},Symbol.toStringTag,{value:"Module"})),v=E("squatch-js:widget");class ce{constructor(t){l(this,"type");l(this,"content");l(this,"analyticsApi");l(this,"widgetApi");l(this,"context");l(this,"npmCdn");l(this,"container");l(this,"loadEventListener",null);var e;v("widget initializing ..."),this.content=t.content==="error"?this._error({rsCode:t.rsCode,apiErrorCode:t.apiErrorCode,statusCode:t.statusCode,message:t.errorMessage}):t.content,this.type=t.type,this.widgetApi=t.api,this.npmCdn=t.npmCdn,this.analyticsApi=new ae({domain:t.domain}),this.context=t.context,this.container=((e=t.context)==null?void 0:e.container)||t.container}_findElement(){let t;if(typeof this.container=="string"?(t=document.querySelector(this.container),v("loading widget with selector",t)):this.container instanceof HTMLElement?(t=this.container,v("loading widget with container",t)):this.container?(t=null,v("container must be an HTMLElement or string",this.container)):(t=document.querySelector("#squatchembed")||document.querySelector(".squatchembed")||document.querySelector("#impactembed")||document.querySelector(".impactembed"),v("loading widget with default selector",t)),!(t instanceof HTMLElement))throw new Error(`element with selector '${this.container||"#squatchembed, .squatchembed, #impactembed, or .impactembed"}' not found.'`);return t}_createFrame(t){const e=document.createElement("iframe");return e.squatchJsApi=this,e.id="squatchFrame",e.width="100%",e.src="about:blank",e.scrolling="no",e.setAttribute("style","border: 0; background-color: none; width: 1px; min-width: 100%; display: block;"),t!=null&&t.minWidth&&(e.style.minWidth=t.minWidth),t!=null&&t.maxWidth&&(e.style.maxWidth=t.maxWidth),(t!=null&&t.maxWidth||t!=null&&t.minWidth)&&(e.style.width="100%"),t!=null&&t.initialHeight&&(e.height=String(t.initialHeight)),e}_findFrame(){const t=this.container?this._findElement():document.body;return(t.shadowRoot||t).querySelector("iframe#squatchFrame")}_detachLoadEventListener(t){this.loadEventListener&&(t.removeEventListener("sq:user-registration",this.loadEventListener),this.loadEventListener=null)}_attachLoadEventListener(t,e){this.loadEventListener===null&&(this.loadEventListener=n=>{this._loadEvent({...e,userId:n.detail.userId,accountId:n.detail.accountId})},t.addEventListener("sq:user-registration",this.loadEventListener))}_loadEvent(t){var n;if(!t)return;if(!_(t))throw new Error("Widget Load event identity property is not an object");let e;if("programId"in t){if(!t.tenantAlias||!t.accountId||!t.userId||!t.engagementMedium)throw new Error("Widget Load event missing required properties");e={tenantAlias:t.tenantAlias,externalAccountId:t.accountId,externalUserId:t.userId,engagementMedium:t.engagementMedium,programId:t.programId}}else{const{analytics:i,mode:s}=t;e={tenantAlias:i.attributes.tenant,externalAccountId:i.attributes.accountId,externalUserId:i.attributes.userId,engagementMedium:s.widgetMode}}(n=this.analyticsApi.pushAnalyticsLoadEvent(e))==null||n.then((i=>{v(`${e.engagementMedium} loaded event recorded.`)})).catch((i=>{v(`ERROR: pushAnalyticsLoadEvent() ${i}`)}))}_shareEvent(t,e){t&&this.analyticsApi.pushAnalyticsShareClickedEvent({tenantAlias:t.analytics.attributes.tenant,externalAccountId:t.analytics.attributes.accountId,externalUserId:t.analytics.attributes.userId,engagementMedium:t.mode.widgetMode,shareMedium:e}).then((n=>{v(`${t.mode.widgetMode} share ${e} event recorded. ${n}`)})).catch((n=>{v(`ERROR: pushAnalyticsShareClickedEvent() ${n}`)}))}_error(t,e="modal",n=""){const{rsCode:i,apiErrorCode:s,statusCode:r,message:a}=t||{};return`<!DOCTYPE html>\n \x3c!--[if IE 7]><html class="ie7 oldie" lang="en"><![endif]--\x3e\n \x3c!--[if IE 8]><html class="ie8 oldie" lang="en"><![endif]--\x3e\n \x3c!--[if gt IE 8]>\x3c!--\x3e<html lang="en">\x3c!--<![endif]--\x3e\n <head>\n <link rel="stylesheet" media="all" href="https://fast.ssqt.io/assets/css/widget/errorpage.css">\n <style>\n ${n}\n .error-details {\n margin-top: 16px;\n padding: 12px;\n background: #f8f8f8;\n border-radius: 4px;\n text-align: left;\n font-size: 13px;\n color: #666;\n }\n .error-details dt {\n font-weight: 600;\n color: #333;\n margin-top: 8px;\n }\n .error-details dt:first-child {\n margin-top: 0;\n }\n .error-details dd {\n margin: 4px 0 0 0;\n word-break: break-word;\n font-family: monospace;\n }\n .error-details dd.message {\n font-family: inherit;\n }\n </style>\n </head>\n <body>\n\n <div class="squatch-container ${e}" style="width:100%">\n <div class="errorheader">\n <button type="button" class="close" onclick="window.frameElement.squatchJsApi.close();">&times;</button>\n <p class="errortitle">Error</p>\n </div>\n <div class="errorbody">\n <div class="sadface"><img src="https://res.cloudinary.com/saasquatch-staging/image/upload/v1774538373/whoops-error-image_km94z1.svg"></div>\n <h4>Our referral program is temporarily unavailable.</h4>\n <p>Please reload the page or check back later.</p>\n <p>If the problem persists please contact our support team.</p>\n\n ${r||s||i||a?`\n <dl class="error-details">\n ${r?`<dt>Status Code</dt><dd>${r}</dd>`:""}\n ${s?`<dt>API Error Code</dt><dd>${s}</dd>`:""}\n ${i?`<dt>RS Code</dt><dd>${i}</dd>`:""}\n ${a?`<dt>Message</dt><dd class="message">${a}</dd>`:""}\n </dl>\n `:""}\n </div>\n </div>\n </body>\n </html>`}async _findInnerContainer(t){const{contentWindow:e}=t;if(!e)throw new Error("Squatch.js frame inner frame is empty");const n=e.document;function i(){const r=n.getElementsByTagName("sqh-global-container"),a=n.getElementsByClassName("squatch-container");return r.length>0?r[0]:a.length>0?a[0]:null}let s=null;for(let r=0;r<5&&(s=i(),!s);r++)await Se(100);return s||n.body}_getSkeletonPreloadHTML(t,e){if(!t)return"";const n=this.context.type==="passwordless"?"instant-access":"verified-access",i=de({type:n,height:"100%"});return`\n <div id="sq-preload" style="visibility: visible; position: absolute; top: 0; left: 0; width: 100%; z-index: 9999; background: ${e||"white"};">\n ${i}\n </div>\n <script>(${qe.toString()})()<\/script>\n `}reload({email:t,firstName:e,lastName:n},i){const s=this._findFrame();if(!s)throw new Error("Could not find widget iframe");const r=s.contentWindow,a=this.context.engagementMedium||"POPUP";if(!r)throw new Error("Frame needs a content window");let d;if(this.context.type==="upsert"){if(!this.context.user)throw new Error("Can't reload without user ids");let c={email:t||null,firstName:e||null,lastName:n||null,id:this.context.user.id,accountId:this.context.user.accountId};d=this.widgetApi.upsertUser({user:c,engagementMedium:a,widgetType:this.type,jwt:i})}else if(this.context.type==="passwordless")d=this.widgetApi.render({user:void 0,engagementMedium:a,widgetType:this.type,jwt:void 0});else throw new Error("can't reload an error widget");d.then((({template:c})=>{c&&(this.content=c,this.__deprecated__register(s,{email:t,engagementMedium:a},(()=>{this.load(),a==="POPUP"&&this.open()})))})).catch((({message:c})=>{v(`${c}`)}))}__deprecated__register(t,e,n){const s=t.contentWindow.document,r=s.createElement("button"),a=s.getElementsByClassName("squatch-register")[0];if(a){r.className="btn btn-primary",r.id="show-stats-btn",r.textContent=this.type==="REFERRER_WIDGET"?"Show Stats":"Show Reward";const d=e.engagementMedium==="POPUP"?"margin-top: 10px; max-width: 130px; width: 100%;":"margin-top: 10px;";r.setAttribute("style",d),r.onclick=n,a.style.paddingTop="30px",a.innerHTML=`<p><strong>${e.email}</strong><br>Has been successfully registered</p>`,a.appendChild(r)}}}function Se(o){return new Promise((t=>{setTimeout(t,o)}))}function qe(){var o=setTimeout(t,1e4);function t(){var n=document.getElementById("sq-preload");n&&n.remove(),clearTimeout(o)}function e(){var n=new Set;if(document.querySelectorAll("*").forEach((function(i){i.tagName.includes("-")&&n.add(i.tagName.toLowerCase())})),!n.size)return t();Promise.all(Array.from(n).map((function(i){return customElements.whenDefined(i)}))).then((function(){requestAnimationFrame((function(){requestAnimationFrame(t)}))}))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):setTimeout(e,0)}const T=E("squatch-js:EMBEDwidget");class U extends ce{constructor(e,n){super(e);l(this,"show",this.open);l(this,"hide",this.close);n&&(this.container=n)}async load(){var f,b,x,y,L,we,ye,ve,ke;const e=(b=(f=this.context.widgetConfig)==null?void 0:f.values)==null?void 0:b.brandingConfig,n=(x=this.content)==null?void 0:x.includes("mint-components"),i=(e==null?void 0:e.loadingHeight)||500,s=(y=e==null?void 0:e.widgetSize)==null?void 0:y.embeddedWidgets,r=s!=null&&s.maxWidth?B(s.maxWidth):"",a=s!=null&&s.minWidth?B(s.minWidth):"",d=this._createFrame({minWidth:a,maxWidth:r,initialHeight:i}),c=this._findElement();(L=this.context)!=null&&L.container&&(c.style.visibility="hidden",c.style.height="0",c.style["overflow-y"]="hidden"),this.container?c.shadowRoot?((we=c.shadowRoot.lastChild)==null?void 0:we.nodeName)==="IFRAME"?c.shadowRoot.replaceChild(d,c.shadowRoot.lastChild):c.shadowRoot.appendChild(d):c.firstChild?c.replaceChild(d,c.firstChild):c.appendChild(d):(!c.firstChild||c.firstChild.nodeName==="#text")&&c.appendChild(d);const{contentWindow:h}=d;if(!h)throw new Error("Frame needs a content window");const p=h.document;p.open();const w=this.widgetApi.domain==="https://staging.referralsaasquatch.com"?"-staging":"";p.write(`\n ${(ye=e==null?void 0:e.main)!=null&&ye.brandFont?`\n <link rel="preconnect" href="https://fast${w}.ssqt.io">\n <link rel="preconnect" href="https://fonts.gstatic.com">\n <link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent((ve=e==null?void 0:e.main)==null?void 0:ve.brandFont)}" as="style">`:""}\n <link rel="dns-prefetch" href="https://res.cloudinary.com">\n <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>\n ${n?`\n <style data-styles>\n html { visibility: hidden; }\n </style>`:""}\n ${this._getSkeletonPreloadHTML(n,(ke=e==null?void 0:e.color)==null?void 0:ke.backgroundColor)}\n ${this.content}\n <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>\n `),p.close(),ne(p,(async()=>{const be=h.squatch||h.widgetIdent;d.height=i;const et=new h.ResizeObserver((nt=>{for(const it of nt){const{height:ot}=it.contentRect;d.height=ot}})),tt=await this._findInnerContainer(d);et.observe(tt),this._shouldFireLoadEvent()?(this._loadEvent(be),T("loaded")):p&&this._attachLoadEventListener(p,be)}))}open(){const e=this._findFrame();if(!e)return T("no target element to open");if(!e.contentWindow)return T("Frame needs a content window");const n=this._findElement();n.style.visibility="unset",n.style.height="auto",n.style["overflow-y"]="auto",e.contentWindow.document.dispatchEvent(new CustomEvent("sq:refresh"));const i=e.contentWindow.squatch||e.contentWindow.widgetIdent;if(this.context.user)this._loadEvent(i),T("loaded");else{if(!e.contentDocument)return;this._attachLoadEventListener(e.contentDocument,i)}}close(){const e=this._findFrame();if(!e)return T("no target element to close");e.contentDocument&&this._detachLoadEventListener(e.contentDocument);const n=this._findElement();n.style.visibility="hidden",n.style.height="0",n.style["overflow-y"]="hidden",T("Embed widget closed")}_error(e,n="embed",i=""){return super._error(e,n,i)}_shouldFireLoadEvent(){const e=!this.container,n=this.container instanceof HTMLElement&&(this.container.tagName.startsWith("SQUATCH-")||this.container.tagName.startsWith("IMPACT-"));return!!this.context.user&&(e||n)}}const S=E("squatch-js:POPUPwidget");let H=0;class q extends ce{constructor(e,n=".squatchpop"){super(e);l(this,"trigger");l(this,"id");l(this,"show",this.open);l(this,"hide",this.close);this.trigger=n,this.container?this.id="squatchModal":(this.id=H===0?"squatchModal":`squatchModal__${H}`,H=H+1),document.head.insertAdjacentHTML("beforeend",`<style>#${this.id}::-webkit-scrollbar { display: none; }</style>`)}_initialiseCTA(){if(!this.trigger)return;let e;try{e=document.querySelector(this.trigger)||document.querySelector(".impactpop"),this.trigger&&!e&&S("No element found with trigger selector",this.trigger)}catch{S("Not a valid selector",this.trigger)}e&&(e.onclick=()=>{this.open()})}_createPopupDialog(e){var d;const n=document.createElement("dialog"),i=(d=e==null?void 0:e.widgetSize)==null?void 0:d.popupWidgets,s=i!=null&&i.minWidth?B(i.minWidth):"auto",r=i!=null&&i.maxWidth?B(i.maxWidth):"500px";n.id=this.id,n.setAttribute("style",`width: 100%; min-width: ${s}; max-width: ${r}; border: none; padding: 0;`);const a=c=>{c.stopPropagation(),c.target===n&&n.close()};return n.addEventListener("click",a),n}async load(){var m,w,f,b,x,y,L;const e=(w=(m=this.context.widgetConfig)==null?void 0:m.values)==null?void 0:w.brandingConfig,n=(e==null?void 0:e.loadingHeight)||500,i=(f=this.content)==null?void 0:f.includes("mint-components"),s=this._createFrame();s.style.height=n+"px",this._initialiseCTA();const r=this.container?this._findElement():document.body,a=(r==null?void 0:r.shadowRoot)||r,d=this._createPopupDialog(e);d.appendChild(s),((b=a.lastChild)==null?void 0:b.nodeName)==="DIALOG"?a.replaceChild(d,a.lastChild):a.appendChild(d);const{contentWindow:c}=s;if(!c)throw new Error("Frame needs a content window");const h=c.document;h.open();const p=this.widgetApi.domain;h.write(`\n ${(x=e==null?void 0:e.main)!=null&&x.brandFont?`\n <link rel="preconnect" href="https://fast${p==="https://staging.referralsaasquatch.com"?"-staging":""}.ssqt.io">\n <link rel="preconnect" href="https://fonts.gstatic.com">\n <link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent((y=e==null?void 0:e.main)==null?void 0:y.brandFont)}" as="style">`:""}\n <link rel="dns-prefetch" href="https://res.cloudinary.com">\n <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>\n ${i?`\n <style data-styles>\n html { visibility: hidden; }\n </style>`:""}\n ${this._getSkeletonPreloadHTML(i,(L=e==null?void 0:e.color)==null?void 0:L.backgroundColor)}\n ${this.content}\n <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>\n `),h.close(),S("Popup template loaded into iframe"),await this._setupResizeHandler(s)}async _setupResizeHandler(e){const{contentWindow:n}=e;if(!n)throw new Error("Frame needs a content window");const i=n.document;ne(i,(async()=>{i.body.style.overflowY="hidden";let s=!0;new n.ResizeObserver((a=>{for(const d of a){const{top:c,bottom:h}=d.contentRect,p=h+c;p<=0||(s?(s=!1,e.style.height="0",e.height=i.body.scrollHeight+"",e.style.height=""):e.height=p+"",d.target.style="")}})).observe(await this._findInnerContainer(e))}))}open(){const e=this.container?this._findElement():document.body,i=(e.shadowRoot||e).querySelector(`#${this.id}`);if(!i)throw new Error("Could not determine container div");i.showModal();const s=this._findFrame();if(!s)throw new Error("Could not find iframe");const{contentWindow:r}=s;if(!r)throw new Error("Squatch.js has an empty iframe");const a=r.document;ne(a,(()=>{var c;const d=r.squatch||r.widgetIdent;(c=s.contentDocument)==null||c.dispatchEvent(new CustomEvent("sq:refresh")),this.context.user?(this._loadEvent(d),S("Popup opened")):this._attachLoadEventListener(a,d)}))}close(){const e=this._findFrame();e!=null&&e.contentDocument&&this._detachLoadEventListener(e.contentDocument);const n=this.container?this._findElement():document.body,s=(n.shadowRoot||n).querySelector(`#${this.id}`);if(!s)throw new Error("Could not determine container div");s.close(),S("Popup closed")}_clickedOutside({target:e}){}_error(e,n="modal",i=""){return super._error(e,n,i||"body { margin: 0; } .modal { box-shadow: none; border: 0; }")}}const k=E("squatch-js:widgets");class R{constructor(t){l(this,"api");l(this,"tenantAlias");l(this,"domain");l(this,"npmCdn");const e=W(t);this.tenantAlias=e.tenantAlias,this.domain=e.domain,this.npmCdn=e.npmCdn,this.api=new F(e)}async upsertUser(t){const n=se(t);try{const i=await this.api.upsertUser(n);return{widget:this._renderWidget(i,n,{type:"upsert",user:n.user,engagementMedium:t.engagementMedium,container:t.container,trigger:t.trigger,widgetConfig:{values:{brandingConfig:i==null?void 0:i.brandingConfig}}}),user:i.user}}catch(i){throw console.log("[DEBUG] Widgets.upsertUser catch - err:",i),console.log("[DEBUG] Widgets.upsertUser catch - typeof err:",typeof i),console.log("[DEBUG] Widgets.upsertUser catch - err.apiErrorCode:",i.apiErrorCode),console.log("[DEBUG] Widgets.upsertUser catch - err keys:",Object.keys(i||{})),k(i),i.apiErrorCode&&(console.log("[DEBUG] Widgets.upsertUser - calling _renderErrorWidget"),this._renderErrorWidget(i,t.engagementMedium)),new Error(i)}}async render(t){const n=re(t);try{const i=await this.api.render(n);return{widget:this._renderWidget(i,n,{type:"passwordless",engagementMedium:n.engagementMedium,container:n.container,trigger:n.trigger,widgetConfig:i==null?void 0:i.widgetConfig}),user:i.user}}catch(i){throw i.apiErrorCode&&this._renderErrorWidget(i,n.engagementMedium),new Error(i)}}async autofill(t){const e=t;if(typeof e=="function"){try{const s=await this.api.squatchReferralCookie();e(s)}catch(s){throw k("Autofill error",s),new Error(s)}return}if(typeof e!="string")throw new Error("Autofill accepts a string or function");let n=document.querySelectorAll(e),i;if(n.length>0)i=n[0];else throw k("Element id/class or function missing"),new Error("Element id/class or function missing");try{const s=await this.api.squatchReferralCookie();i.value=s.codes[0]}catch(s){throw new Error(s)}}_renderWidget(t,e,n){var d;if(k("Rendering Widget..."),!t)throw new Error("Unable to get a response");let i,s=!!e.displayOnLoad;const r=t.jsOptions||{},a={content:t.template,type:e.widgetType||((d=r.widget)==null?void 0:d.defaultWidgetType),api:this.api,domain:this.domain,npmCdn:this.npmCdn,context:n};return r.widgetUrlMappings&&r.widgetUrlMappings.forEach((c=>{var h,p;R._matchesUrl(c.url)&&(c.widgetType!=="CONVERSION_WIDGET"||(p=(h=t.user)==null?void 0:h.referredBy)!=null&&p.code?(s=c.displayOnLoad,k(`Display ${c.widgetType} on ${c.url}`)):k(`Don't display ${c.widgetType} when no referral on widget rule match ${c.url}`))})),r.fuelTankAutofillUrls&&(k("We found a fuel tank autofill!"),r.fuelTankAutofillUrls.forEach((({url:c,formSelector:h})=>{var p,m,w;if(R._matchesUrl(c)&&(k("Fuel Tank URL matches"),(m=(p=t.user)==null?void 0:p.referredBy)!=null&&m.code)){const f=document.querySelector(h);f?f.value=((w=t.user.referredBy.referredReward)==null?void 0:w.fuelTankCode)||"":k(new Error(`Element with id/class ${h} was not found.`))}}))),e.engagementMedium==="EMBED"?i=this._renderEmbedWidget(a):(i=this._renderPopupWidget(a),s&&i.open()),i}_renderPopupWidget(t){const e=new q(t,t.context.trigger);return e.load(),e}_renderEmbedWidget(t){const e=new U(t,t.context.container);return e.load(),e}_renderErrorWidget(t,e="POPUP"){const{apiErrorCode:n,rsCode:i,statusCode:s,message:r}=t;k(new Error(`${n} (${i}) ${r}`));const a={content:"error",rsCode:i,apiErrorCode:n,statusCode:s,errorMessage:r,api:this.api,domain:this.domain,npmCdn:this.npmCdn,type:"ERROR_WIDGET",context:{type:"error"}};let d;e==="EMBED"?(d=new U(a),d.load()):e==="POPUP"&&(d=new q(a),d.load())}static _matchesUrl(t){return!!window.location.href.match(new RegExp(t))}}class Re{constructor(t){l(this,"tenantAlias");l(this,"domain");const n=W(t);this.tenantAlias=n.tenantAlias,this.domain=n.domain}track(t,e){const n=t,i=e,s=Pe(n),{jwt:r}=Me(i),a=encodeURIComponent(this.tenantAlias),d=encodeURIComponent(s.userId),c=encodeURIComponent(s.accountId),h=`/api/v1/${a}/open/account/${c}/user/${d}/events`,p=this.domain+h;return te(p,JSON.stringify(s),r)}}function Pe(o){if(!_(o))throw new Error("tracking parameter must be an object");if(!(o!=null&&o.accountId))throw new Error("accountId field is required");if(!(o!=null&&o.events))throw new Error("events field is required");if(!(o!=null&&o.userId))throw new Error("userId field is required");const t=o;if(!Array.isArray(t.events))throw new Error("'events' should be an array");return t}function Me(o){if(!_(o))throw new Error("'options' should be an object");return o}function Le(){var i;const o=window[Z]?Z:j,t=((i=window["_"+o])==null?void 0:i.ready)||[],e=window.impactOnReady||window.squatchOnReady,n=[...t,e].filter((s=>!!s));setTimeout((()=>{window[j]&&(window[Z]=window[j],n.forEach((s=>s())),window[j]._auto(),window["_"+o]=void 0,delete window["_"+o])}),0)}const C=E("squatch-js"),le=o=>typeof o=="object"&&!Array.isArray(o),he=(o,t)=>{const e=i=>le(t[i])&&o.hasOwnProperty(i)&&le(o[i]),n=Object.getOwnPropertyNames(t).map((i=>({[i]:e(i)?he(o[i],t[i]):t[i]}))).reduce(((i,s)=>({...i,...s})),{});return{...o,...n}};function G(o){const t=atob(o.replace(/_/g,"/").replace(/-/g,"+")),e=new Uint8Array(t.length);for(let n=0;n<t.length;n++)e[n]=t.charCodeAt(n);return new TextDecoder("utf8").decode(e)}function ue(o){const t=(new TextEncoder).encode(o),e=Array.from(t,(n=>String.fromCodePoint(n))).join("");return btoa(e).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function Oe(){var o,t,e="weird_get_top_level_domain=cookie",n=document.location.hostname.split(".");for(o=n.length-1;o>=0;o--)if(t=n.slice(o).join("."),document.cookie=e+";domain=."+t+";",document.cookie.indexOf(e)>-1)return document.cookie=e.split("=")[0]+"=;domain=."+t+";expires=Thu, 01 Jan 1970 00:00:01 GMT;",t}function De(){const o=window.location.search,e=new URLSearchParams(o).get("_saasquatch")||"";if(e){let n="",i="",s="";try{n=JSON.parse(G(e))}catch(r){C("Unable to decode params",r);return}try{i=JSON.parse(G(D.get("_saasquatch"))),C("existing cookie",i)}catch(r){C("Unable to retrieve cookie",r)}try{const r=Oe();if(C("domain retrieved:",r),i){const a=he(i,n);s=ue(JSON.stringify(a)),C("cookie to store:",a)}else s=ue(JSON.stringify(n)),C("cookie to store:",n);D.set("_saasquatch",s,{expires:365,secure:!1,sameSite:"Lax",domain:r,path:"/"})}catch(r){C("Unable to set cookie",r)}}}const J=E("squatch-js");function je(){var p;const o=window.location.search,e=new URLSearchParams(o).get("_saasquatchExtra")||"";if(!e){J("No _saasquatchExtra param");return}const n=W({tenantAlias:"UNKNOWN"});if(!n.domain){J("domain must be provided in config to use _saasquatchExtra");return}let i;try{i=JSON.parse(G(e))}catch{J("Unable to decode _saasquatchExtra config");return}function s(m){return m.replace(/^https?:\/\//,"")}const r=s(n.domain),a=Object.keys((i==null?void 0:i[r])||{})[0],d=(p=i==null?void 0:i[r])==null?void 0:p[a];if(!d){J("_saasquatchExtra did not have an expected structure");return}const{autoPopupWidgetType:c,...h}=d;return{widgetConfig:{widgetType:c,displayOnLoad:!0,...h},squatchConfig:{...n,tenantAlias:a}}}const Ne=E("squatch-js:decodeUserJwt");function Fe(o){var t;try{const e=o.split(".")[1];if(e===void 0)return null;const n=G(e);return(t=JSON.parse(n))==null?void 0:t.user}catch(e){return Ne(e),null}}const pe=E("squatch-js:DeclarativeWidget");class ge extends HTMLElement{constructor(){super();l(this,"config");l(this,"token");l(this,"tenant");l(this,"widgetType");l(this,"locale");l(this,"widgetApi");l(this,"analyticsApi");l(this,"widgetInstance");l(this,"type");l(this,"container");l(this,"element");l(this,"loaded");l(this,"_setWidget",((e,n)=>{var s;const i={api:this.widgetApi,content:e.template,context:{type:n.type,user:n.user,container:this.container||void 0,engagementMedium:this.type,widgetConfig:e.widgetConfig},type:this.widgetType,domain:((s=this.config)==null?void 0:s.domain)||I,npmCdn:K,container:this};if(this.type==="EMBED")return new U(i);{const r=this.firstChild?null:void 0;return new q(i,r)}}));l(this,"setErrorWidget",(e=>{var d;const n=e instanceof Error?e.message:e==null?void 0:e.message,i=e instanceof Error||e==null?void 0:e.apiErrorCode,s=e instanceof Error||e==null?void 0:e.rsCode,r=e instanceof Error||e==null?void 0:e.statusCode,a={api:this.widgetApi,content:"error",context:{type:"error",container:this.container||void 0},type:"ERROR_WIDGET",domain:((d=this.config)==null?void 0:d.domain)||I,npmCdn:K,container:this,apiErrorCode:i,rsCode:s,statusCode:r,errorMessage:n};if(this.type==="EMBED")return new U(a);{const c=this.firstChild?null:void 0;return new q(a,c)}}));l(this,"reload",this.renderWidget);l(this,"show",this.open);l(this,"hide",this.close);this.attachShadow({mode:"open"}).innerHTML="<style>:host { display: block; }</style><slot></slot>",this.config=ee(),this.token=$(),this.tenant=window.squatchTenant,this.container=this}_setupApis(e){var n,i;if(!this.tenant)throw new Error("tenantAlias not provided");this.widgetApi=new F({tenantAlias:(e==null?void 0:e.tenantAlias)||this.tenant,domain:(e==null?void 0:e.domain)||((n=this.config)==null?void 0:n.domain)||I}),this.analyticsApi=new ae({domain:(e==null?void 0:e.domain)||((i=this.config)==null?void 0:i.domain)||I})}getWidgetType(e){return e&&(e.includes("websiteReferralWidget")||e.includes("friendWidget"))?"instant-access":"verified-access"}async renderPasswordlessVariant(){return this._setupApis(),pe("Rendering as an Instant Access widget"),await this.widgetApi.render({engagementMedium:this.type,widgetType:this.widgetType,locale:this.locale}).then((e=>this._setWidget(e,{type:"passwordless"}))).catch(this.setErrorWidget)}async renderUserUpsertVariant(){this._setupApis();const e=Fe(this.token);if(!e)return this.setErrorWidget(Error("No user object in token."));pe("Rendering as a Verified widget");try{await this.widgetApi.upsertUser({user:e,locale:this.locale,engagementMedium:this.type,widgetType:this.widgetType,jwt:this.token})}catch(i){return this.setErrorWidget(i)}return await this.widgetApi.render({locale:this.locale,engagementMedium:this.type,widgetType:this.widgetType}).then((i=>this._setWidget(i,{type:"upsert",user:e}))).catch(this.setErrorWidget)}async getWidgetInstance(){let e;this.widgetType=this.getAttribute("widget")||void 0,this.locale=this.getAttribute("locale")||this.locale;const n=this.getWidgetType(this.widgetType);if(!this.widgetType)throw new Error("No widget has been specified");return!this.token&&n==="verified-access"?this.setErrorWidget(Error("A valid token is required to render this widget.")):(n==="instant-access"?e=await this.renderPasswordlessVariant():e=await this.renderUserUpsertVariant(),this.widgetInstance=e,this.widgetInstance&&this.dispatchEvent(new CustomEvent("sq:widget-loaded")),e)}async renderWidget(){await this.getWidgetInstance(),await this.widgetInstance.load()}open(){if(!this.widgetInstance)throw new Error("Widget has not loaded yet");this.widgetInstance.open()}close(){if(!this.widgetInstance)throw new Error("Widget has not loaded yet");this.widgetInstance.close()}static get observedAttributes(){return["widget","locale"]}attributeChangedCallback(e,n,i){if(!(n===i||!this.loaded))switch(e){case"locale":case"widget":this.connectedCallback();break}}async connectedCallback(){this.loaded=!0,this.container=this.getAttribute("container"),this.widgetType=this.getAttribute("widget")||void 0;const e=this.getWidgetType(this.widgetType),{getSkeleton:n}=await Promise.resolve().then((()=>Ue)),i=n({height:"100%",type:e}),s=document.createElement("div");s.id="loading-skeleton",s.innerHTML=i;const r=this.shadowRoot||this.attachShadow({mode:"open"});if(this.type==="POPUP"){const d=r.getElementById("#squatchModal");d&&(d.innerHTML="",d.appendChild(s))}else r.innerHTML="",r.appendChild(s);await this.renderWidget();const a=r.getElementById("loading-skeleton");a&&a.remove(),this.getAttribute("open")!==null&&this.open()}}class ie extends ge{constructor(){super(),this.type="EMBED",this.loaded=!1}}class oe extends ge{constructor(){super(),this.type="POPUP",this.loaded=!1,this.addEventListener("click",(t=>{t.stopPropagation(),this.open()}))}}class Be extends ie{}class He extends oe{}class Ge extends ie{}class Je extends oe{}window.customElements.get("squatch-embed")||window.customElements.define("squatch-embed",Be),window.customElements.get("impact-embed")||window.customElements.define("impact-embed",Ge),window.customElements.get("squatch-popup")||window.customElements.define("squatch-popup",He),window.customElements.get("impact-popup")||window.customElements.define("impact-popup",Je);function ze(){console.log("Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.")}const P=E("squatch-js");let z=null,V=null,X=null;function Ve(){return z||M({}),z}function Q(){return V||M({}),V}function Xe(){return X||M({}),X}function Qe(o){var t;return(t=Q())==null?void 0:t.render(o)}function Ye(){var t;const o=je();if(o){const{squatchConfig:e,widgetConfig:n}=o;return M(e),(t=Q())==null?void 0:t.render(n)}}function M(o){const e=W(o);e.tenantAlias.match("^test")||e.debug?A("squatch-js*"):Ee(),P("initializing ..."),z=new F(e),V=new R(e),X=new Re(e),P("Widget API instance",z),P("Widgets instance",V),P("Events API instance",X)}function Ke(o){o()}function Ze(o){Q().autofill(o)}function me(){De()}typeof document<"u"&&!window.SaaSquatchDoNotAutoDrop&&me(),(fe=window.squatch)!=null&&fe.init&&P("Squatchjs is being loaded more than once. This may lead to multiple load events being sent, duplicated widgets, and inaccurate analytics."),typeof document<"u"&&Le(),u.DeclarativeEmbedWidget=ie,u.DeclarativePopupWidget=oe,u.EmbedWidget=U,u.PopupWidget=q,u.WidgetApi=F,u.Widgets=R,u._auto=Ye,u.api=Ve,u.autofill=Ze,u.events=Xe,u.help=ze,u.init=M,u.pushCookie=me,u.ready=Ke,u.widget=Qe,u.widgets=Q,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));
5
+ */}function M(o,t){let e=[],n,i=o,s=i.documentElement.doScroll,r="DOMContentLoaded",a=(s?/^loaded|^c/:/^loaded|^i|^c/).test(i.readyState);return a||i.addEventListener(r,n=()=>{for(i.removeEventListener(r,n),a=!0;n=e.shift();)n()}),a?setTimeout(t,0):e.push(t)}function H({value:o,unit:t}){switch(t){case"px":return`${o}px`;case"%":return`${o}%`;default:return`${o}px`}}class le{constructor(t){l(this,"domain");var i;const n=We(t);this.domain=(n==null?void 0:n.domain)||((i=ee())==null?void 0:i.domain)||A}pushAnalyticsLoadEvent(t){if(!t.externalUserId||!t.externalAccountId)return;const e=window.location.search,n=new URLSearchParams(e),i=n==null?void 0:n.get("rsShareMedium"),s=encodeURIComponent(t.tenantAlias),r=encodeURIComponent(t.externalAccountId),a=encodeURIComponent(t.externalUserId),d=encodeURIComponent(t.engagementMedium),c=t.programId?`&programId=${encodeURIComponent(t.programId)}`:"",h=i?`&shareMedium=${encodeURIComponent(i)}`:"",u=`/a/${s}/widgets/analytics/loaded?externalAccountId=${r}&externalUserId=${a}&engagementMedium=${d}${h}${c}`,m=this.domain+u;return te(m,JSON.stringify({}))}pushAnalyticsShareClickedEvent(t){const e=encodeURIComponent(t.tenantAlias),n=encodeURIComponent(t.externalAccountId),i=encodeURIComponent(t.externalUserId),s=encodeURIComponent(t.engagementMedium),r=encodeURIComponent(t.shareMedium),a=`/a/${e}/widgets/analytics/shared?externalAccountId=${n}&externalUserId=${i}&engagementMedium=${s}&shareMedium=${r}`,d=this.domain+a;return te(d,JSON.stringify({}))}}function We(o){if(!_(o))throw new Error("'options' should be an object");return o}const b=v("squatch-js:widget");class he{constructor(t){l(this,"type");l(this,"content");l(this,"analyticsApi");l(this,"widgetApi");l(this,"context");l(this,"npmCdn");l(this,"container");l(this,"loadEventListener",null);l(this,"errorInfo");var e;b("widget initializing ..."),t.content==="error"?(this.content="error",this.errorInfo={rsCode:t.rsCode,apiErrorCode:t.apiErrorCode,statusCode:t.statusCode,message:t.errorMessage}):this.content=t.content,this.type=t.type,this.widgetApi=t.api,this.npmCdn=t.npmCdn,this.analyticsApi=new le({domain:t.domain}),this.context=t.context,this.container=((e=t.context)==null?void 0:e.container)||t.container}async _getContent(){if(this.content==="error"&&this.errorInfo){const{getErrorTemplate:t}=await Promise.resolve().then((()=>Ke));return t({rsCode:this.errorInfo.rsCode,apiErrorCode:this.errorInfo.apiErrorCode,statusCode:this.errorInfo.statusCode,mode:this._getErrorMode(),style:this._getErrorStyle(),message:this.errorInfo.message})}return this.content}_getErrorMode(){return"modal"}_getErrorStyle(){return""}_findElement(){let t;if(typeof this.container=="string"?(t=document.querySelector(this.container),b("loading widget with selector",t)):this.container instanceof HTMLElement?(t=this.container,b("loading widget with container",t)):this.container?(t=null,b("container must be an HTMLElement or string",this.container)):(t=document.querySelector("#squatchembed")||document.querySelector(".squatchembed")||document.querySelector("#impactembed")||document.querySelector(".impactembed"),b("loading widget with default selector",t)),!(t instanceof HTMLElement))throw new Error(`element with selector '${this.container||"#squatchembed, .squatchembed, #impactembed, or .impactembed"}' not found.'`);return t}_createFrame(t){const e=document.createElement("iframe");return e.squatchJsApi=this,e.id="squatchFrame",e.width="100%",e.src="about:blank",e.scrolling="no",e.setAttribute("style","border: 0; background-color: none; width: 1px; min-width: 100%; display: block;"),t!=null&&t.minWidth&&(e.style.minWidth=t.minWidth),t!=null&&t.maxWidth&&(e.style.maxWidth=t.maxWidth),(t!=null&&t.maxWidth||t!=null&&t.minWidth)&&(e.style.width="100%"),t!=null&&t.initialHeight&&(e.height=String(t.initialHeight)),e}_findFrame(){const t=this.container?this._findElement():document.body;return(t.shadowRoot||t).querySelector("iframe#squatchFrame")}_detachLoadEventListener(t){this.loadEventListener&&(t.removeEventListener("sq:user-registration",this.loadEventListener),this.loadEventListener=null)}_attachLoadEventListener(t,e){this.loadEventListener===null&&(this.loadEventListener=n=>{this._loadEvent({...e,userId:n.detail.userId,accountId:n.detail.accountId})},t.addEventListener("sq:user-registration",this.loadEventListener))}_loadEvent(t){var n;if(!t)return;if(!_(t))throw new Error("Widget Load event identity property is not an object");let e;if("programId"in t){if(!t.tenantAlias||!t.accountId||!t.userId||!t.engagementMedium)throw new Error("Widget Load event missing required properties");e={tenantAlias:t.tenantAlias,externalAccountId:t.accountId,externalUserId:t.userId,engagementMedium:t.engagementMedium,programId:t.programId}}else{const{analytics:i,mode:s}=t;e={tenantAlias:i.attributes.tenant,externalAccountId:i.attributes.accountId,externalUserId:i.attributes.userId,engagementMedium:s.widgetMode}}(n=this.analyticsApi.pushAnalyticsLoadEvent(e))==null||n.then((i=>{b(`${e.engagementMedium} loaded event recorded.`)})).catch((i=>{b(`ERROR: pushAnalyticsLoadEvent() ${i}`)}))}_shareEvent(t,e){t&&this.analyticsApi.pushAnalyticsShareClickedEvent({tenantAlias:t.analytics.attributes.tenant,externalAccountId:t.analytics.attributes.accountId,externalUserId:t.analytics.attributes.userId,engagementMedium:t.mode.widgetMode,shareMedium:e}).then((n=>{b(`${t.mode.widgetMode} share ${e} event recorded. ${n}`)})).catch((n=>{b(`ERROR: pushAnalyticsShareClickedEvent() ${n}`)}))}async _findInnerContainer(t){const{contentWindow:e}=t;if(!e)throw new Error("Squatch.js frame inner frame is empty");const n=e.document;function i(){const r=n.getElementsByTagName("sqh-global-container"),a=n.getElementsByClassName("squatch-container");return r.length>0?r[0]:a.length>0?a[0]:null}let s=null;for(let r=0;r<5&&(s=i(),!s);r++)await Me(100);return s||n.body}async _getSkeletonPreloadHTML(t,e){if(!t)return"";const{getSkeleton:n}=await Promise.resolve().then((()=>pe)),i=this.context.type==="passwordless"?"instant-access":"verified-access",s=n({type:i}),r=new Set,a=/<([a-z][\w]*-[\w-]*)/gi;let d;for(;d=a.exec(this.content);)r.add(d[1].toLowerCase());const c=JSON.stringify([...r]);return`\n <div id="sq-preload" style="visibility: visible; position: absolute; top: 0; left: 0; width: 100%; z-index: 9999; background: ${(e||"white").replace(/[^a-zA-Z0-9#(),.\s%-]/g,"")};">\n ${s}\n </div>\n <script>(${qe.toString()})(${c})<\/script>\n `}reload({email:t,firstName:e,lastName:n},i){const s=this._findFrame();if(!s)throw new Error("Could not find widget iframe");const r=s.contentWindow,a=this.context.engagementMedium||"POPUP";if(!r)throw new Error("Frame needs a content window");let d;if(this.context.type==="upsert"){if(!this.context.user)throw new Error("Can't reload without user ids");let c={email:t||null,firstName:e||null,lastName:n||null,id:this.context.user.id,accountId:this.context.user.accountId};d=this.widgetApi.upsertUser({user:c,engagementMedium:a,widgetType:this.type,jwt:i})}else if(this.context.type==="passwordless")d=this.widgetApi.render({user:void 0,engagementMedium:a,widgetType:this.type,jwt:void 0});else throw new Error("can't reload an error widget");d.then((({template:c})=>{c&&(this.content=c,this.__deprecated__register(s,{email:t,engagementMedium:a},(()=>{this.load(),a==="POPUP"&&this.open()})))})).catch((({message:c})=>{b(`${c}`)}))}__deprecated__register(t,e,n){const s=t.contentWindow.document,r=s.createElement("button"),a=s.getElementsByClassName("squatch-register")[0];if(a){r.className="btn btn-primary",r.id="show-stats-btn",r.textContent=this.type==="REFERRER_WIDGET"?"Show Stats":"Show Reward";const d=e.engagementMedium==="POPUP"?"margin-top: 10px; max-width: 130px; width: 100%;":"margin-top: 10px;";r.setAttribute("style",d),r.onclick=n,a.style.paddingTop="30px",a.innerHTML=`<p><strong>${e.email}</strong><br>Has been successfully registered</p>`,a.appendChild(r)}}}function Me(o){return new Promise((t=>{setTimeout(t,o)}))}function qe(o){var t=setTimeout(e,1e4);function e(){var i=document.getElementById("sq-preload");i&&i.remove(),clearTimeout(t)}function n(){if(!o||!o.length)return e();Promise.all(o.map((function(i){return customElements.whenDefined(i)}))).then((function(){requestAnimationFrame((function(){requestAnimationFrame(e)}))}))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",n):setTimeout(n,0)}const T=v("squatch-js:EMBEDwidget");class q extends he{constructor(e,n){super(e);l(this,"show",this.open);l(this,"hide",this.close);n&&(this.container=n)}async load(){var f,E,x,y,O,fe,we,ye,ve;const e=(E=(f=this.context.widgetConfig)==null?void 0:f.values)==null?void 0:E.brandingConfig,n=(x=this.content)==null?void 0:x.includes("mint-components"),i=(e==null?void 0:e.loadingHeight)||500,s=(y=e==null?void 0:e.widgetSize)==null?void 0:y.embeddedWidgets,r=s!=null&&s.maxWidth?H(s.maxWidth):"",a=s!=null&&s.minWidth?H(s.minWidth):"",d=this._createFrame({minWidth:a,maxWidth:r,initialHeight:i}),c=this._findElement();(O=this.context)!=null&&O.container&&(c.style.visibility="hidden",c.style.height="0",c.style["overflow-y"]="hidden"),this.container?c.shadowRoot?((fe=c.shadowRoot.lastChild)==null?void 0:fe.nodeName)==="IFRAME"?c.shadowRoot.replaceChild(d,c.shadowRoot.lastChild):c.shadowRoot.appendChild(d):c.firstChild?c.replaceChild(d,c.firstChild):c.appendChild(d):(!c.firstChild||c.firstChild.nodeName==="#text")&&c.appendChild(d);const{contentWindow:h}=d;if(!h)throw new Error("Frame needs a content window");const u=h.document;if(u.open(),this.content==="error"){u.write(await this._getContent()),u.close(),M(u,(()=>{d.height=u.body.scrollHeight}));return}const w=this.widgetApi.domain==="https://staging.referralsaasquatch.com"?"-staging":"";u.write(`\n ${(we=e==null?void 0:e.main)!=null&&we.brandFont?`\n <link rel="preconnect" href="https://fast${w}.ssqt.io">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>\n <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent((ye=e==null?void 0:e.main)==null?void 0:ye.brandFont)}" as="style">`:""}\n <link rel="dns-prefetch" href="https://res.cloudinary.com">\n <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>\n ${n?`\n <style data-styles>\n html { visibility: hidden; }\n </style>`:""}\n ${await this._getSkeletonPreloadHTML(n,(ve=e==null?void 0:e.color)==null?void 0:ve.backgroundColor)}\n ${await this._getContent()}\n `),u.close(),M(u,(async()=>{const be=h.squatch||h.widgetIdent;d.height=i;const et=new h.ResizeObserver((nt=>{for(const it of nt){const{height:ot}=it.contentRect;d.height=ot}})),tt=await this._findInnerContainer(d);et.observe(tt),this._shouldFireLoadEvent()?(this._loadEvent(be),T("loaded")):u&&this._attachLoadEventListener(u,be)}))}open(){const e=this._findFrame();if(!e)return T("no target element to open");if(!e.contentWindow)return T("Frame needs a content window");const n=this._findElement();n.style.visibility="unset",n.style.height="auto",n.style["overflow-y"]="auto",e.contentWindow.document.dispatchEvent(new CustomEvent("sq:refresh"));const i=e.contentWindow.squatch||e.contentWindow.widgetIdent;if(this.context.user)this._loadEvent(i),T("loaded");else{if(!e.contentDocument)return;this._attachLoadEventListener(e.contentDocument,i)}}close(){const e=this._findFrame();if(!e)return T("no target element to close");e.contentDocument&&this._detachLoadEventListener(e.contentDocument);const n=this._findElement();n.style.visibility="hidden",n.style.height="0",n.style["overflow-y"]="hidden",T("Embed widget closed")}_getErrorMode(){return"embed"}_shouldFireLoadEvent(){const e=!this.container,n=this.container instanceof HTMLElement&&(this.container.tagName.startsWith("SQUATCH-")||this.container.tagName.startsWith("IMPACT-"));return!!this.context.user&&(e||n)}}const S=v("squatch-js:POPUPwidget");let J=0;class P extends he{constructor(e,n=".squatchpop"){super(e);l(this,"trigger");l(this,"id");l(this,"show",this.open);l(this,"hide",this.close);this.trigger=n,this.container?this.id="squatchModal":(this.id=J===0?"squatchModal":`squatchModal__${J}`,J=J+1),document.head.insertAdjacentHTML("beforeend",`<style>#${this.id}::-webkit-scrollbar { display: none; }</style>`)}_initialiseCTA(){if(!this.trigger)return;let e;try{e=document.querySelector(this.trigger)||document.querySelector(".impactpop"),this.trigger&&!e&&S("No element found with trigger selector",this.trigger)}catch{S("Not a valid selector",this.trigger)}e&&(e.onclick=()=>{this.open()})}_createPopupDialog(e){var d;const n=document.createElement("dialog"),i=(d=e==null?void 0:e.widgetSize)==null?void 0:d.popupWidgets,s=i!=null&&i.minWidth?H(i.minWidth):"auto",r=i!=null&&i.maxWidth?H(i.maxWidth):"500px";n.id=this.id,n.setAttribute("style",`width: 100%; min-width: ${s}; max-width: ${r}; border: none; padding: 0;`);const a=c=>{c.stopPropagation(),c.target===n&&n.close()};return n.addEventListener("click",a),n}async load(){var m,w,f,E,x,y,O;const e=(w=(m=this.context.widgetConfig)==null?void 0:m.values)==null?void 0:w.brandingConfig,n=(e==null?void 0:e.loadingHeight)||500,i=(f=this.content)==null?void 0:f.includes("mint-components"),s=this._createFrame();s.style.height=n+"px",this._initialiseCTA();const r=this.container?this._findElement():document.body,a=(r==null?void 0:r.shadowRoot)||r,d=this._createPopupDialog(e);d.appendChild(s),((E=a.lastChild)==null?void 0:E.nodeName)==="DIALOG"?a.replaceChild(d,a.lastChild):a.appendChild(d);const{contentWindow:c}=s;if(!c)throw new Error("Frame needs a content window");const h=c.document;if(h.open(),this.content==="error"){h.write(await this._getContent()),h.close(),M(h,(()=>{s.height=h.body.scrollHeight})),S("Popup error template loaded into iframe");return}const u=this.widgetApi.domain;h.write(`\n ${(x=e==null?void 0:e.main)!=null&&x.brandFont?`\n <link rel="preconnect" href="https://fast${u==="https://staging.referralsaasquatch.com"?"-staging":""}.ssqt.io">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent((y=e==null?void 0:e.main)==null?void 0:y.brandFont)}" as="style">`:""}\n <link rel="dns-prefetch" href="https://res.cloudinary.com">\n <link rel="preconnect" href="https://res.cloudinary.com" crossorigin>\n ${i?`\n <style data-styles>\n html { visibility: hidden; }\n </style>`:""}\n ${await this._getSkeletonPreloadHTML(i,(O=e==null?void 0:e.color)==null?void 0:O.backgroundColor)}\n ${await this._getContent()}\n `),h.close(),S("Popup template loaded into iframe"),await this._setupResizeHandler(s)}async _setupResizeHandler(e){const{contentWindow:n}=e;if(!n)throw new Error("Frame needs a content window");const i=n.document;M(i,(async()=>{i.body.style.overflowY="hidden";let s=!0;new n.ResizeObserver((a=>{for(const d of a){const{top:c,bottom:h}=d.contentRect,u=h+c;u<=0||(s?(s=!1,e.style.height="0",e.height=i.body.scrollHeight+"",e.style.height=""):e.height=u+"",d.target.style="")}})).observe(await this._findInnerContainer(e))}))}open(){const e=this.container?this._findElement():document.body,i=(e.shadowRoot||e).querySelector(`#${this.id}`);if(!i)throw new Error("Could not determine container div");i.showModal();const s=this._findFrame();if(!s)throw new Error("Could not find iframe");const{contentWindow:r}=s;if(!r)throw new Error("Squatch.js has an empty iframe");const a=r.document;M(a,(()=>{var c;const d=r.squatch||r.widgetIdent;(c=s.contentDocument)==null||c.dispatchEvent(new CustomEvent("sq:refresh")),this.context.user?(this._loadEvent(d),S("Popup opened")):this._attachLoadEventListener(a,d)}))}close(){const e=this._findFrame();e!=null&&e.contentDocument&&this._detachLoadEventListener(e.contentDocument);const n=this.container?this._findElement():document.body,s=(n.shadowRoot||n).querySelector(`#${this.id}`);if(!s)throw new Error("Could not determine container div");s.close(),S("Popup closed")}_getErrorStyle(){return"body { margin: 0; } .modal { box-shadow: none; border: 0; }"}}const k=v("squatch-js:widgets");class R{constructor(t){l(this,"api");l(this,"tenantAlias");l(this,"domain");l(this,"npmCdn");const e=$(t);this.tenantAlias=e.tenantAlias,this.domain=e.domain,this.npmCdn=e.npmCdn,this.api=new F(e)}async upsertUser(t){const n=ae(t);try{const i=await this.api.upsertUser(n);return{widget:this._renderWidget(i,n,{type:"upsert",user:n.user,engagementMedium:t.engagementMedium,container:t.container,trigger:t.trigger,widgetConfig:{values:{brandingConfig:i==null?void 0:i.brandingConfig}}}),user:i.user}}catch(i){throw k(i),i.apiErrorCode&&this._renderErrorWidget(i,t.engagementMedium),new Error(i)}}async render(t){const n=de(t);try{const i=await this.api.render(n);return{widget:this._renderWidget(i,n,{type:"passwordless",engagementMedium:n.engagementMedium,container:n.container,trigger:n.trigger,widgetConfig:i==null?void 0:i.widgetConfig}),user:i.user}}catch(i){throw i.apiErrorCode&&this._renderErrorWidget(i,n.engagementMedium),new Error(i)}}async autofill(t){const e=t;if(typeof e=="function"){try{const s=await this.api.squatchReferralCookie();e(s)}catch(s){throw k("Autofill error",s),new Error(s)}return}if(typeof e!="string")throw new Error("Autofill accepts a string or function");let n=document.querySelectorAll(e),i;if(n.length>0)i=n[0];else throw k("Element id/class or function missing"),new Error("Element id/class or function missing");try{const s=await this.api.squatchReferralCookie();i.value=s.codes[0]}catch(s){throw new Error(s)}}_renderWidget(t,e,n){var d;if(k("Rendering Widget..."),!t)throw new Error("Unable to get a response");let i,s=!!e.displayOnLoad;const r=t.jsOptions||{},a={content:t.template,type:e.widgetType||((d=r.widget)==null?void 0:d.defaultWidgetType),api:this.api,domain:this.domain,npmCdn:this.npmCdn,context:n};return r.widgetUrlMappings&&r.widgetUrlMappings.forEach((c=>{var h,u;R._matchesUrl(c.url)&&(c.widgetType!=="CONVERSION_WIDGET"||(u=(h=t.user)==null?void 0:h.referredBy)!=null&&u.code?(s=c.displayOnLoad,k(`Display ${c.widgetType} on ${c.url}`)):k(`Don't display ${c.widgetType} when no referral on widget rule match ${c.url}`))})),r.fuelTankAutofillUrls&&(k("We found a fuel tank autofill!"),r.fuelTankAutofillUrls.forEach((({url:c,formSelector:h})=>{var u,m,w;if(R._matchesUrl(c)&&(k("Fuel Tank URL matches"),(m=(u=t.user)==null?void 0:u.referredBy)!=null&&m.code)){const f=document.querySelector(h);f?f.value=((w=t.user.referredBy.referredReward)==null?void 0:w.fuelTankCode)||"":k(new Error(`Element with id/class ${h} was not found.`))}}))),e.engagementMedium==="EMBED"?i=this._renderEmbedWidget(a):(i=this._renderPopupWidget(a),s&&i.open()),i}_renderPopupWidget(t){const e=new P(t,t.context.trigger);return e.load(),e}_renderEmbedWidget(t){const e=new q(t,t.context.container);return e.load(),e}_renderErrorWidget(t,e="POPUP"){const{apiErrorCode:n,rsCode:i,statusCode:s,message:r}=t;k(new Error(`${n} (${i}) ${r}`));const a={content:"error",rsCode:i,apiErrorCode:n,statusCode:s,errorMessage:r,api:this.api,domain:this.domain,npmCdn:this.npmCdn,type:"ERROR_WIDGET",context:{type:"error"}};let d;e==="EMBED"?(d=new q(a),d.load()):e==="POPUP"&&(d=new P(a),d.load())}static _matchesUrl(t){return!!window.location.href.match(new RegExp(t))}}class Pe{constructor(t){l(this,"tenantAlias");l(this,"domain");const n=$(t);this.tenantAlias=n.tenantAlias,this.domain=n.domain}track(t,e){const n=t,i=e,s=Re(n),{jwt:r}=Ue(i),a=encodeURIComponent(this.tenantAlias),d=encodeURIComponent(s.userId),c=encodeURIComponent(s.accountId),h=`/api/v1/${a}/open/account/${c}/user/${d}/events`,u=this.domain+h;return te(u,JSON.stringify(s),r)}}function Re(o){if(!_(o))throw new Error("tracking parameter must be an object");if(!(o!=null&&o.accountId))throw new Error("accountId field is required");if(!(o!=null&&o.events))throw new Error("events field is required");if(!(o!=null&&o.userId))throw new Error("userId field is required");const t=o;if(!Array.isArray(t.events))throw new Error("'events' should be an array");return t}function Ue(o){if(!_(o))throw new Error("'options' should be an object");return o}function Le(){var i;const o=window[K]?K:D,t=((i=window["_"+o])==null?void 0:i.ready)||[],e=window.impactOnReady||window.squatchOnReady,n=[...t,e].filter((s=>!!s));setTimeout((()=>{window[D]&&(window[K]=window[D],n.forEach((s=>s())),window[D]._auto(),window["_"+o]=void 0,delete window["_"+o])}),0)}const B=v("squatch-js");function Oe(){var u;const o=window.location.search,e=new URLSearchParams(o).get("_saasquatchExtra")||"";if(!e){B("No _saasquatchExtra param");return}const n=$({tenantAlias:"UNKNOWN"});if(!n.domain){B("domain must be provided in config to use _saasquatchExtra");return}let i;try{i=JSON.parse(j(e))}catch{B("Unable to decode _saasquatchExtra config");return}function s(m){return m.replace(/^https?:\/\//,"")}const r=s(n.domain),a=Object.keys((i==null?void 0:i[r])||{})[0],d=(u=i==null?void 0:i[r])==null?void 0:u[a];if(!d){B("_saasquatchExtra did not have an expected structure");return}const{autoPopupWidgetType:c,...h}=d;return{widgetConfig:{widgetType:c,displayOnLoad:!0,...h},squatchConfig:{...n,tenantAlias:a}}}const je=v("squatch-js:decodeUserJwt");function De(o){var t;try{const e=o.split(".")[1];if(e===void 0)return null;const n=j(e);return(t=JSON.parse(n))==null?void 0:t.user}catch(e){return je(e),null}}const z=v("squatch-js:DeclarativeWidget");class ue extends HTMLElement{constructor(){super();l(this,"config");l(this,"token");l(this,"tenant");l(this,"widgetType");l(this,"locale");l(this,"widgetApi");l(this,"analyticsApi");l(this,"widgetInstance");l(this,"type");l(this,"container");l(this,"element");l(this,"loaded");l(this,"_setWidget",((e,n)=>{var s;const i={api:this.widgetApi,content:e.template,context:{type:n.type,user:n.user,container:this.container||void 0,engagementMedium:this.type,widgetConfig:e.widgetConfig},type:this.widgetType,domain:((s=this.config)==null?void 0:s.domain)||A,npmCdn:Z,container:this};if(this.type==="EMBED")return new q(i);{const r=this.firstChild?null:void 0;return new P(i,r)}}));l(this,"setErrorWidget",(e=>{var d;const n=e instanceof Error?e.message:e==null?void 0:e.message,i=e==null?void 0:e.apiErrorCode,s=e==null?void 0:e.rsCode,r=e==null?void 0:e.statusCode,a={api:this.widgetApi,content:"error",context:{type:"error",container:this.container||void 0},type:"ERROR_WIDGET",domain:((d=this.config)==null?void 0:d.domain)||A,npmCdn:Z,container:this,apiErrorCode:i,rsCode:s,statusCode:r,errorMessage:n};if(this.type==="EMBED")return new q(a);{const c=this.firstChild?null:void 0;return new P(a,c)}}));l(this,"reload",this.renderWidget);l(this,"show",this.open);l(this,"hide",this.close);this.attachShadow({mode:"open"}).innerHTML="<style>:host { display: block; }</style><slot></slot>",this.config=ee(),this.token=W(),this.tenant=window.squatchTenant,this.container=this}_setupApis(e){var n,i;if(!this.tenant)throw new Error("tenantAlias not provided");this.widgetApi=new F({tenantAlias:(e==null?void 0:e.tenantAlias)||this.tenant,domain:(e==null?void 0:e.domain)||((n=this.config)==null?void 0:n.domain)||A}),this.analyticsApi=new le({domain:(e==null?void 0:e.domain)||((i=this.config)==null?void 0:i.domain)||A})}getWidgetType(e){return e&&e.includes("friendWidget")?"instant-access":"verified-access"}async renderPasswordlessVariant(){return this._setupApis(),z("Rendering as an Instant Access widget"),await this.widgetApi.render({engagementMedium:this.type,widgetType:this.widgetType,locale:this.locale}).then((e=>this._setWidget(e,{type:"passwordless"}))).catch(this.setErrorWidget)}async renderUserUpsertVariant(){this._setupApis();const e=De(this.token);if(!e)return this.setErrorWidget(Error("No user object in token."));!this.locale&&e.locale&&(this.locale=e.locale),z("Rendering as a Verified widget");try{await this.widgetApi.upsertUser({user:e,locale:this.locale,engagementMedium:this.type,widgetType:this.widgetType,jwt:this.token})}catch(i){return this.setErrorWidget(i)}return await this.widgetApi.render({locale:this.locale,engagementMedium:this.type,widgetType:this.widgetType}).then((i=>this._setWidget(i,{type:"upsert",user:e}))).catch(this.setErrorWidget)}async getWidgetInstance(){let e;this.widgetType=this.getAttribute("widget")||void 0,this.locale=this.getAttribute("locale")||this.locale;const n=this.getWidgetType(this.widgetType);if(!this.widgetType)throw new Error("No widget has been specified");return!this.token&&n==="verified-access"&&z("[SquatchJS] Authentication token is required for this widget type."),this.token?e=await this.renderUserUpsertVariant():e=await this.renderPasswordlessVariant(),this.widgetInstance=e,this.widgetInstance&&this.dispatchEvent(new CustomEvent("sq:widget-loaded")),e}async renderWidget(){await this.getWidgetInstance(),await this.widgetInstance.load()}open(){if(!this.widgetInstance)throw new Error("Widget has not loaded yet");this.widgetInstance.open()}close(){if(!this.widgetInstance)throw new Error("Widget has not loaded yet");this.widgetInstance.close()}static get observedAttributes(){return["widget","locale"]}attributeChangedCallback(e,n,i){if(!(n===i||!this.loaded))switch(e){case"locale":case"widget":this.connectedCallback();break}}async connectedCallback(){this.loaded=!0,this.container=this.getAttribute("container"),this.widgetType=this.getAttribute("widget")||void 0;const e=this.getWidgetType(this.widgetType),{getSkeleton:n}=await Promise.resolve().then((()=>pe)),i=n({type:e}),s=document.createElement("div");s.id="loading-skeleton",s.innerHTML=i;const r=this.shadowRoot||this.attachShadow({mode:"open"});if(this.type==="POPUP"){const a=r.getElementById("squatchModal");a&&(a.innerHTML="",a.appendChild(s))}else r.innerHTML="",r.appendChild(s);try{await this.renderWidget()}catch(a){z("Failed to render widget",a)}finally{const a=r.getElementById("loading-skeleton");a&&a.remove()}this.getAttribute("open")!==null&&this.open()}}class ne extends ue{constructor(){super(),this.type="EMBED",this.loaded=!1}}class ie extends ue{constructor(){super(),this.type="POPUP",this.loaded=!1,this.addEventListener("click",(t=>{t.stopPropagation(),this.open()}))}}class Ne extends ne{}class Fe extends ie{}class He extends ne{}class Je extends ie{}window.customElements.get("squatch-embed")||window.customElements.define("squatch-embed",Ne),window.customElements.get("impact-embed")||window.customElements.define("impact-embed",He),window.customElements.get("squatch-popup")||window.customElements.define("squatch-popup",Fe),window.customElements.get("impact-popup")||window.customElements.define("impact-popup",Je);function Be(){console.log("Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.")}const U=v("squatch-js");let G=null,V=null,X=null;function ze(){return G||L({}),G}function Q(){return V||L({}),V}function Ge(){return X||L({}),X}function Ve(o){var t;return(t=Q())==null?void 0:t.render(o)}function Xe(){var t;const o=Oe();if(o){const{squatchConfig:e,widgetConfig:n}=o;return L(e),(t=Q())==null?void 0:t.render(n)}}function L(o){const e=$(o);e.tenantAlias.match("^test")||e.debug?I("squatch-js*"):ke(),U("initializing ..."),G=new F(e),V=new R(e),X=new Pe(e),U("Widget API instance",G),U("Widgets instance",V),U("Events API instance",X)}function Qe(o){o()}function Ye(o){Q().autofill(o)}function ge(){Ce()}typeof document<"u"&&!window.SaaSquatchDoNotAutoDrop&&ge(),(me=window.squatch)!=null&&me.init&&U("Squatchjs is being loaded more than once. This may lead to multiple load events being sent, duplicated widgets, and inaccurate analytics."),typeof document<"u"&&Le();function Ze(o={}){const{rsCode:t,apiErrorCode:e,statusCode:n,message:i,mode:s="modal",style:r=""}=o,a=document.createElement("span"),d=u=>(a.textContent=u,a.innerHTML),c=[];n!==void 0&&c.push(`<dt>Status Code</dt><dd>${d(String(n))}</dd>`),e&&c.push(`<dt>API Error Code</dt><dd>${d(e)}</dd>`),t&&c.push(`<dt>RS Code</dt><dd>${d(t)}</dd>`),i&&c.push(`<dt>Message</dt><dd>${d(i)}</dd>`);const h=c.length>0?`<dl class="error-details">${c.join(`\n `)}</dl>`:"";return`<!DOCTYPE html>\n \x3c!--[if IE 7]><html class="ie7 oldie" lang="en"><![endif]--\x3e\n \x3c!--[if IE 8]><html class="ie8 oldie" lang="en"><![endif]--\x3e\n \x3c!--[if gt IE 8]>\x3c!--\x3e<html lang="en">\x3c!--<![endif]--\x3e\n <head>\n <style>\n ${r}\n body {\n font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n line-height: 20px;\n }\n h3 {\n text-align: center;\n }\n .errortitle {\n margin: 0;\n font-size: 14px;\n }\n .errorbody p {\n text-align: center;\n font-size: 12px;\n margin: 0 0 10px;\n }\n h4 {\n font-size: 17.5px;\n text-align: center;\n margin: 10px 0;\n }\n .embed {\n width: 100%;\n max-width: 500px;\n margin-left: auto;\n margin-right: auto;\n }\n .errorbody {\n padding: 15px;\n position: relative;\n height: auto;\n }\n p {\n text-align: center;\n font-size: 12px;\n }\n .sadface {\n padding: 10px;\n }\n .sadface img {\n display: block;\n margin: auto;\n height: 100px;\n }\n .modal-disable-overlay {\n display: none;\n position: absolute;\n top: 50px;\n width: 100%;\n height: 85%;\n background: rgba(255, 255, 255, 0.4);\n }\n\n .right-align {\n text-align: right;\n }\n .errtxt {\n color: #CCC9C9;\n }\n .error-details {\n margin-top: 16px;\n padding: 12px;\n background: #f8f8f8;\n border-radius: 4px;\n text-align: left;\n font-size: 13px;\n color: #666;\n display: block;\n overflow: visible;\n }\n .error-details dt {\n display: block;\n font-weight: 600;\n color: #333;\n margin-top: 8px;\n }\n .error-details dt:first-child {\n margin-top: 0;\n }\n .error-details dd {\n display: block;\n margin: 4px 0 0 0;\n word-break: break-word;\n }\n </style>\n </head>\n <body>\n\n <div class="squatch-container ${s}" style="width:100%;background:#FFF;">\n <div class="errorbody">\n <div class="sadface"><img src="https://fast.ssqt.io/assets/images/whoops-error-image.png"></div>\n <h4>Our referral program is temporarily unavailable.</h4>\n <p>Please reload the page or check back later.</p>\n <p>If the problem persists please contact our support team.</p>\n\n ${h}\n </div>\n </div>\n </body>\n </html>`}const Ke=Object.freeze(Object.defineProperty({__proto__:null,getErrorTemplate:Ze},Symbol.toStringTag,{value:"Module"})),pe=Object.freeze(Object.defineProperty({__proto__:null,getSkeleton:({type:o="verified-access"})=>`\n <style>\n * {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n .widget-container {\n background: white;\n width: 100%;\n padding: 40px;\n box-sizing: border-box;\n overflow: hidden; \n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n\n .skeleton {\n background: #e0e0e0;\n animation: pulse 1.8s ease-in-out infinite;\n border-radius: 6px;\n margin-bottom: 12px;\n }\n\n /* Typography Skeletons */\n .sk-title-lg { height: 36px; width: 80%; margin-bottom: 16px; }\n .sk-title-md { height: 28px; width: 30%; margin-bottom: 20px; margin-top: 40px; }\n .sk-text { height: 16px; width: 90%; margin-bottom: 8px; }\n .sk-text-short { width: 40%; }\n .sk-label { height: 14px; width: 25%; margin-bottom: 10px; }\n\n /* Layouts */\n .hero-section {\n display: flex;\n gap: 40px;\n margin-bottom: 40px;\n padding-bottom: 40px;\n flex-direction: row;\n height: 100%;\n /* Removed border-bottom */\n }\n \n .hero-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n \n .hero-image {\n flex: 1;\n height: 300px;\n border-radius: 12px;\n }\n\n /* -- Specific Instant Access Overrides -- */\n .instant-access-layout {\n margin-bottom: 0;\n padding-bottom: 0;\n align-items: center; \n }\n .ia-image {\n height: 400px; \n }\n .ia-center {\n margin-left: auto;\n margin-right: auto;\n }\n .ia-content {\n align-items: center; \n text-align: center;\n }\n .sk-btn-action {\n height: 45px;\n width: 140px;\n border-radius: 6px;\n margin: 24px auto;\n }\n .input-group {\n display: flex;\n gap: 10px;\n width: 100%;\n max-width: 400px;\n }\n .sk-btn-copy {\n height: 50px;\n width: 120px;\n border-radius: 8px;\n }\n /* ------------------------------------- */\n\n .share-section { margin-bottom: 40px; }\n .sk-input { height: 50px; width: 100%; border-radius: 8px; margin-bottom: 16px; }\n \n .social-buttons { display: flex; gap: 12px; }\n .sk-btn-social { flex: 1; height: 50px; border-radius: 8px; }\n\n .stats-section {\n display: flex;\n gap: 24px;\n margin-bottom: 40px;\n padding: 30px 0;\n /* Removed border-top and border-bottom */\n }\n .stat-card { flex: 1; display: flex; flex-direction: column; align-items: center; }\n .stat-divider { padding-left: 24px; }\n .sk-stat-num { height: 48px; width: 120px; margin-bottom: 8px; }\n .sk-stat-label { height: 18px; width: 80px; }\n\n /* Table Styles */\n .table-header { display: flex; gap: 16px; margin-bottom: 16px; }\n .sk-th { height: 16px; }\n .table-row { \n display: flex; \n align-items: center; \n gap: 16px; \n padding: 16px 0; \n /* Removed border-bottom */\n }\n \n .col-user { flex: 2; }\n .col-status { flex: 1; }\n .col-reward { flex: 2; }\n .col-date { flex: 1; }\n\n .sk-badge { height: 28px; width: 90px; border-radius: 14px; }\n .sk-reward-block { height: 36px; width: 100%; border-radius: 6px; }\n\n .pagination { display: flex; justify-content: flex-end; gap: 8px; margin-top: 24px; }\n .sk-btn-page { height: 36px; width: 64px; border-radius: 6px; margin-bottom: 0; }\n\n @media (max-width: 768px) {\n body { padding: 20px; }\n .widget-container { padding: 24px; }\n\n .hero-section { flex-direction: column-reverse; gap: 24px; }\n .instant-access-layout { flex-direction: column; }\n \n .hero-image { height: 220px; width: 100%; }\n .sk-title-lg { width: 100%; }\n\n .col-date { display: none; }\n }\n </style>\n\n <div class="widget-container">\n ${o==="verified-access"?`\n <div class="hero-section">\n <div class="hero-content">\n <div class="skeleton sk-title-lg"></div>\n <div class="skeleton sk-text"></div>\n <div class="skeleton sk-text sk-text-short"></div>\n </div>\n <div class="skeleton hero-image"></div>\n </div>\n\n <div class="share-section">\n <div class="skeleton sk-label"></div>\n <div class="skeleton sk-input"></div>\n <div class="social-buttons">\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n <div class="skeleton sk-btn-social"></div>\n </div>\n </div>\n\n <div class="skeleton sk-title-md" style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"></div>\n <div class="skeleton sk-text" style="width: 60%; margin-left: auto; margin-right: auto"></div>\n\n <div class="stats-section">\n <div class="stat-card">\n <div class="skeleton sk-stat-num"></div>\n <div class="skeleton sk-stat-label"></div>\n </div>\n <div class="stat-card stat-divider">\n <div class="skeleton sk-stat-num"></div>\n <div class="skeleton sk-stat-label"></div>\n </div>\n </div>\n\n <div class="skeleton sk-title-md"></div>\n\n <div class="table-header">\n <div class="skeleton sk-th col-user"></div>\n <div class="skeleton sk-th col-status"></div>\n <div class="skeleton sk-th col-reward"></div>\n <div class="skeleton sk-th col-date"></div>\n </div>\n\n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 70%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n \n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 60%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n\n <div class="table-row">\n <div class="col-user"><div class="skeleton sk-text" style="width: 75%; margin: 0"></div></div>\n <div class="col-status"><div class="skeleton sk-badge" style="margin: 0"></div></div>\n <div class="col-reward"><div class="skeleton sk-reward-block" style="margin: 0"></div></div>\n <div class="col-date"><div class="skeleton sk-text" style="width: 80%; margin: 0"></div></div>\n </div>\n\n <div class="pagination">\n <div class="skeleton sk-btn-page"></div>\n <div class="skeleton sk-btn-page"></div>\n </div>\n `:`\n <div class="hero-section instant-access-layout">\n <div class="skeleton hero-image ia-image"></div>\n \n <div class="hero-content ia-content">\n <div class="skeleton sk-title-lg ia-center"></div>\n <div class="skeleton sk-text ia-center"></div>\n \n <div class="skeleton sk-btn-action"></div>\n\n <div class="skeleton sk-label"></div>\n <div class="input-group">\n <div class="skeleton sk-input"></div>\n <div class="skeleton sk-btn-copy"></div>\n </div>\n\n <div class="skeleton sk-text-short ia-center" style="margin-top: 20px; width: 30%"></div>\n <div class="skeleton sk-text-short ia-center" style="width: 20%"></div>\n </div>\n </div>\n `}\n </div>\n `},Symbol.toStringTag,{value:"Module"}));g.DeclarativeEmbedWidget=ne,g.DeclarativePopupWidget=ie,g.EmbedWidget=q,g.PopupWidget=P,g.WidgetApi=F,g.Widgets=R,g._auto=Xe,g.api=ze,g.autofill=Ye,g.events=Ge,g.help=Be,g.init=L,g.pushCookie=ge,g.ready=Qe,g.widget=Ve,g.widgets=Q,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})}));
@@ -1,3 +1,4 @@
1
+ export declare function getCookie(name: string): string | undefined;
1
2
  export declare function b64decode(input: any): string;
2
3
  export declare function b64encode(input: any): string;
3
4
  export declare function _pushCookie(): void;
@@ -18,7 +18,7 @@ export default class EmbedWidget extends Widget {
18
18
  */
19
19
  open(): void;
20
20
  close(): void;
21
- protected _error(rs: any, mode?: string, style?: string): string;
21
+ protected _getErrorMode(): string;
22
22
  private _shouldFireLoadEvent;
23
23
  show: () => void;
24
24
  hide: () => void;
@@ -0,0 +1,9 @@
1
+ export interface ErrorTemplateOptions {
2
+ rsCode?: string;
3
+ apiErrorCode?: string;
4
+ statusCode?: number;
5
+ message?: string;
6
+ mode?: string;
7
+ style?: string;
8
+ }
9
+ export declare function getErrorTemplate(options?: ErrorTemplateOptions): string;
@@ -22,10 +22,7 @@ export default class PopupWidget extends Widget {
22
22
  protected _setupResizeHandler(frame: HTMLIFrameElement): Promise<void>;
23
23
  open(): void;
24
24
  close(): void;
25
- protected _clickedOutside({ target }: {
26
- target: any;
27
- }): void;
28
- protected _error(rs: any, mode?: string, style?: string): string;
25
+ protected _getErrorStyle(): string;
29
26
  show: () => void;
30
27
  hide: () => void;
31
28
  }
@@ -1,11 +1,10 @@
1
1
  export type WidgetType = "instant-access" | "verified-access";
2
2
  interface SkeletonProps {
3
3
  type?: WidgetType;
4
- height?: string | number;
5
4
  }
6
5
  /**
7
6
  * Returns the complete HTML string (including <style>) for the skeleton.
8
7
  * Values are injected directly into the CSS string.
9
8
  */
10
- export declare const getSkeleton: ({ type, height, }: SkeletonProps) => string;
9
+ export declare const getSkeleton: ({ type }: SkeletonProps) => string;
11
10
  export {};
@@ -42,7 +42,21 @@ export default abstract class Widget {
42
42
  npmCdn: string;
43
43
  container: string | HTMLElement | undefined | null;
44
44
  loadEventListener: EventListener | null;
45
+ protected errorInfo?: {
46
+ rsCode?: string;
47
+ apiErrorCode?: string;
48
+ statusCode?: number;
49
+ message?: string;
50
+ };
45
51
  protected constructor(params: Params);
52
+ /**
53
+ * Returns the widget content, dynamically loading the error template if needed.
54
+ */
55
+ protected _getContent(): Promise<string>;
56
+ /** Override in subclasses to customize error template mode */
57
+ protected _getErrorMode(): string;
58
+ /** Override in subclasses to customize error template styles */
59
+ protected _getErrorStyle(): string;
46
60
  _findElement(): HTMLElement;
47
61
  _createFrame(options?: {
48
62
  minWidth?: string;
@@ -55,24 +69,18 @@ export default abstract class Widget {
55
69
  protected _attachLoadEventListener(frameDoc: Document, sqh: ProgramLoadEvent | GenericLoadEvent): void;
56
70
  protected _loadEvent(sqh: ProgramLoadEvent | GenericLoadEvent): void;
57
71
  protected _shareEvent(sqh: any, medium: any): void;
58
- protected _error(errorInfo?: {
59
- rsCode?: string;
60
- apiErrorCode?: string;
61
- statusCode?: number;
62
- message?: string;
63
- }, mode?: string, style?: string): string;
64
72
  protected _findInnerContainer(frame: HTMLIFrameElement): Promise<Element>;
65
73
  /**
66
74
  * Returns HTML for an in-iframe skeleton preload overlay that is removed
67
- * once all Stencil component chunks have loaded and been hydrated.
75
+ * once all custom elements in the widget are defined.
68
76
  *
69
- * Uses a MutationObserver to detect when components receive the `hydrated`
70
- * class, debouncing removal so the skeleton stays visible until all chunks
71
- * have finished loading. Includes a timeout fallback.
77
+ * Uses `customElements.whenDefined()` to wait for all custom element tags,
78
+ * then removes the skeleton after two animation frames. Includes a 10s
79
+ * timeout fallback.
72
80
  *
73
81
  * Only generates content for mint-components widgets; returns empty string otherwise.
74
82
  */
75
- protected _getSkeletonPreloadHTML(hasMintComponents: boolean, backgroundColor?: string): string;
83
+ protected _getSkeletonPreloadHTML(hasMintComponents: boolean, backgroundColor?: string): Promise<string>;
76
84
  /**
77
85
  * Reloads the current widget, makes updated request to API and renders result.
78
86
  * Primarily for Classic widgets with registration
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@saasquatch/squatch-js",
3
3
  "type": "module",
4
- "version": "2.8.3-9",
4
+ "version": "2.8.4",
5
5
  "description": "The official Referral SaaSquatch Javascript Web/Browser SDK https://docs.referralsaasquatch.com/developer/squatchjs/",
6
6
  "license": "MIT",
7
7
  "author": "ReferralSaaSquatch.com, Inc.",
@@ -36,8 +36,8 @@
36
36
  "test:webkit": "cross-env BROWSER=webkit cucumber-js",
37
37
  "test:firefox": "cross-env BROWSER=firefox cucumber-js",
38
38
  "test:types": "tsd",
39
- "test:features": "jest --verbose --coverage",
40
- "test:utf8": "jest --verbose -t 'UTF-8 characters in different languages'",
39
+ "test:features": "vitest run --coverage",
40
+ "test:utf8": "vitest run -t 'UTF-8 characters in different languages'",
41
41
  "test": "run-s test:features test:browser test:webkit test:firefox",
42
42
  "build:docs": "typedoc",
43
43
  "deploy": "np --no-cleanup",
@@ -45,6 +45,9 @@
45
45
  "preversion": "run-s build",
46
46
  "demo": "msw init demo/dist/ --save && run-p static parcel",
47
47
  "demo:deploy": "run-s parcel:build parcel:deploy",
48
+ "perf": "npx tsx demo/perf-benchmark.ts",
49
+ "perf:ui": "npx tsx demo/perf-server.ts",
50
+ "perf:deploy": "cp demo/perf-compare.html demo/perf-deploy/index.html && cp demo/perf-frame.html demo/perf-deploy/perf-frame.html && cd demo/perf-deploy && vercel --prod",
48
51
  "static": "serve -l 3333 -s dist",
49
52
  "parcel": "cd demo && parcel index.html",
50
53
  "parcel:build": "cd demo && parcel build index.html",
@@ -52,13 +55,11 @@
52
55
  },
53
56
  "devDependencies": {
54
57
  "@babel/core": "^7.14.3",
55
- "@babel/plugin-proposal-class-properties": "^7.13.0",
56
58
  "@babel/plugin-transform-runtime": "^7.14.3",
57
59
  "@babel/preset-env": "^7.14.2",
58
60
  "@babel/preset-typescript": "^7.13.0",
59
61
  "@babel/register": "^7.13.16",
60
62
  "@babel/runtime-corejs2": "^7.14.0",
61
- "@happy-dom/jest-environment": "^9.20.3",
62
63
  "@open-wc/testing-helpers": "^2.3.0",
63
64
  "@size-limit/preset-small-lib": "^8.2.4",
64
65
  "@testing-library/dom": "^9.3.1",
@@ -67,22 +68,19 @@
67
68
  "@types/estree": "^1.0.1",
68
69
  "@types/express": "^4.17.6",
69
70
  "@types/inquirer": "^9.0.3",
70
- "@types/jest": "^29.5.2",
71
- "@types/js-cookie": "^2.2.6",
72
71
  "@types/jsdom-global": "^3.0.2",
73
72
  "@types/react": "^16.9.35",
74
73
  "@ungap/url-search-params": "^0.2.0",
74
+ "@vitest/coverage-v8": "^4.1.2",
75
75
  "ajv": "^8.17.1",
76
- "babel-jest": "^29.5.0",
77
76
  "babel-loader": "^8.2.2",
78
77
  "base64-url": "^2.3.3",
79
78
  "chai": "^4.3.7",
80
79
  "cross-env": "^7.0.2",
81
80
  "cucumber": "^6.0.5",
82
81
  "express": "^4.17.1",
83
- "jest": "^29.5.0",
82
+ "happy-dom": "^20.8.9",
84
83
  "jest-cucumber": "^3.0.1",
85
- "jest-environment-jsdom": "^29.5.0",
86
84
  "microbundle": "^0.13.0",
87
85
  "msw": "^0.36.8",
88
86
  "np": "^6.2.3",
@@ -97,21 +95,19 @@
97
95
  "serve": "^11.3.0",
98
96
  "size-limit": "^8.2.4",
99
97
  "terser": "^5.39.1",
100
- "ts-jest": "^29.3.3",
101
98
  "ts-loader": "^7.0.4",
102
99
  "ts-node": "^8.10.2",
103
100
  "tsd": "^0.13.1",
101
+ "tsx": "^4.21.0",
104
102
  "typedoc": "^0.24.8",
105
103
  "typescript": "^5.1.6",
106
104
  "vite": "^6.2.4",
107
105
  "vite-bundle-analyzer": "^0.18.1",
108
106
  "vite-plugin-dts": "^4.5.3",
109
- "vite-tsconfig-paths": "^5.1.4"
107
+ "vite-tsconfig-paths": "^5.1.4",
108
+ "vitest": "^4.1.2"
110
109
  },
111
110
  "prettier": {},
112
- "dependencies": {
113
- "js-cookie": "^3.0.5"
114
- },
115
111
  "browserslist": "> 0.25%, not dead",
116
112
  "msw": {
117
113
  "workerDirectory": "demo/dist"
package/vite-env.d.ts CHANGED
@@ -1 +1,2 @@
1
- /// <reference types="vite/client" />
1
+ /// <reference types="vite/client" />
2
+ /// <reference types="vitest/globals" />
package/vite.config.ts CHANGED
@@ -4,6 +4,23 @@ import tsconfigPaths from "vite-tsconfig-paths";
4
4
  import dts from "vite-plugin-dts";
5
5
 
6
6
  export default defineConfig({
7
+ test: {
8
+ environment: "happy-dom",
9
+ globals: true,
10
+ include: [
11
+ "**/*.steps.[tj]s",
12
+ "**/__tests__/**/*.[jt]s?(x)",
13
+ "**/?(*.)+(spec|test).[tj]s?(x)",
14
+ ],
15
+ mockReset: true,
16
+ restoreMocks: false,
17
+ coverage: {
18
+ exclude: ["node_modules", "test"],
19
+ },
20
+ alias: {
21
+ "^uuid$": "uuid",
22
+ },
23
+ },
7
24
  plugins: [
8
25
  tsconfigPaths(),
9
26
  dts({
package/babel.config.js DELETED
@@ -1,8 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- [
4
- "@babel/preset-env",
5
- { targets: { esmodules: true }}
6
- ]
7
- ]
8
- }