Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@formbricks/js

Package Overview
Dependencies
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@formbricks/js - npm Package Compare versions

Comparing version 1.6.3 to 1.6.4

2

dist/index.iife.js

@@ -1,2 +0,2 @@

var formbricks=function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}();
var formbricks=function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(m);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=w.getInstance(),S=l.getInstance();let H=null;const C=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.4";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=E(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},E=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==H&&(window.clearInterval(H),H=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let O=!1,U=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const P=()=>{O&&(document.removeEventListener("mouseleave",U),O=!1)};let T=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{T&&(window.removeEventListener("scroll",L),T=!1)},z=w.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const W=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",U),O=!0),"undefined"==typeof window||T||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),T=!0)},ee=()=>{A(),X(),K(),P(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=te.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=te.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=fe.get();if(!t){const e=fe.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Ue=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Pe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(de.debug("Check if initialized"),ce&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Ue(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Te=async(e,t)=>{Pe.add(!0,ie,e,t),await Pe.wait()};return{init:async e=>{y.init(e.errorHandler),Pe.add(!1,le,e),await Pe.wait()},setUserId:async()=>{Pe.add(!0,se),await Pe.wait()},setEmail:async e=>{Te("email",e),await Pe.wait()},setAttribute:Te,track:async(e,t={})=>{Pe.add(!0,xe,e,t),await Pe.wait()},logout:async()=>{Pe.add(!0,re),await Pe.wait()},reset:async()=>{Pe.add(!0,oe),await Pe.wait()},registerRouteChange:async()=>{Pe.add(!0,M),await Pe.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}();
//# sourceMappingURL=index.iife.js.map

@@ -1,2 +0,2 @@

"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()},Pe={init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}};module.exports=Pe;
"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(m);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=w.getInstance(),S=l.getInstance();let H=null;const C=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.4";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=E(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},E=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==H&&(window.clearInterval(H),H=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let O=!1,U=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const P=()=>{O&&(document.removeEventListener("mouseleave",U),O=!1)};let T=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{T&&(window.removeEventListener("scroll",L),T=!1)},z=w.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const W=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",U),O=!0),"undefined"==typeof window||T||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),T=!0)},ee=()=>{A(),X(),K(),P(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=te.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=te.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=fe.get();if(!t){const e=fe.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Ue=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Pe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(de.debug("Check if initialized"),ce&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Ue(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Te=async(e,t)=>{Pe.add(!0,ie,e,t),await Pe.wait()},Re={init:async e=>{y.init(e.errorHandler),Pe.add(!1,le,e),await Pe.wait()},setUserId:async()=>{Pe.add(!0,se),await Pe.wait()},setEmail:async e=>{Te("email",e),await Pe.wait()},setAttribute:Te,track:async(e,t={})=>{Pe.add(!0,xe,e,t),await Pe.wait()},logout:async()=>{Pe.add(!0,re),await Pe.wait()},reset:async()=>{Pe.add(!0,oe),await Pe.wait()},registerRouteChange:async()=>{Pe.add(!0,M),await Pe.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}};module.exports=Re;
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).formbricks=t()}(this,(function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const w="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(w);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(w,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(w)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const T=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let U=!1,P=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(P=!1),!P&&e/(n-t)>=.5){P=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{U&&(window.removeEventListener("scroll",R),U=!1)},z=m.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||U||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),U=!0)},Z=()=>{A(),J(),G(),T(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(w,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),ye=y.getInstance();let we=!1,me=e=>{},Ie=e=>{};const be=e=>{we=e},ke=async e=>{if(we)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){ye.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Te=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{y.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Te("email",e),await Oe.wait()},setAttribute:Te,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).formbricks=t()}(this,(function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){e&&void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(m);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=w.getInstance(),S=l.getInstance();let H=null;const C=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.4";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=E(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},E=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==H&&(window.clearInterval(H),H=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let O=!1,T=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{O&&(document.removeEventListener("mouseleave",T),O=!1)};let P=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",L),P=!1)},z=w.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const W=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",T),O=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),P=!0)},ee=()=>{A(),X(),K(),U(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),U(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=te.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=te.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),U(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=fe.get();if(!t){const e=fe.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Te=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Ue=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(de.debug("Check if initialized"),ce&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Te(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Pe=async(e,t)=>{Ue.add(!0,ie,e,t),await Ue.wait()};return{init:async e=>{y.init(e.errorHandler),Ue.add(!1,le,e),await Ue.wait()},setUserId:async()=>{Ue.add(!0,se),await Ue.wait()},setEmail:async e=>{Pe("email",e),await Ue.wait()},setAttribute:Pe,track:async(e,t={})=>{Ue.add(!0,xe,e,t),await Ue.wait()},logout:async()=>{Ue.add(!0,re),await Ue.wait()},reset:async()=>{Ue.add(!0,oe),await Ue.wait()},registerRouteChange:async()=>{Ue.add(!0,M),await Ue.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}));
//# sourceMappingURL=index.umd.js.map
{
"name": "@formbricks/js",
"license": "MIT",
"version": "1.6.3",
"version": "1.6.4",
"description": "Formbricks-js allows you to connect your app to Formbricks, display surveys and trigger events.",

@@ -41,3 +41,3 @@ "homepage": "https://formbricks.com",

"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "1.12.5",
"eslint-config-turbo": "1.10.12",
"isomorphic-fetch": "^3.0.0",

@@ -47,7 +47,7 @@ "terser": "^5.29.1",

"vite-plugin-dts": "^3.7.3",
"@formbricks/lib": "0.0.0",
"@formbricks/surveys": "1.6.2",
"@formbricks/api": "1.6.0",
"@formbricks/surveys": "1.6.2",
"@formbricks/tsconfig": "1.0.0",
"@formbricks/types": "0.0.0",
"@formbricks/lib": "0.0.0"
"@formbricks/tsconfig": "1.0.0"
},

@@ -54,0 +54,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc