@parag.more.withsurface.com/forms-sdk 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1 @@
1
- "use strict";var SurfaceFormsSDK=(()=>{var $e=Object.defineProperty;var en=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var nn=Object.prototype.hasOwnProperty;var rn=(e,n)=>{for(var t in n)$e(e,t,{get:n[t],enumerable:!0})},on=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of tn(n))!nn.call(e,o)&&o!==t&&$e(e,o,{get:()=>n[o],enumerable:!(r=en(n,o))||r.enumerable});return e};var sn=e=>on($e({},"__esModule",{value:!0}),e);var yr={};rn(yr,{DEFAULT_API_BASE_URL:()=>Q,DEFAULT_REDIRECT_TIMEOUT_MS:()=>Ot,ENRICHMENT_STATE_ID:()=>Oe,IDENTITY_INFO_ANSWER_KEYS:()=>Mt,JOURNEY_COOKIE_NAME:()=>re,LEAD_DATA_STORAGE_KEY:()=>te,LEAD_DATA_TTL_MS:()=>Ut,RECENT_VISIT_COOKIE_NAME:()=>oe,SurfaceForms:()=>Gt,attachEmailValidation:()=>qe,attachEnrichment:()=>Fe,bindForm:()=>ae,buildIdentifyPayload:()=>xe,buildRedirectUrl:()=>We,buildResponsesArray:()=>Ke,buildStepTransitionEventBatch:()=>ke,buildUrlData:()=>Re,constructUrlParamsObject:()=>Je,createEmailValidator:()=>he,createEmitter:()=>Se,createFormEngine:()=>Te,createFormJourneyTracker:()=>_e,createJourneyTracker:()=>Le,createPushEventClient:()=>we,createSchedulerClient:()=>ge,createStartedDetector:()=>Ie,createSubmitResponsePayload:()=>Ee,createTransport:()=>be,createUpdateResponsePayload:()=>z,enrichmentSourcesOf:()=>pe,ensureIdentified:()=>ne,fetchRuntimeConfig:()=>le,getBrowserFingerprint:()=>Ce,getHash:()=>Ye,hasEnabledEnrichmentProvider:()=>fe,identifyLead:()=>Pe,mountBookingWidget:()=>de,mountScheduler:()=>Rt,observeDropoff:()=>Ae,observeFormView:()=>ie,parseCookiesObject:()=>Qe,parsePrefillParams:()=>Dt,parseQuestionId:()=>ze,performRedirect:()=>Ft,readLeadData:()=>Y,schedulerQuestionsOf:()=>me,statefulQuestionIdsOf:()=>dt,statefulQuestionsOf:()=>J,stepsOf:()=>ce,submitResponse:()=>ve,toSchedulerAnswerState:()=>St,updateResponse:()=>ee,writeLeadData:()=>Me});var ie=(e,n)=>{if(typeof IntersectionObserver>"u")return n(),()=>{};let t=!1,r=new IntersectionObserver(o=>{let[a]=o;!a?.isIntersecting||t||(t=!0,r.disconnect(),n())});return r.observe(e),()=>r.disconnect()};var ot="input, select, textarea",an=e=>e.matches(ot)?[e]:Array.from(e.querySelectorAll(ot)).filter(n=>n.closest("[data-question-id]")===e),dn=(e,n,t)=>{let r=e.getAttribute("data-field-name")??n.getAttribute("data-field-name");return r||(t==="Dropdown"&&n instanceof HTMLSelectElement?"selected":n instanceof HTMLInputElement&&n.type==="email"?"email":"input")},st=(e,n)=>{let t=e.getAttribute("data-question-type")??n.getAttribute("data-question-type");return t||(n instanceof HTMLInputElement&&n.type==="email"?"EmailForm":"ShortInput")},it=e=>e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")&&e.type==="checkbox"?e.checked:e.value,ln=e=>e instanceof HTMLInputElement&&(e.type==="radio"||e.type==="checkbox"),at=e=>{let n=e.findIndex(t=>t.checked);return{value:n===-1?"":e[n].value,index:n}},un={MultipleOptionsQuestion:e=>({choices:e.map((n,t)=>({key:n.value,value:n.checked,index:t}))}),MultipleChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),MMChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),GraphicOptions:at,MultipleChoiceSingleAnswer:at},ae=({engine:e,root:n,expectedQuestionIds:t})=>{let r=[],o=new Set,a=(u,c,p)=>{u.addEventListener(c,p),r.push(()=>u.removeEventListener(c,p))};for(let u of Array.from(n.querySelectorAll("[data-question-id]"))){let c=u.getAttribute("data-question-id"),p=an(u);if(p.length===0)continue;o.add(c);let A=st(u,p[0]),h=un[A],f=p.filter(ln);if(h&&f.length>0){let y=()=>e.setAnswer(c,{type:A,...h(f)});for(let S of f)a(S,"change",y);f.some(S=>S.checked)&&y();continue}for(let y of p){let S=st(u,y),g=dn(u,y,S),M=()=>e.setAnswer(c,{type:S,[g]:it(y)});a(y,"input",M),a(y,"change",M);let k=it(y);k!==""&&k!==!1&&M()}}let i=(t??[]).filter(u=>!o.has(u));i.length>0&&console.warn(`Surface SDK: form record declares questionIds with no bound element: ${i.join(", ")}. Answers for these will never be captured \u2014 check data-question-id attributes (validate_form_html catches this at authoring time).`);let s="[data-surface-goto-step], .surface-disqualify-button, .surface-submit-button, .surface-next-button";for(let u of Array.from(n.querySelectorAll(s))){let c=u.getAttribute("data-surface-goto-step"),p=[c!=null?"goto":null,u.classList.contains("surface-disqualify-button")?"disqualify":null,u.classList.contains("surface-submit-button")?"submit":null,u.classList.contains("surface-next-button")?"next":null].filter(h=>h!=null),A=p[0];p.length>1&&console.warn(`Surface SDK: element carries multiple navigation markers (${p.join(", ")}); only "${A}" is bound.`),a(u,"click",h=>{h.preventDefault(),A==="goto"?e.goToStep(c).catch(f=>console.warn(`Surface SDK: ${String(f)}`)):A==="disqualify"?e.disqualify():A==="submit"?e.submit():e.next()})}n instanceof HTMLFormElement&&a(n,"submit",u=>{u.preventDefault(),e.submit()});let d=Array.from(n.querySelectorAll("[data-step-id]")),l=()=>{let{currentStepId:u}=e.state();for(let c of d)c.hidden=c.getAttribute("data-step-id")!==u};return d.length>0&&(l(),r.push(e.on("stepChanged",l))),r.push(ie(n,()=>e.markViewed())),()=>r.forEach(u=>u())};var cn=()=>{let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`},pn=e=>{let[n,t]=e.split("-").map(Number);return new Date(n,t-1,1).toLocaleDateString(void 0,{month:"long",year:"numeric"})},mn=e=>{let[n,t,r]=e.split("-").map(Number);return new Date(n,t-1,r).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"})},fn=(e,n)=>{let[t,r]=e.split("-").map(Number),o=new Date(t,r-1+n,1);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}`},de=({container:e,scheduler:n,eventTypeId:t,timezone:r=Intl.DateTimeFormat().resolvedOptions().timeZone,duration:o,prefill:a,identity:i,formatters:s,onEvent:d,onComplete:l})=>{let u=s?.month??pn,c=s?.date??mn,p=s?.time??(b=>new Date(b.start).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:r})),A=document.createElement("div");A.className="surface-booking",e.appendChild(A);let h=cn(),f=[],y=null,S=null,g=!1,M=0,k=(b,D,I)=>{let v=document.createElement(b);return v.className=D,I!=null&&(v.textContent=I),v},x=b=>{g||A.replaceChildren(...b)},R=(b,D)=>{let I=k("p","surface-booking-error",b),v=k("button","surface-booking-retry","Try again");v.type="button",v.addEventListener("click",D),x([I,v])},U=async()=>{let b=h,D=++M;x([k("p","surface-booking-loading","Loading availability\u2026")]);let I=await n.getMonthAvailability({eventTypeId:t,month:b,timezone:r,duration:o});if(g||D!==M)return;if(!I.ok){R("Unable to load availability.",()=>{U()});return}f=I.data.data?.dates??[];let v=k("p","surface-booking-month",u(b));v.dataset.value=b;let L=k("div","surface-booking-month-nav");for(let[F,T]of[["Previous month",-1],["Next month",1]]){let P=k("button","surface-booking-month-button",F);P.type="button",P.addEventListener("click",()=>{h=fn(h,T),U()}),L.appendChild(P)}let O=k("ul","surface-booking-dates");for(let F of f.filter(T=>T.slots&&T.slots.length>0)){let T=k("li","surface-booking-date"),P=k("button","surface-booking-date-button",c(F.date));P.dataset.value=F.date,P.type="button",P.addEventListener("click",()=>{y=F,d?.({type:"date_selected",date:F.date}),w()}),T.appendChild(P),O.appendChild(T)}O.childElementCount===0&&O.appendChild(k("li","surface-booking-no-dates","No availability this month.")),x([v,L,O])},w=async()=>{if(!y)return;let b=++M,D=y.slots??[];if(D.length===0){let O=await n.getSlots({eventTypeId:t,date:y.date,timezone:r,duration:o});if(g||b!==M)return;if(!O.ok){R("Unable to load times.",()=>{w()});return}D=O.data.data?.slots??[]}let I=k("p","surface-booking-day",c(y.date));I.dataset.value=y.date;let v=k("button","surface-booking-back","Back");v.type="button",v.addEventListener("click",()=>{U()});let L=k("ul","surface-booking-slots");for(let O of D){let F=k("li","surface-booking-slot"),T=k("button","surface-booking-slot-button",p(O));T.dataset.value=O.start,T.type="button",T.addEventListener("click",()=>{S=O,d?.({type:"slot_selected",slot:O}),_()}),F.appendChild(T),L.appendChild(F)}x([I,v,L])},_=b=>{if(!S)return;b==null&&d?.({type:"form_opened"});let D=k("form","surface-booking-form"),I=k("input","surface-booking-name");I.name="name",I.placeholder="Name",I.value=a?.name??"";let v=k("input","surface-booking-email");v.type="email",v.name="email",v.placeholder="Email",v.value=a?.email??"";let L=k("button","surface-booking-submit","Book");L.type="submit",D.append(I,v,L),b&&D.appendChild(k("p","surface-booking-error",b)),D.addEventListener("submit",O=>{O.preventDefault(),(async()=>{L.disabled=!0;let F=typeof i=="function"?await i():i,T=await n.book({eventTypeId:t,startTime:S.start,endTime:S.end,timezone:r,inviteeName:I.value,inviteeEmail:v.value,duration:o,...F});if(!g){if(!T.ok){_("Booking failed. Please try again.");return}x([k("p","surface-booking-booked","Booked!")]),d?.({type:"booking_confirmed",booking:T.data}),l(T.data)}})()}),x([D])};return d?.({type:"viewed"}),U(),()=>{g=!0,A.remove()}};var le=(e,n,{preview:t=!1,previewToken:r}={})=>e.get(`/api/v1/public/forms/${n}/runtime-config${t?`?preview=1${r?`&pt=${encodeURIComponent(r)}`:""}`:""}`),ue=e=>{let n=e.components;if(Array.isArray(n))return n;let t=n?.layout;return Array.isArray(t)?t.flatMap(r=>{let o=r.row;return Array.isArray(o)?o.map(a=>a.type==="GridLayoutRowItem"?a.component:a):[]}):[]},ce=e=>(e.steps??[]).map(n=>({id:n.id,...n.endStepKind!==void 0&&{endStepKind:n.endStepKind}})),J=e=>(e.steps??[]).flatMap(ue).flatMap(n=>{let t=n;return typeof t?.state?.questionId!="string"?[]:[{questionId:t.state.questionId,...typeof t.type=="string"&&{componentType:t.type}}]}),dt=e=>J(e).map(n=>n.questionId),pe=e=>(e.steps??[]).flatMap(ue).flatMap(n=>{let t=n;if(typeof t?.state?.questionId!="string")return[];if(t.type==="IdentityInfo"){let r=typeof t.content?.enrichmentSourceField=="string"?t.content.enrichmentSourceField:"emailAddress";return[{questionId:t.state.questionId,fieldNames:[...new Set([r,"websiteUrl"])]}]}return t.type==="EmailForm"?[{questionId:t.state.questionId,fieldNames:["email"]}]:[]}),lt=e=>{let n=e;return typeof n?.stepId=="string"&&typeof n?.questionId=="string"?{stepId:n.stepId,questionId:n.questionId}:void 0},gn=e=>{let n=lt(e),t=e?.variable;return n&&typeof t=="string"?{...n,variable:t}:void 0},me=e=>(e.steps??[]).flatMap(n=>ue(n).flatMap(t=>{let r=t;if(r?.type!=="CalendlyScreen"&&r?.type!=="DynamicScheduler")return[];if(typeof r.state?.questionId!="string")return[];let o=r.content??{},a={};for(let s of["dataUrl","eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);for(let s of["addSchedulerQueryParams","skipFormIfPrefilled"])typeof o[s]=="boolean"&&(a[s]=o[s]);for(let s of["linkNameToStep","linkLastNameToStep","linkEmailToStep"]){let d=lt(o[s]);d&&(a[s]=d)}let i=Object.entries(o.dataUrlParams??{}).flatMap(([s,d])=>{let l=gn(d);return l?[[s,l]]:[]});return i.length>0&&(a.dataUrlParams=Object.fromEntries(i)),Array.isArray(o.calendars)&&(a.calendars=o.calendars),o.defaultCalendar!=null&&(a.defaultCalendar=o.defaultCalendar),[{questionId:r.state.questionId,stepId:n.id,componentType:r.type,calendarType:typeof o.calendarType=="string"?o.calendarType:"Calendly",content:a}]})),ut=e=>(e.steps??[]).flatMap(ue).some(n=>typeof n?.content?.enrichmentSourceField=="string"),fe=e=>{let n=e?.enrichment;return n?.version!==2||!Array.isArray(n.providers)?!1:n.providers.some(t=>t?.enabled===!0&&Array.isArray(t.enabledFields)&&t.enabledFields.length>0)};var X=e=>/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`,B=(e,n)=>{let t;try{t=new URL(X(e))}catch{return null}for(let[r,o]of Object.entries(n))o!=null&&!t.searchParams.has(r)&&t.searchParams.set(r,o);return t.toString()},yn=(e,n)=>{let t=document.createElement("iframe");return t.className="surface-scheduler-frame",t.src=n,t.style.width="100%",t.style.height="100%",t.style.border="0",e.appendChild(t),t},W=e=>new Promise((n,t)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.surfaceLoaded==="true")return n();r.addEventListener("load",()=>n()),r.addEventListener("error",()=>t(new Error(`Failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.async=!0,o.addEventListener("load",()=>{o.dataset.surfaceLoaded="true",n()}),o.addEventListener("error",()=>{o.remove(),t(new Error(`Failed to load ${e}`))}),document.head.appendChild(o)}),hn=(e,n)=>{let t;try{t=new URL(e)}catch{return!1}return n.some(r=>"exact"in r?e===r.exact:t.protocol!=="https:"?!1:"hostRegex"in r?r.hostRegex.test(t.hostname):t.hostname===r.hostSuffix||t.hostname.endsWith(`.${r.hostSuffix}`))},q=(e,n)=>(console.warn(`Surface SDK: scheduler question "${e.questionId}" is missing ${n} on the record.`),()=>{}),j=e=>{let n=!1,t;return e().then(r=>{n?r?.():t=r}).catch(r=>console.warn("Surface SDK: scheduler embed failed",r)),()=>{n=!0,t?.()}},Z=(e,n)=>{let t=r=>{if(hn(r.origin,e))try{n(r.data)}catch(o){console.warn("Surface SDK: scheduler message handler failed",o)}};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},V=(e,{needsResponseId:n=!1,build:t})=>j(async()=>{let r=n?await e.ensureResponseId():null,o=t(r);if(o.src==null)return;let a=yn(e.container,o.src),i=o.origins&&o.onMessage?Z(o.origins,o.onMessage):void 0,s=o.poll&&r!=null?vn({transport:e.form.transport,...o.poll}):void 0;return()=>{i?.(),s?.(),a.remove()}}),vn=({transport:e,path:n,onResult:t,intervalMs:r=2e3,timeoutMs:o=3e5})=>{let a=Date.now(),i=!1,s=null,d=()=>{i=!0,s!=null&&clearInterval(s),s=null},l=async()=>{if(i)return;if(Date.now()-a>o)return d();let u=await e.get(n);i||!u.ok||t(u.data)==="stop"&&d()};return l(),s=setInterval(()=>{l()},r),d};var ct=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=X(n),r=t.split("/").pop()?.split("?")[0]??"surface",o=t.replace(/^https?:\/\/(app\.)?cal\.com\//,""),a=`surface-cal-${e.question.questionId}`,i=document.createElement("div");i.id=a,e.container.appendChild(i);let s=l=>{let u=l.detail?.data?.booking?.uid;e.confirmBooking({uri:u?`https://app.cal.com/booking/${u}`:"",raw:l.detail})};window.addEventListener(`CAL:${r}:bookingSuccessful`,s);let d=j(async()=>{await W("https://app.cal.com/embed/embed.js");let l=window.Cal;l&&(l("init",r,{origin:"https://cal.com"}),l.ns?.[r]?.("inline",{elementOrSelector:`#${a}`,calLink:o,config:{...e.prefill.name&&{name:e.prefill.name},...e.prefill.email&&{email:e.prefill.email}}}))});return()=>{window.removeEventListener(`CAL:${r}:bookingSuccessful`,s),d(),i.remove()}};var pt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=!1,r=(a,i)=>{t||(t=!0,e.confirmBooking({uri:a,raw:i}))},o=e.content.addSchedulerQueryParams!==!1;return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed_domain:"1",embed_type:"Inline",...o&&{hide_event_type_details:"1",hide_gdpr_banner:"1"},...Object.keys(e.urlParams).length>0?e.urlParams:{name:e.prefill.name,email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`}}),origins:[{exact:"https://calendly.com"}],onMessage:i=>{let s=i;typeof s?.event!="string"||!s.event.startsWith("calendly.")||(s.event==="calendly.event_type_viewed"&&e.emit({type:"viewed"}),s.event==="calendly.date_and_time_selected"&&e.emit({type:"slot_selected"}),s.event==="calendly.event_scheduled"&&r(s.payload?.invitee?.uri??"",i))},poll:{path:`/api/v1/calendly/check-event/${a}`,onResult:i=>i.status==="pending"?"continue":i.status==="canceled"?(t&&e.cancelBooking(),"stop"):typeof i.url=="string"&&i.url&&i.responseId===a?(r(i.url,i),"stop"):t?"stop":"continue"}})})};var mt=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams}),origins:[{hostSuffix:"chilipiper.com"}],onMessage:t=>{let r=t;r?.action==="booking-confirmed"&&e.confirmBooking({uri:r.args?.eventId??"",raw:t})}})}):q(e.question,"dataUrl")};var ft=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams})})}):q(e.question,"dataUrl")};var gt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=B(n,{embed:"true",...e.urlParams});if(t==null)return()=>{};let r=`surface-hubspot-${e.question.questionId}`,o=document.createElement("div");o.id=r,o.className="meetings-iframe-container",o.dataset.src=t,e.container.appendChild(o);let a=Z([{exact:"https://meetings.hubspot.com"},{hostRegex:/^meetings-[a-z0-9]+\.hubspot\.com$/}],s=>{s?.meetingBookSucceeded===!0&&e.confirmBooking({uri:" ",raw:s})}),i=j(async()=>{await W("https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js"),window.MeetingsEmbedCode?.createMeetingsIframe(`#${r}`)});return()=>{a(),i(),o.remove()}};var bn=["reclaim.ai","reclaim.com","reclaimai.com"],yt=e=>{let n=e.content.dataUrl,t=(()=>{try{return new URL(X(n??"")).hostname}catch{return null}})(),r=t!=null&&bn.some(o=>t===o||t.endsWith(`.${o}`));return!n||!r?q(e.question,"a valid reclaim.ai dataUrl"):V(e,{needsResponseId:!0,build:o=>({src:B(n,{...o!=null&&{"data-responseId":o},...e.urlParams}),poll:{path:`/api/v1/reclaimai/check-event/${o}`,onResult:a=>{if(a.status==="pending")return"continue";if(a.meetingId!=null&&a.responseId===o){let i=[a.schedulingLinkId,a.meetingId].find(s=>typeof s=="string"&&s.length>0);return e.confirmBooking({uri:i??"",raw:a}),"stop"}return"continue"}}})})};var ht=e=>{let n=e.content.revenueHeroRouterId;if(!n)return q(e.question,"revenueHeroRouterId");let t=`surface-revenuehero-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=Z([{hostSuffix:"revenuehero.io"}],i=>{let s=i;s?.type!=="MEETING_BOOKED"||s.meeting==null||e.confirmBooking({uri:s.meeting.id??"",...s.meeting.attributes?.meeting_time!=null&&{meetingTime:s.meeting.attributes.meeting_time},raw:i})}),a=j(async()=>{await W("https://assets.revenuehero.io/scheduler.min.js");let i=window.RevenueHero;if(!i)return;let s=new i({routerId:n,showLoader:!1}),d={...e.urlParams,...e.prefill.email&&{email:e.prefill.email},...e.prefill.name&&{name:e.prefill.name}},l=await s.submit(d);s.dialog.setEmbedTarget(`#${t}`),s.dialog.open(l)});return()=>{o(),a(),r.remove()}};var vt=e=>{let n=e.content.savvyCalLinkId;if(!n)return q(e.question,"savvyCalLinkId");let t=`surface-savvycal-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=i=>{let s=i.detail;s&&e.confirmBooking({uri:s.url??"",raw:s})};window.addEventListener("savvycal.scheduled",o);let a=j(async()=>{await W("https://embed.savvycal.com/v1/embed.js");let i=window.SavvyCal;if(!i)return;i("init");let s=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");i("inline",{link:n,selector:`#${t}`,...s&&{displayName:s},...e.prefill.email&&{email:e.prefill.email}})});return()=>{window.removeEventListener("savvycal.scheduled",o),a(),r.remove()}};var bt=e=>new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,n])=>n!=null))),ge=({transport:e,preview:n=!1})=>{let t=n?"true":void 0,r=o=>{if(!o.ok)return o;let a=o.data.data;return a?.id?{ok:!0,data:a}:{ok:!1,error:{kind:"http",status:200,body:o.data}}};return{getPublicEventType:o=>e.get(`/api/v1/scheduler/event-types/${o}/public`),getAvailabilitySummary:({eventTypeId:o,timezone:a})=>{let i=new URLSearchParams({eventTypeId:o,timezone:a??Intl.DateTimeFormat().resolvedOptions().timeZone});return e.get(`/api/v1/scheduler/availability-summary?${i}`)},getMonthAvailability:({eventTypeId:o,month:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let[u,c]=a.split("-").map(Number),p=bt({eventTypeId:o,month:String(c),year:String(u),timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/availability?${p}`)},getSlots:({eventTypeId:o,date:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let u=bt({eventTypeId:o,date:a,timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/slots?${u}`)},book:async({eventTypeId:o,startTime:a,endTime:i,timezone:s,inviteeName:d,inviteeEmail:l,duration:u,intakeResponses:c,guestEmails:p,captchaToken:A,responseId:h,leadSessionId:f,fingerprint:y,hostRouting:S})=>{if(n)return{ok:!0,data:{id:"preview-booking-"+Date.now(),startTime:a,endTime:i,timezone:s,inviteeName:d||"Test User",inviteeEmail:l||"test@example.com",meetingJoinLink:null,cancelToken:"preview-cancel-"+Date.now(),rescheduleToken:"preview-reschedule-"+Date.now(),attendees:[{name:"Host",email:"host@example.com",isHost:!0}]}};let g=await e.post("/api/v1/scheduler/book",{eventTypeId:o,startTime:a,timezone:s,inviteeName:d,inviteeEmail:l.trim(),...u?{duration:u}:{},...c&&Object.keys(c).length>0?{intakeResponses:c}:{},...p&&p.length>0?{guestEmails:p}:{},...A?{captchaToken:A}:{},meta:{source:"form",...h?{responseId:h}:{},...f?{leadSessionId:f}:{},...y?{fingerprint:y}:{},...S?{hostRouting:S}:{}}});return r(g)},reschedule:async({bookingId:o,rescheduleToken:a,newStartTime:i,timezone:s})=>{let d=await e.post(`/api/v1/scheduler/bookings/${o}/reschedule`,{rescheduleToken:a,newStartTime:i,timezone:s});return r(d)}}},St=e=>{let n=e.attendees?.find(t=>t.isHost);return{type:"DynamicScheduler",eventScheduled:!0,uri:e.id,meetingTime:e.startTime,meetingEndTime:e.endTime,ownerEmails:n?.email??"",guestEmails:e.inviteeEmail,inviteeName:e.inviteeName,googleMeetLink:e.meetingJoinLink??""}};var kt=e=>{let n=e.content.eventTypeId;if(!n)throw new Error(`mountScheduler: Surface scheduler question "${e.question.questionId}" has no eventTypeId on the record.`);let t=ge({transport:e.form.transport,preview:e.form.preview}),r=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");return e.mergeAnswer({eventScheduled:!1,uri:"",schedulerSubStep:"date"}),de({container:e.container,scheduler:t,eventTypeId:n,prefill:{...r&&{name:r},...e.prefill.email&&{email:e.prefill.email}},formatters:e.formatters,identity:async()=>{let o=await e.ensureResponseId(),a=e.form.identity();return{...o!=null&&{responseId:o},...a.leadSessionId!=null&&{leadSessionId:a.leadSessionId},...a.fingerprint!=null&&{fingerprint:a.fingerprint}}},onEvent:o=>{if(o.type==="booking_confirmed"){let{booking:i}=o,s=i.attendees?.find(d=>d.isHost);e.confirmBooking({uri:i.id,meetingTime:i.startTime,meetingEndTime:i.endTime,inviteeName:i.inviteeName,guestEmails:i.inviteeEmail,ownerEmails:s?.email??"",joinLink:i.meetingJoinLink??"",raw:i},{schedulerSubStep:"booked"});return}let a={date_selected:"time",form_opened:"form"}[o.type];a&&e.mergeAnswer({schedulerSubStep:a}),e.emit(o)},onComplete:()=>{}})};var Sn={hostEmail:"ownerEmails",startTime:"meetingTime",endTime:"meetingEndTime",joinUrl:"googleMeetLink",duration:"durationMinutes",timezone:"hostTimezone"},wt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let[t,...r]=(e.prefill.name??"").split(/\s+/),o=e.prefill.lastName??(r.length>0?r.join(" "):void 0);return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed:"true",origin:window.location.origin,...t&&{firstname:t},...o&&{lastname:o},...e.prefill.email&&{email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`},...e.urlParams}),origins:[{exact:"https://scheduler.zoom.us"}],onMessage:i=>{let s=i;if(s?.type!=="bookingForm")return;let d=s.payload??{},l=[d.bookerFirstName,d.bookerLastName].filter(Boolean).join(" ");e.confirmBooking({uri:d.scheduledEventId??"",guestEmails:d.bookerEmail??"",...l&&{inviteeName:l},raw:i})},poll:{path:`/api/v1/zoom/check-event/${a}`,onResult:i=>{if(i.status==="pending"||i.hostEmail==null&&i.startTime==null)return"continue";let s={};for(let[d,l]of Object.entries(Sn))typeof i[d]=="string"&&(s[l]=i[d]);return e.mergeAnswer(s,{save:!0}),"stop"}}})})};var It={Surface:kt,Calendly:pt,Cal:ct,SavvyCal:vt,ChiliCal:mt,Hubspot:gt,RevenueHero:ht,Zoom:wt,ReclaimAI:yt,Clari:ft};var Et="surface-scheduler-styles",kn=`
2
- \${--surface-scheduler-accent:#2563eb;--surface-scheduler-border:#e2e8f0;--surface-scheduler-text:#0f172a;--surface-scheduler-muted:#64748b;--surface-scheduler-radius:8px;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--surface-scheduler-text)}
3
- %{display:flex;flex-direction:column;gap:12px;max-width:26rem;padding:16px;border:1px solid var(--surface-scheduler-border);border-radius:var(--surface-scheduler-radius)}
4
- %-month,%-day{margin:0;font-size:1rem;font-weight:600}
5
- %-month-nav{display:flex;gap:8px}
6
- $ button{font:inherit;cursor:pointer;border-radius:calc(var(--surface-scheduler-radius) - 2px)}
7
- %-month-button,%-back,%-retry{padding:4px 10px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-muted)}
8
- %-month-button:hover,%-back:hover{color:var(--surface-scheduler-text)}
9
- %-dates,%-slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr));gap:8px;margin:0;padding:0;list-style:none}
10
- %-date-button,%-slot-button{width:100%;padding:8px 6px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-text)}
11
- %-date-button:hover,%-slot-button:hover{border-color:var(--surface-scheduler-accent);color:var(--surface-scheduler-accent)}
12
- %-form{display:flex;flex-direction:column;gap:8px}
13
- %-name,%-email{font:inherit;padding:8px 10px;border:1px solid var(--surface-scheduler-border);border-radius:calc(var(--surface-scheduler-radius) - 2px)}
14
- %-name:focus,%-email:focus{outline:2px solid var(--surface-scheduler-accent);outline-offset:-1px}
15
- %-submit{padding:8px 14px;border:0;background:var(--surface-scheduler-accent);color:#fff}
16
- %-submit:disabled{opacity:.6;cursor:default}
17
- %-loading,%-no-dates{color:var(--surface-scheduler-muted)}
18
- %-error{color:#b91c1c;margin:0}
19
- %-booked{font-weight:600;color:var(--surface-scheduler-accent)}
20
- .surface-scheduler-frame{display:block;min-height:640px}
21
- `,Tt=()=>{if(document.getElementById(Et))return;let e=document.createElement("style");e.id=Et,e.textContent=kn.replace(/%/g,"$ .surface-booking").replace(/\$/g,".surface-scheduler"),document.head.appendChild(e)};var ye=(e,n)=>{for(let t of Object.values(e.state().answers))if(t[n]!=null)return t[n]},Be=(e,n)=>{for(let t of n){let r=e?.[t];if(typeof r=="string"&&r.length>0)return r}},wn=(e,n,t)=>({name:t?.name??Be(n.linkNameToStep&&ye(e,n.linkNameToStep.questionId),["fullName","firstName","input"]),lastName:t?.lastName??Be(n.linkLastNameToStep&&ye(e,n.linkLastNameToStep.questionId),["lastName","input"]),email:t?.email??Be(n.linkEmailToStep&&ye(e,n.linkEmailToStep.questionId),["email","emailAddress","workEmailAddress","input"])}),In=(e,n)=>{let{content:t}=e;if(e.componentType!=="DynamicScheduler")return t;let r=t.calendars??[],o;if(n!=null){if(o=r.find(s=>s.name===n),!o){let s=r.map(d=>String(d.name)).join(", ")||"(none)";throw new Error(`mountScheduler: no calendar named "${n}" on question "${e.questionId}" \u2014 available: ${s}.`)}}else if(o=t.defaultCalendar??void 0,!o&&r.length===1&&(o=r[0]),!o)throw new Error(`mountScheduler: question "${e.questionId}" routes between ${r.length} calendars with no default \u2014 pass calendarId to choose one (condition evaluation is the caller's own routing).`);let a={...t},i=[o.dataUrl,o.url].find(s=>typeof s=="string"&&s.length>0);i!=null&&(a.dataUrl=i);for(let s of["eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);return a},En=(e,{questionId:n,stepId:t})=>{if(!e.runtimeConfig)throw new Error("mountScheduler: no record to read scheduler config from (the form was booted with caller-provided steps) \u2014 init without `steps`, or mount the widget manually.");let r=me(e.runtimeConfig.config),o=r.filter(i=>(n==null||i.questionId===n)&&(t==null||i.stepId===t));if(o.length===1)return o[0];let a=r.map(i=>`"${i.questionId}" (${i.calendarType}, step "${i.stepId}")`).join(", ");throw new Error(o.length===0?`mountScheduler: no scheduler question${n?` "${n}"`:""}${t?` on step "${t}"`:""} \u2014 the record has: ${a||"none"}.`:`mountScheduler: ${o.length} scheduler questions match \u2014 pass questionId. Candidates: ${a}.`)},Rt=({form:e,container:n,questionId:t,stepId:r,styled:o=!0,persist:a=!0,prefill:i,formatters:s,calendarId:d,onEvent:l,onComplete:u})=>{let c=En(e,{questionId:t,stepId:r}),p=c.calendarType,A=It[p];if(!A)throw new Error(`mountScheduler: unsupported provider "${c.calendarType}" on question "${c.questionId}".`);let h=In(c,d),f=!1,y=!1,S=w=>{if(f)return;if(w.type==="viewed"){if(y)return;y=!0}let _={...w,questionId:c.questionId,stepId:c.stepId,provider:p};e.notifyScheduler(_);try{l?.(_)}catch(b){console.warn("Surface SDK: mountScheduler onEvent handler failed",b)}},g=(w,_)=>{a&&(e.setAnswer(c.questionId,{type:c.componentType,...w}),_?.save&&!e.state().finished&&e.savePartial())},M=(w,_)=>{let b={...w,provider:p},D={eventScheduled:!0,uri:b.uri},I={meetingTime:b.meetingTime,meetingEndTime:b.meetingEndTime,ownerEmails:b.ownerEmails,guestEmails:b.guestEmails,inviteeName:b.inviteeName,googleMeetLink:b.joinLink};for(let[v,L]of Object.entries(I))L!==void 0&&(D[v]=L);g({...D,..._},{save:!0}),S({type:"booking_confirmed",booking:b});try{u?.(b)}catch(v){console.warn("Surface SDK: mountScheduler onComplete handler failed",v)}},k=w=>{g({eventScheduled:!1,eventCancelled:!0,...w!=null&&{cancelReason:w}},{save:!0}),S({type:"booking_cancelled",...w!=null&&{reason:w}})},x=async()=>e.preview?null:(e.state().responseId==null&&a&&await e.savePartial(),e.state().responseId);o&&(Tt(),n.classList.add("surface-scheduler"));let R=Object.fromEntries(Object.entries(h.dataUrlParams??{}).flatMap(([w,_])=>{let b=ye(e,_.questionId)?.[_.variable];return typeof b=="string"&&b.length>0?[[w,b]]:[]})),U=A({form:e,container:n,question:c,content:h,prefill:wn(e,h,i),urlParams:R,formatters:s,styled:o,emit:S,confirmBooking:M,cancelBooking:k,mergeAnswer:g,ensureResponseId:x});return S({type:"viewed"}),()=>{f||(f=!0,o&&n.classList.remove("surface-scheduler"),U())}};var Tn="/api/v1/edge/emailValidation",At=e=>({email:e,isValid:!0,status:"unknown",reason:"validation_failed",failed:!0}),Rn=(e,n)=>!n||typeof n.isValid!="boolean"?At(e):{email:e,isValid:n.isValid,status:n.status,reason:n.reason,...n.blacklistEntryIds?.length?{blacklistEntryIds:n.blacklistEntryIds}:{},...n.validationSuccessfullyRan===!1?{failed:!0}:{}},he=({transport:e,environmentId:n,preview:t=!1})=>{let r=new Map,o=a=>{let i=[...new Set(a.map(d=>d.trim()).filter(d=>d!==""))];if(t)for(let d of i)r.has(d)||r.set(d,Promise.resolve({email:d,isValid:!0,status:"preview"}));let s=i.filter(d=>!r.has(d));if(s.length>0){let d=e.post(Tn,{emails:s,environmentId:n}).then(l=>l.ok?l.data.data??{}:{}).catch(()=>({}));for(let l of s)r.set(l,d.then(u=>Rn(l,u[l])))}return Promise.all(i.map(d=>r.get(d)))};return{validateBatch:o,validate:async a=>{let[i]=await o([a]);return i??At(a.trim())}}};var An="/api/v1/responses/",_t="/api/v1/responses/update",_n="/api/v1/responses/getResponse",ve=async(e,n)=>{let t=await e.post(An,n,{credentials:!0});if(!t.ok)return t;let r=t.data.data?.id;return r?{ok:!0,data:{responseId:r,leadId:t.data.data?.meta?.leadId??null,resumeToken:t.data.data?.resumeToken??null}}:{ok:!1,error:{kind:"http",status:200,body:t.data}}},ee=(e,n)=>{e.beacon(_t,n)},Ct=(e,n)=>e.post(_t,n,{keepalive:!0,credentials:!0}),Cn=e=>typeof e?.questionId=="string"&&typeof e?.response=="object"&&e.response!==null,xt=async(e,{responseId:n,resumeToken:t})=>{let r=await e.get(`${_n}?rid=${encodeURIComponent(n)}&rt=${encodeURIComponent(t)}`);return r.ok?{ok:!0,data:{answers:(Array.isArray(r.data.data?.data)?r.data.data.data:[]).filter(Cn).filter(a=>a.response.type!=="URL_DATA")}}:r};var Q="https://forms.withsurface.com",Pt="0.1.0",Ve=(e={})=>({...e,"X-Surface-Sdk-Version":Pt}),xn=e=>`${e}${e.includes("?")?"&":"?"}sdv=${Pt}`,be=({apiBaseUrl:e=Q}={})=>{let n=e.replace(/\/$/,""),t=i=>`${n}${i}`;return{get:async i=>{try{let s=await fetch(t(i),{headers:Ve()});if(!s.ok){let d=await s.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:s.status,body:d}}}return{ok:!0,data:await s.json()}}catch(s){return{ok:!1,error:{kind:"network",cause:s}}}},post:async(i,s,d)=>{try{let l=await fetch(t(i),{method:"POST",headers:Ve({"Content-Type":"application/json"}),body:JSON.stringify(s),...d?.keepalive?{keepalive:!0}:{},...d?.credentials?{credentials:"include"}:{}});if(!l.ok){let u=await l.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:l.status,body:u}}}return{ok:!0,data:await l.json()}}catch(l){return{ok:!1,error:{kind:"network",cause:l}}}},beacon:(i,s)=>{let d;try{d=JSON.stringify(s)}catch{return!1}let l=xn(t(i));try{if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&navigator.sendBeacon(l,new Blob([d],{type:"application/json"})))return!0}catch{}try{fetch(l,{method:"POST",keepalive:!0,credentials:"include",headers:Ve({"Content-Type":"application/json"}),body:d}).catch(()=>{})}catch{}return!1}}};var Mt=["firstName","lastName","fullName","emailAddress","workEmailAddress","phoneNumber","companyName","numberOfEmployees","websiteUrl","title","streetAddress","aptSuiteEtc","city","state","country","zipCode","companyRevenue","profilePictureUrl"];var Se=()=>{let e=new Map;return{on:(n,t)=>{let r=e.get(n)??new Set;return r.add(t),e.set(n,r),()=>{r.delete(t)}},emit:(n,t)=>{e.get(n)?.forEach(r=>{try{r(t)}catch(o){console.error(`Surface SDK: "${String(n)}" handler threw`,o)}})}}};var Pn="/api/v1/pushEvent",Mn=/bot|crawl|spider|slurp|baidu|bingpreview|googlebot|yandex|duckduck|ahrefs|semrush|facebookexternalhit|embedly|quora link preview|pinterest|twitterbot|linkedinbot|whatsapp|telegram|discord|headless|lighthouse|pagespeed/i,Ln=()=>{let e=navigator.userAgent;return e?Mn.test(e):!1},On=e=>!!(e?.type&&e?.entityType&&e?.entityId),ke=({sessionId:e,formId:n,currentStepId:t,nextStepId:r,stepCompletionTime:o})=>({events:[{type:"form_step_submitted",entityType:"form_step",entityId:n,stepId:t,leadSessionId:e,properties:[{key:"stepCompletionTime",value:o}]},{type:"form_step_viewed",entityType:"form_step",entityId:n,stepId:r,leadSessionId:e,properties:[]}]}),we=({transport:e,preview:n=!1})=>({push:t=>{if(n||typeof navigator>"u")return;let r="events"in t?t.events:[t];Ln()||r.some(o=>!On(o))||e.beacon(Pn,t)}});var Ie=e=>{let n=je(e),t=!1;return r=>t||He(n,r)?!1:(t=!0,!0)},je=e=>{if(Array.isArray(e))return e.map(je);if(e!==null&&typeof e=="object"){let n={};for(let[t,r]of Object.entries(e))n[t]=je(r);return n}return e},He=(e,n)=>{if(Object.is(e,n))return!0;if(Array.isArray(e)||Array.isArray(n))return!Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?!1:e.every((t,r)=>He(t,n[r]));if(e!==null&&n!==null&&typeof e=="object"&&typeof n=="object"){let t=Object.keys(e),r=Object.keys(n);return t.length!==r.length?!1:t.every(o=>He(e[o],n[o]))}return!1};var Ke=(e,n)=>{let t=[],r={},o;for(let a in e){let i=e[a];for(let s in i){let d=i[s];!o&&d?.eventScheduled===!0&&typeof d.uri=="string"&&d.uri.length>0&&!d.uri.includes("calendly.com")&&!d.uri.includes("cal.com")&&(o=d.uri),t.push({questionId:s,response:{...i[s]}})}}for(let a in n){let i=n[a];i.type!=="SCHEDULER_AVAILABILITY_DATA"&&(t.push({questionId:a,response:{...i}}),i.type==="APOLLO_EMAIL_ENRICHMENT"&&i.processed&&(r=i.data??{}))}return{responses:t,enrichedFields:r,bookingId:o}},Lt=({formId:e,answers:n,externalStates:t,submittingOnStepId:r,finished:o,invalidResponse:a,trackCookies:i,meta:s={},personAttributeEnrichedFields:d,fingerprint:l,leadSessionId:u})=>{let{responses:c,enrichedFields:p,bookingId:A}=Ke(n,t),h=i?s:Object.fromEntries(Object.entries(s).filter(([f])=>f!=="cookies"));return{responses:c,enrichedFields:d??p??{},formId:e,finished:o,invalidResponse:a,stepId:r,fingerprint:l,leadSessionId:u,meta:A?{...h,bookingId:A}:h}},Ee=e=>({...Lt(e),responseShapeVersion:"2.0"}),z=e=>({...Lt(e),responseId:e.responseId});var Te=({formId:e,environmentId:n,steps:t,transport:r,resolveNextStep:o,trackPartialResponses:a=!0,trackCookies:i=!1,externalStates:s={},meta:d={},identity:l,pushEvents:u,formJourney:c,preview:p=!1,resume:A})=>{if(t.length===0)throw new Error("createFormEngine requires at least one step");let h=o??(m=>{let E=t.findIndex(H=>H.id===m),$=t[E+1];return $?{stepId:$.id,reason:"linear"}:"END"}),f=Se(),y=new Set,S=!0,g,M=()=>{S=!0,y.forEach(m=>m())},k=()=>l?.()??{},x={},R=t[0].id,U=A?.responseId??null,w=null;if(A?.answers){let m={};for(let[E,$]of Object.entries(A.answers))m[E]={...$};x[R]=m}let _=!1,b=null,D=!1,I=Date.now(),v=[],L=Ie(x);c?.setFormId(e),U!=null&&c?.setResponseId(U),c?.recordEntry(R);let O=async(m,E,$)=>{if(p)return;let H={formId:e,answers:x,externalStates:s,submittingOnStepId:m,finished:E,invalidResponse:$,trackCookies:i,meta:d,fingerprint:k().fingerprint,leadSessionId:k().leadSessionId};if(U==null){let K=await ve(r,Ee(H));if(!K.ok){K.error.kind==="network"&&u?.push({type:"response_submission_error",entityType:"response",entityId:e,stepId:m,leadSessionId:k().leadSessionId,properties:[{key:"error",value:"network"}]}),f.emit("error",{scope:"submit",error:K.error});return}U=K.data.responseId,w=K.data.resumeToken,c?.setResponseId(U),u?.push({type:"response_submission_created",entityType:"response",entityId:e,stepId:m,leadSessionId:k().leadSessionId,properties:[{key:"responseId",value:U}]})}else if(E){let K=await Ct(r,z({...H,responseId:U}));if(!K.ok){ee(r,z({...H,responseId:U})),f.emit("error",{scope:"submit",error:K.error});return}}else ee(r,z({...H,responseId:U}));M(),f.emit("saved",{responseId:U,finished:E,resumeToken:w})},F=Promise.resolve(),T=m=>{let E=F.then(()=>_?void 0:m());return F=E.catch(()=>{}),E},P=()=>{if(!_||b==null)return;let m=b;F=F.then(()=>{if(U!=null)return O(m.stepId,!0,m.invalid)}).catch(()=>{})},C=null,N=m=>{if(_)return Promise.resolve();if(C)return m?C.then(()=>N(!0)):C;let E=T(()=>Zt(m)).finally(()=>{C===E&&(C=null)});return C=E,E},G=m=>{let E=R;for(;v.length>0&&R!==m;)R=v.pop();M(),c?.recordTransition({fromStepId:E,toStepId:R,reason:"back_nav"}),f.emit("stepChanged",{fromStepId:E,toStepId:R})},se=m=>{if(!t.some($=>$.id===m))return Promise.reject(new Error(`goToStep: no step with id "${m}"`));if(_)return Promise.resolve();if(C)return C.then(()=>se(m));if(m===R)return Promise.resolve();if(v.includes(m))return G(m),Promise.resolve();let E=T(async()=>{m!==R&&(f.emit("stepCompleted",{stepId:R}),await nt({stepId:m,reason:"conditional_match"}))}).finally(()=>{C===E&&(C=null)});return C=E,E},tt=()=>{if(_)return Promise.resolve();if(C)return C.then(()=>tt());let m=T(async()=>{f.emit("stepCompleted",{stepId:R}),await rt(!0)}).finally(()=>{C===m&&(C=null)});return C=m,m},nt=async m=>{let E=R;u?.push(ke({sessionId:k().leadSessionId,formId:e,currentStepId:E,nextStepId:m.stepId,stepCompletionTime:(Date.now()-I)/1e3})),c?.recordTransition({fromStepId:E,toStepId:m.stepId,reason:m.reason??"linear"}),a&&await O(E,!1,!1),v.push(E),R=m.stepId,M(),f.emit("stepChanged",{fromStepId:E,toStepId:R})},Xt=m=>{let E=t.find(H=>H.endStepKind===m);if(!E||E.id===R)return;let $=R;v.push($),R=E.id,M(),f.emit("stepChanged",{fromStepId:$,toStepId:R})},rt=async m=>{let E=R;_=!0,b={stepId:E,invalid:m},await O(E,!0,m),Xt(m?"disqualified":"thank_you"),m?(c?.recordTerminal({outcome:"disqualified",disqualification:{reason:"conditional_match",atStepId:E}}),f.emit("disqualified",{stepId:E})):(c?.recordTerminal({outcome:"completed"}),u?.push({type:"form_completed",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[],environmentId:n,leadId:k().leadId}),f.emit("completed",{formId:e})),M()},Zt=async m=>{let E=h(R,x),$=m||E==="END"||E==="INVALID"||E==null;if(f.emit("stepCompleted",{stepId:R}),!$){await nt(E);return}await rt(E==="INVALID")};return{setAnswer:(m,E)=>{let $=x[R]??(x[R]={});$[m]={...$[m],...E},L(x)&&(u?.push({type:"form_started",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[]}),f.emit("started",{formId:e})),M(),P()},setExternalState:(m,E)=>{s[m]=E,M(),P()},mergeMeta:m=>{Object.assign(d,m),P()},next:()=>N(!1),goToStep:se,submit:()=>N(!0),disqualify:tt,back:()=>{let m=v.pop();if(m==null||_)return;let E=R;R=m,M(),c?.recordTransition({fromStepId:E,toStepId:m,reason:"back_nav"}),f.emit("stepChanged",{fromStepId:E,toStepId:m})},savePartial:()=>{let m=R;return T(()=>O(m,!1,!1))},notifyScheduler:m=>f.emit("scheduler",m),flush:()=>F.then(()=>{}),markViewed:()=>{D||(D=!0,u?.push({type:"form_viewed",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[],environmentId:n,leadId:k().leadId}),u?.push({type:"form_step_viewed",entityType:"form_step",entityId:e,stepId:t[0].id,leadSessionId:k().leadSessionId,properties:[]}),f.emit("viewed",{formId:e}))},on:f.on,state:()=>(S&&(g={currentStepId:R,answers:x,externalStates:s,responseId:U,resumeToken:w,finished:_},S=!1),g),subscribe:m=>(y.add(m),()=>y.delete(m))}};var Ot=400,Fn=(e,n="https")=>!e||e.startsWith(n)?e:`${n}://${e}`,We=(e,{leadId:n,sessionId:t}={})=>{if(!e||!e.trim())return"";try{let r=new URL(Fn(e));return n&&r.searchParams.set("leadId",n),t&&r.searchParams.set("sessionId",t),r.toString()}catch{return e}},Ft=({url:e,redirectType:n="CurrentWindow",leadId:t,sessionId:r,preview:o=!1})=>{if(!e||o||typeof window>"u")return;let a=We(e,{leadId:t,sessionId:r});a&&(n==="CurrentWindow"?window.location.href=a:n==="NewTab"&&window.open(a,"_blank"))};var Je=e=>{let n=new URL(e);if(!n.search)return{};let t={};return new URLSearchParams(n.search).forEach((r,o)=>{t[o]=r}),t},Qe=e=>{let n={};for(let t of e.split(";")){let r=t.trim(),o=r.indexOf("=");if(o<=0)continue;let a=r.substring(o+1);try{n[r.substring(0,o)]=decodeURIComponent(a)}catch{n[r.substring(0,o)]=a}}return n},Re=({defaultUrl:e,trackCookies:n=!1}={})=>{let t=typeof window<"u",r={type:"URL_DATA",fullUrl:e??(t?window.location.href:void 0),referrer:t&&typeof document<"u"?document.referrer||"":void 0};if(r.fullUrl)try{r.params=Je(r.fullUrl)}catch{}return n?r.cookies=t&&typeof document<"u"?Qe(document.cookie):{}:r.cookies={},r};var ze=e=>{let n=e.indexOf("_");return{originalId:e,questionId:n>=0?e.slice(0,n).trim():e,fieldName:n>=0?e.slice(n+1).trim():null}},Dn=new Set(["url","referrer","cookies"]),Dt=e=>{let n=typeof e=="string"?new URLSearchParams(e):e,t=null;for(let r of n.keys()){if(Dn.has(r))continue;let{originalId:o,questionId:a,fieldName:i}=ze(r);if(i==null)continue;let s={originalId:o,questionId:a,fieldName:i,value:n.get(r)};t??(t=Object.create(null)),t[a]=[...t[a]??[],s]}return t};var Ae=(e,n)=>{if(typeof window>"u")return()=>{};let t=r=>{let{started:o,formId:a,stepId:i,sessionId:s}=n();!o||r.persisted||e.push({type:"form_step_dropoff",entityType:"form_step",entityId:a,stepId:i,leadSessionId:s,properties:[]})};return window.addEventListener("pagehide",t),()=>window.removeEventListener("pagehide",t)};var Un="/api/v1/form-journey/track";var Nn=new Set(["completed","disqualified","dropped_off","partial"]),_e=({transport:e,preview:n=!1})=>{let t={responseId:null,formId:null,nextOrdinal:1,enteredAt:new Map,pendingClose:null,visits:[],truncated:!1,terminal:{},frozen:!1,flushScheduled:!1},r=()=>{t.flushScheduled=!1,!n&&(!t.responseId||!t.formId||t.visits.length===0&&!t.terminal.outcome||(e.beacon(Un,{responseId:t.responseId,formId:t.formId,events:t.visits,...t.terminal}),t.terminal={}))},o=()=>{t.flushScheduled||(t.flushScheduled=!0,queueMicrotask(()=>{t.flushScheduled&&r()}))},a=s=>{if(!t.pendingClose)return;let{ordinal:d,stepId:l}=t.pendingClose,u=t.enteredAt.get(d),c=t.visits.find(A=>A.ordinal===d),p=u?Date.parse(s)-Date.parse(u):null;c?(c.exitedAt=s,c.durationMs=p):t.visits.push({ordinal:d,stepId:l,enteredAt:u??s,exitedAt:s,durationMs:p,fromStepId:null,transitionReason:"initial"}),t.pendingClose=null},i=s=>t.visits.length>=50?(t.truncated=!0,!1):(t.visits.push(s),!0);return{hasRecordedTransition:()=>t.nextOrdinal>1,setResponseId:s=>{t.responseId=s,o()},setFormId:s=>{t.formId=s,o()},recordEntry:s=>{if(t.frozen||t.truncated)return;let d=new Date().toISOString();t.nextOrdinal===1&&(t.enteredAt.set(1,d),t.pendingClose={ordinal:1,stepId:s},t.nextOrdinal=2)},recordTransition:({fromStepId:s,toStepId:d,reason:l,transitionMeta:u})=>{if(t.frozen||t.truncated)return;let c=new Date().toISOString();a(c);let p=t.nextOrdinal++;t.enteredAt.set(p,c);let A=i({ordinal:p,stepId:d,enteredAt:c,exitedAt:null,durationMs:null,fromStepId:s,transitionReason:l,transitionMeta:u??null});t.pendingClose=A?{ordinal:p,stepId:d}:null,o()},recordTerminal:({outcome:s,disqualification:d})=>{if(t.frozen)return;let l=new Date().toISOString();a(l),t.terminal={outcome:s,disqualification:d?{reason:d.reason,matched:d.matched}:void 0,disqualifiedAtStepId:d?.atStepId,disqualifiedTriggerStepId:d?.triggerStepId},Nn.has(s)&&(t.frozen=!0),s==="in_progress"?r():o()}}};async function Ye(e){let n=new TextEncoder().encode(e),t=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}var Ce=async e=>{let n=navigator.userAgentData||{},t={deviceType:/Mobi|Android/i.test(navigator.userAgent)?"Mobile":"Desktop",screen:{width:screen.width,height:screen.height,colorDepth:screen.colorDepth},userAgent:navigator.userAgent,browser:n.brands||n.uaList||[{brand:"unknown",version:"unknown"}],os:n.platform||"unknown",language:navigator.language,...navigator.plugins!=null?{plugins:Array.from(navigator.plugins).map(r=>r.name)}:{},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,environmentId:e};return{...t,id:await Ye(JSON.stringify(t))}};var qn="/api/v1/lead/identify",xe=({environmentId:e,fingerprintId:n,pageUrl:t,source:r="sdkForm",formId:o,leadId:a=null,sessionIdFromParams:i=null,referrer:s})=>{let d=new URL(t);return{environmentId:e,source:r,sourceURL:d.href.replace(/\/$/,""),sourceURLDomain:d.hostname,sourceURLPath:d.pathname.replace(/\/$/,""),sourceUrlSearchParams:d.search,fingerprint:n,formId:o,leadId:a,sessionIdFromParams:i,...s!=null?{referrer:s}:{}}},Pe=async(e,n)=>{let t=await e.post(qn,n,{keepalive:!0,credentials:!0});if(!t.ok)return null;let r=t.data.data?.data;return!r?.leadId||!r?.sessionId?null:{leadId:r.leadId,sessionId:r.sessionId,existing:r.existing,leadHasExistingBookingAttr:r.leadHasExistingBookingAttr,leadHasExistingEmailAttr:r.leadHasExistingEmailAttr}};var te="surfaceLeadData",Ut=6e5,Y=()=>{if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(te);if(!e)return null;let n=JSON.parse(e);return Date.now()>(n.expiry??0)?(localStorage.removeItem(te),null):{leadId:n.leadId,leadSessionId:n.leadSessionId,fingerprint:n.fingerprint,landingPageUrl:n.landingPageUrl,expiry:n.expiry}}catch{return null}},Me=e=>{if(!(typeof localStorage>"u"))try{localStorage.setItem(te,JSON.stringify({...e,expiry:Date.now()+6e5}))}catch{}};var ne=async({transport:e,environmentId:n,formId:t,pageUrl:r,source:o,preview:a=!1})=>{if(a||typeof window>"u")return null;let i=Y();if(i?.leadSessionId&&i?.fingerprint)return i;let s=r??window.location.href,d=await Ce(n),l=await Pe(e,xe({environmentId:n,fingerprintId:d.id,pageUrl:s,formId:t,source:o,leadId:i?.leadId??null,sessionIdFromParams:i?.leadSessionId??null}));if(l==null)return null;let u={leadId:l.leadId,leadSessionId:l.sessionId,fingerprint:d.id,landingPageUrl:s};return Me(u),u};var re="surface_journey_id",oe="surface_recent_visit",$n=5184e3,Bn=86400,Nt="/api/v1/lead/track",qt=e=>{if(typeof document>"u")return null;for(let n of document.cookie.split(";")){let t=n.trim(),r=t.indexOf("=");if(r===-1||t.substring(0,r)!==e)continue;let o=t.substring(r+1);try{return decodeURIComponent(o)}catch{return o}}return null},$t=(e,n,t,r)=>{if(typeof document>"u")return;let o=r?`; domain=${r}`:"";document.cookie=`${e}=${encodeURIComponent(n)}; path=/; max-age=${t}; samesite=lax${o}`},Ge=()=>{let e=typeof window>"u"?"":window.location?.hostname??"";if(!e||!e.includes("."))return;let n=e.split(".");return"."+(n.length===2?e:n.slice(1).join("."))},Le=({transport:e,environmentId:n})=>{let t=qt(re),r=()=>{t&&$t(re,t,$n,Ge())},o=d=>{let l=Y();return{...t?{id:t}:{},data:{type:"page_view",payload:{url:d,timestamp:new Date().toISOString(),referrer:typeof document>"u"?"":document.referrer||""}},metadata:{environmentId:n,...l?{...l.leadId?{leadId:l.leadId}:{},...l.leadSessionId?{leadSessionId:l.leadSessionId}:{},fingerprint:l.fingerprint,...l.landingPageUrl?{landingPageUrl:l.landingPageUrl}:{}}:{}}}},a=async d=>{if(typeof window>"u")return;let l=d??window.location.href;if(qt(oe)===l)return;let u=o(l);if(t&&e.beacon(Nt,u))r();else{let c=await e.post(Nt,u);c.ok&&c.data.data?.id&&(t=c.data.data.id),r()}$t(oe,l,Bn,Ge())};return{trackPageView:a,observeRouteChanges:()=>{if(typeof window>"u")return()=>{};let d=window.location.href,l=()=>{let p=window.location.href;p!==d&&(d=p,a(p))};window.addEventListener("popstate",l);let u=history.pushState,c=history.replaceState;return history.pushState=function(...p){u.apply(history,p),setTimeout(l,0)},history.replaceState=function(...p){c.apply(history,p),setTimeout(l,0)},()=>{window.removeEventListener("popstate",l),history.pushState=u,history.replaceState=c}},clear:()=>{let d=Ge(),l=d?`; domain=${d}`:"";typeof document>"u"||(document.cookie=`${re}=; path=/; max-age=0; samesite=lax${l}`,document.cookie=`${oe}=; path=/; max-age=0; samesite=lax${l}`,t=null)}}};var Vn="/api/v1/services/enrichment/realtime",Oe="selfServeEnrichment";var jn=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,Hn=/^(?:https?:\/\/)?(?:www\.)?([a-z0-9-]+(?:\.[a-z0-9-]+)+)/i,Bt=e=>{let n=e.trim();if(jn.test(n))return{email:n};let t=n.match(Hn)?.[1];return t?{domain:t}:null},Fe=({engine:e,transport:n,formId:t,sources:r})=>{let o=new Set,a=new Set,i,s,d=!1,l=async h=>{let f=Bt(h);if(!f)return;let y=f.email??f.domain;if(!(o.has(y)||a.has(y))){a.add(y);try{let S=await n.post(Vn,{formId:t,...f});if(d||!S.ok)return;let g=S.data.data??{};if(Object.keys(g).length===0)return;o.add(y);let M=e.state().externalStates[Oe],k=M?.type==="APOLLO_EMAIL_ENRICHMENT"?M.data??{}:{};e.setExternalState(Oe,{type:"APOLLO_EMAIL_ENRICHMENT",processed:!0,data:{...g,...k}})}finally{a.delete(y)}}},u=()=>{let h=[],f={};for(let y of Object.values(e.state().answers))Object.assign(f,y);for(let{questionId:y,fieldNames:S}of r){let g=f[y];if(g)for(let M of S){let k=g[M];typeof k=="string"&&k.trim().length>0&&h.push(k)}}return h},c=()=>{let h=u().find(f=>{let y=Bt(f);return y!=null&&!o.has(y.email??y.domain)});h===void 0||h===s||(s=h,clearTimeout(i),i=setTimeout(()=>{s=void 0,l(h)},1e3))},p=()=>{if(s===void 0)return;clearTimeout(i);let h=s;s=void 0,l(h)},A=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{d=!0,clearTimeout(i),A.forEach(h=>h())}};var Kn=new Set(["MultipleOptionsQuestion","MultipleChoiceQuestion","MMChoiceQuestion"]),Wn=(e,n)=>typeof e=="object"&&e!==null&&typeof e.key=="string"&&typeof e.value=="boolean"&&(!n||typeof e.index=="number"),Vt=({questions:e,questionId:n,merged:t})=>{let r=`Surface SDK [debug]: setAnswer("${n}")`,o=e.size>0?e.get(n):void 0;if(e.size>0&&!o){console.warn(`${r} \u2014 the record has no stateful question with this id; the answer will be dropped.`),console.debug(`Surface SDK [debug]: answer ${n}`,t);return}t.type===void 0?console.warn(`${r} \u2014 state has no "type" discriminator; the wire schema rejects untyped states. Include type: "${o?.componentType??"<ComponentType>"}".`):o?.componentType!==void 0&&t.type!==o.componentType&&console.warn(`${r} \u2014 state type "${String(t.type)}" but the record's component is ${o.componentType}.`);let a=o?.componentType??t.type;if(typeof a=="string"&&Kn.has(a)){let i=a==="MultipleOptionsQuestion";(!Array.isArray(t.choices)||t.choices.some(d=>!Wn(d,i)))&&console.warn(`${r} \u2014 ${a} answers need the ENTIRE option list under "choices" as {key, value${i?", index":""}} objects, not ${JSON.stringify(t.choices??t)}. See get_sdk_binding_map's answerShape.`)}console.debug(`Surface SDK [debug]: answer ${n}`,t)};var Jn="Lead",Qn="generate_lead",zn="lead_created",Kt=/^tw-([a-z0-9]+)-([a-z0-9]+)$/i,Yn=e=>{let n=e?.trim().match(Kt);return n?n[1]:null},jt=e=>/^\d+$/.test(e?.trim()??""),Gn=e=>{if(e.enabled===!1||(e.trigger??"reached_qualified")==="reached_step"&&!e.triggerStepId?.trim())return!1;switch(e.provider){case"x":return Kt.test(e.eventId?.trim()??"");case"meta":case"openai":return!!e.pixelId?.trim();case"ga4":return!!e.measurementId?.trim();case"linkedin":return jt(e.partnerId)&&jt(e.conversionId);default:return!1}},Xn=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o},Ht=(e,n)=>{let t=Xn(n,e.param)?.trim()??"",r=e.values??[];switch(e.operator){case"is_present":return t.length>0;case"equals_any":return r.some(o=>o.trim().toLowerCase()===t.toLowerCase());case"contains":return t.length>0&&r.some(o=>t.toLowerCase().includes(o.trim().toLowerCase()));default:return!1}},Zn=(e,n,t="and")=>e.length===0?!0:t==="or"?e.some(r=>Ht(r,n)):e.every(r=>Ht(r,n)),er=e=>{if(!Gn(e))return null;switch(e.provider){case"x":{let n=Yn(e.eventId);return n?{provider:"x",event:{event_id:e.eventId.trim(),pixel_id:n}}:null}case"meta":return{provider:"meta",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||Jn}};case"openai":return{provider:"openai",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||zn}};case"ga4":return{provider:"ga4",event:{measurement_id:e.measurementId.trim(),event_name:e.eventName?.trim()||Qn}};case"linkedin":return{provider:"linkedin",event:{partner_id:e.partnerId.trim(),conversion_id:e.conversionId.trim()}};default:return null}},De=(e,n,t,r)=>{let o=[];for(let a of e){if((a.trigger??"reached_qualified")!==n||n==="reached_step"&&(!r||a.triggerStepId!==r)||!Zn(a.conditions??[],t,a.conditionsOperator??"and"))continue;let i=er(a);i&&o.push({rule:a,conversion:i})}return o},tr=(e,n)=>{if(!e.twq){let t=e.twq=function(...o){t.exe?t.exe.apply(t,o):t.queue.push(o)};t.version="1.1",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://static.ads-twitter.com/uwt.js",e.document.head.appendChild(r)}e.twq("config",n)},nr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...o){t.callMethod?t.callMethod.apply(t,o):t.queue.push(o)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://connect.facebook.net/en_US/fbevents.js",e.document.head.appendChild(r)}e.fbq("init",n)},rr=(e,n)=>{if(!e.oaiq){let t=e.oaiq=function(...o){t.q.push(o)};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://bzrcdn.openai.com/sdk/oaiq.min.js",e.document.head.appendChild(r)}e.oaiq("init",{pixelId:n})},or=(e,n)=>{if(!e.gtag){e.dataLayer=e.dataLayer||[],e.gtag=function(...r){e.dataLayer.push(r)};let t=e.document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`,e.document.head.appendChild(t),e.gtag("js",new Date)}e.gtag("config",n,{send_page_view:!1})},sr=(e,n)=>{if(!e.lintrk){e._linkedin_partner_id=n;let t=e.lintrk=function(o,a){t.q.push([o,a])};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://snap.licdn.com/li.lms-analytics/insight.min.js",e.document.head.appendChild(r)}e._linkedin_data_partner_ids=e._linkedin_data_partner_ids||[],e._linkedin_data_partner_ids.includes(n)||e._linkedin_data_partner_ids.push(n)},Wt=(e,n,t)=>{let r=e;try{switch(n.provider){case"x":return tr(r,n.event.pixel_id),r.twq("event",n.event.event_id,{conversion_id:t.responseId,...t.twclid?{twclid:t.twclid}:{},...t.email?{email_address:t.email}:{}}),!0;case"meta":return nr(r,n.event.pixel_id),r.fbq("track",n.event.event_name,{},{eventID:t.responseId}),!0;case"openai":return rr(r,n.event.pixel_id),r.oaiq("measure",n.event.event_name,{type:"customer_action"},{event_id:t.responseId}),!0;case"ga4":return or(r,n.event.measurement_id),r.gtag("event",n.event.event_name,{transaction_id:t.responseId,send_to:n.event.measurement_id}),!0;case"linkedin":return sr(r,n.event.partner_id),r.lintrk("track",{conversion_id:n.event.conversion_id}),!0;default:return!1}}catch{return!1}};var Xe=(e,n)=>e.document.querySelector(`script[src="${n}"]`)!=null,Ue=(e,n,t,r)=>{if(Xe(e,n))return;let o=e.document.createElement("script");o.async=!0,o.src=n,r&&(o.id=r),e.document[t].appendChild(o)},ir=(e,n)=>{let t=`https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(n)}`;Xe(e,t)||(e.dataLayer=e.dataLayer||[],e.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"}),Ue(e,t,"head"))},ar=(e,n)=>{let t=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`;if(Xe(e,t))return;e.dataLayer=e.dataLayer||[],e.gtag||(e.gtag=function(){e.dataLayer.push(arguments)},e.gtag("js",new Date)),Ue(e,t,"head");let r=e.self!==e.top;e.gtag("config",n,{...r&&{cookie_flags:"SameSite=None;Secure;Partitioned"}})},dr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...r){t.callMethod?t.callMethod.apply(t,r):t.queue.push(r)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],Ue(e,"https://connect.facebook.net/en_US/fbevents.js","head")}e.fbq("init",n)},lr=(e,n)=>{Ue(e,`https://js.hs-scripts.com/${n}.js`,"body","hs-script-loader")},Jt=(e,n)=>{let t=e;n.gtmId&&ir(t,n.gtmId),n.gaMeasurementId&&ar(t,n.gaMeasurementId),n.metaPixelId&&dr(t,n.metaPixelId),n.hubspotTracking?.trackingId&&lr(t,n.hubspotTracking.trackingId);let r=i=>{n.gtmId&&(t.dataLayer=t.dataLayer||[],t.dataLayer.push(i))},o=(i,s)=>{n.gaMeasurementId&&t.gtag?.("event",i,s)},a=(i,s)=>{n.metaPixelId&&t.fbq?.("trackCustom",i,s)};return{formStarted:(i,s)=>{r({event:"SurfaceFormStarted",formId:i,...s}),a("SurfaceFormStarted",{formId:i,...s}),o("SurfaceFormStarted",{formId:i,...s})},stepSubmitted:i=>{r({event:"SurfaceFormStepSubmitted",...i}),a("SurfaceFormStepSubmitted",i),o("SurfaceFormStepSubmitted",i)},formCompleted:(i,s)=>{r({event:"SurfaceFormSubmitEvent",formId:i,...s}),a("SurfaceFormCompleted",{formId:i,...s}),o("SurfaceFormCompleted",{formId:i,...s})}}};var ur=e=>{try{return Object.fromEntries(new URLSearchParams(e.location.search).entries())}catch{return{}}},Ne=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o?.trim()||void 0},cr=e=>({twclid:Ne(e,"twclid"),fbclid:Ne(e,"fbclid"),gclid:Ne(e,"gclid"),li_fat_id:Ne(e,"li_fat_id")}),pr=["email","emailAddress","workEmailAddress"],Ze=e=>{for(let n of Object.values(e))for(let t of pr){let r=n[t];if(typeof r=="string"&&r.trim().length>0)return r.trim()}},Qt=e=>Object.values(e).some(n=>n.eventScheduled===!0),et=e=>{let n={};for(let t of Object.values(e.state().answers))Object.assign(n,t);return n},zt=({engine:e,formId:n,settings:t,win:r})=>{let o=r??window,a=Jt(o,t),i=t.adsConversions??[],s=ur(o),d={url:o.location.href,urlParams:s},l=new Set,u=new Set,c=new Set,p=new Set,A=!1,h=!1,f=!1,y=!1,S=!1,g=e.state().responseId==null,M=!g,k=(I,v)=>{let L=I.filter(({rule:F})=>!l.has(F.id));if(L.length===0)return;L.forEach(({rule:F})=>l.add(F.id));let O={responseId:v,email:Ze(et(e)),...cr(s)};L.forEach(({conversion:F})=>Wt(o,F,O))},x=(I,v)=>{if(!v){p.add(I);return}k(De(i,I,s),v)},R=(I,v)=>{if(!v){c.add(I);return}k(De(i,"reached_step",s,I),v)},U=I=>{if(!I){A=!0;return}h=!0,A=!1;let v=new Map;for(let L of["reached_qualified","form_submitted"])for(let O of De(i,L,s))v.set(O.rule.id,O);k(Array.from(v.values()),I)},w=()=>{let I=et(e);!y&&g&&Ze(I)!==void 0&&(y=!0,x("email_provided",e.state().responseId)),!S&&g&&Qt(I)&&(S=!0,x("meeting_booked",e.state().responseId))},_=[];_.push(e.on("started",()=>{a.formStarted(n,d)}));let b;_.push(e.on("stepCompleted",({stepId:I})=>{let v=et(e);b={stepId:I,formId:n,emailProvided:Ze(v)!==void 0,meetingBooked:Qt(v),...d},!f&&g&&(f=!0,x("step_submitted",e.state().responseId))})),_.push(e.on("stepChanged",({toStepId:I})=>{b&&(e.state().finished||a.stepSubmitted(b),b=void 0),!u.has(I)&&(u.add(I),R(I,e.state().responseId))})),_.push(e.on("completed",()=>{b=void 0,a.formCompleted(n,d),h||U(e.state().responseId)})),_.push(e.on("saved",({responseId:I})=>{if(M||(M=!0,x("form_started",I)),A&&U(I),c.size>0){let v=Array.from(c);c.clear(),v.forEach(L=>R(L,I))}if(p.size>0){let v=Array.from(p);p.clear(),v.forEach(L=>x(L,I))}})),_.push(e.subscribe(w));let D=e.state().currentStepId;return u.add(D),R(D,e.state().responseId),w(),()=>_.forEach(I=>I())};var mr=["email","emailAddress","workEmailAddress"],fr=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,qe=({engine:e,validator:n})=>{let t=new Set,r=new Map,o,a=!1,i,s=!1,d=()=>{let h=[];for(let f of Object.values(e.state().answers))for(let y of Object.values(f))for(let S of mr){let g=y[S];typeof g=="string"&&fr.test(g.trim())&&h.push(g.trim())}return h},l=()=>{let h=new Set(d()),f=[...r.values()].filter(g=>h.has(g.email));if(f.length===0)return;let y=JSON.stringify(f.map(g=>[g.email,g.isValid,g.failed===!0]));if(y===i)return;i=y;let S=f.find(g=>g.status&&g.reason);e.mergeMeta({isEmailValid:f.some(g=>g.isValid),emailValidation:S?{status:S.status,reason:S.reason,...S.blacklistEntryIds?.length&&{blacklistEntryIds:S.blacklistEntryIds}}:void 0,emailValidationFailed:f.some(g=>g.failed===!0)})},u=async()=>{let h=d().filter(y=>!t.has(y));if(h.length===0)return;h.forEach(y=>t.add(y));let f=await n.validateBatch(h);s||(f.forEach(y=>r.set(y.email,y)),l())},c=()=>{if(!d().some(h=>!t.has(h))){l();return}a=!0,clearTimeout(o),o=setTimeout(()=>{a=!1,u()},300)},p=()=>{a&&(a=!1,clearTimeout(o),u())},A=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{s=!0,clearTimeout(o),A.forEach(h=>h())}};var Yt=new Set(["surfaceTagStatus","isEmailValid","emailValidation","emailValidationFailed"]),gr=new Set(["CalendlyScreen","DynamicScheduler","FileUploader"]),Gt={init:async({environmentId:e,formId:n,steps:t,settings:r={},apiBaseUrl:o,container:a,expectedQuestionIds:i,resolveNextStep:s,urlDataStateId:d,source:l,journey:u=!1,emailValidation:c=!1,preview:p=!1,previewToken:A,debug:h=!1,resume:f,meta:y})=>{let S=be({apiBaseUrl:o}),g;if(!t){let T=await le(S,n,{preview:p,previewToken:A});if(!T.ok||!T.data.data){let C=(o??Q).replace(/\/$/,""),N=T.ok?"empty response":T.error.kind==="http"?`HTTP ${T.error.status}`:"network error";throw new Error(`SurfaceForms.init: could not fetch runtime config for form "${n}" (${N} from ${C}/api/v1/public/forms/${n}/runtime-config). If this environment is not served from ${Q}, pass apiBaseUrl \u2014 the get_sdk_binding_map MCP tool returns the correct value.`)}g=T.data.data,t=ce(g.config),i=i??J(g.config).filter(C=>!gr.has(C.componentType??"")).map(C=>C.questionId);let P=g.settings??{};r={trackPartialResponses:P.trackPartialResponses,trackCookies:P.trackCookie,gtmId:P.gtmId,gaMeasurementId:P.gaMeasurementId,metaPixelId:P.metaPixelId,hubspotTracking:P.hubspotTracking,adsConversions:P.adsConversions,...r}}let M=r.trackCookies??!1,k;if(f&&!p){let T=await xt(S,f);T.ok?k={responseId:f.responseId,answers:Object.fromEntries(T.data.answers.map(P=>[P.questionId,P.response]))}:console.warn(`Surface SDK: resume fetch for response "${f.responseId}" failed \u2014 starting a fresh session.`)}let x=await ne({transport:S,environmentId:e,formId:n,source:l,preview:p}),R=we({transport:S,preview:p}),U=_e({transport:S,preview:p}),w=Te({formId:n,environmentId:e,steps:t,transport:S,resolveNextStep:s,trackPartialResponses:r.trackPartialResponses??!0,trackCookies:M,externalStates:d?{[d]:Re({trackCookies:M})}:{},meta:{...y,surfaceTagStatus:"sdk"},identity:()=>({fingerprint:x?.fingerprint,leadSessionId:x?.leadSessionId??void 0,leadId:x?.leadId??void 0}),pushEvents:R,formJourney:U,preview:p,resume:k}),_=[],b=w;if(h){let T=new Map((g?J(g.config):[]).map(C=>[C.questionId,C])),P=(C,N)=>((...G)=>(console.debug(`Surface SDK [debug]: ${C} requested from step ${w.state().currentStepId}`),N(...G)));b={...w,setAnswer:(C,N)=>{let G=w.state().currentStepId;w.setAnswer(C,N);let se=w.state().answers[G]?.[C]??N;Vt({questions:T,questionId:C,merged:se})},next:P("next",w.next),back:P("back",w.back),goToStep:P("goToStep",w.goToStep),submit:P("submit",w.submit),disqualify:P("disqualify",w.disqualify)};for(let C of["viewed","started","stepChanged","stepCompleted","completed","disqualified","saved","error","scheduler"])_.push(w.on(C,N=>console.debug(`Surface SDK [debug]: ${C}`,N)))}let D=!1;_.push(w.on("started",()=>{D=!0})),_.push(Ae(R,()=>({started:D,formId:n,stepId:w.state().currentStepId,sessionId:x?.leadSessionId??void 0}))),a&&_.push(ae({engine:b,root:a,expectedQuestionIds:i}));let I=!!r.gtmId||!!r.gaMeasurementId||!!r.metaPixelId||!!r.hubspotTracking?.trackingId||(r.adsConversions?.length??0)>0;I&&!p&&typeof window<"u"&&_.push(zt({engine:w,formId:n,settings:r}));let v=g?pe(g.config):[],L=g!=null&&v.length>0&&fe(g.settings);L&&!p?_.push(Fe({engine:w,transport:S,formId:n,sources:v})):h&&g&&!L&&ut(g.config)&&console.warn("Surface SDK: the record declares an enrichmentSourceField, but this environment has no enabled enrichment provider \u2014 no enrichment will run (capabilities.enrichment is false).");let O=he({transport:S,environmentId:e,preview:p});c&&!p&&_.push(qe({engine:w,validator:O}));let F;return u&&!p&&(F=Le({transport:S,environmentId:e}),F.trackPageView(),_.push(F.observeRouteChanges())),{setAnswer:b.setAnswer,setExternalState:w.setExternalState,next:b.next,back:b.back,goToStep:b.goToStep,submit:b.submit,disqualify:b.disqualify,savePartial:w.savePartial,notifyScheduler:w.notifyScheduler,flush:w.flush,markViewed:w.markViewed,mergeMeta:T=>{let P=Object.entries(T),C=P.filter(([N])=>Yt.has(N));C.length>0&&console.warn(`Surface SDK: mergeMeta dropped reserved key(s) ${C.map(([N])=>N).join(", ")} \u2014 these are SDK-owned response markers.`),w.mergeMeta(Object.fromEntries(P.filter(([N])=>!Yt.has(N))))},capabilities:{enrichment:L,emailValidation:c,tracking:I},on:w.on,state:w.state,subscribe:w.subscribe,identify:async()=>{let T=await ne({transport:S,environmentId:e,formId:n,source:l,preview:p});return T&&(x=T),T},validateEmail:O.validate,runtimeConfig:g,transport:S,identity:()=>({fingerprint:x?.fingerprint,leadSessionId:x?.leadSessionId??void 0,leadId:x?.leadId??void 0}),preview:p,destroy:()=>_.forEach(T=>T())}}};return sn(yr);})();
1
+ "use strict";var SurfaceFormsSDK=(()=>{var $e=Object.defineProperty;var en=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var nn=Object.prototype.hasOwnProperty;var rn=(e,n)=>{for(var t in n)$e(e,t,{get:n[t],enumerable:!0})},on=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of tn(n))!nn.call(e,o)&&o!==t&&$e(e,o,{get:()=>n[o],enumerable:!(r=en(n,o))||r.enumerable});return e};var sn=e=>on($e({},"__esModule",{value:!0}),e);var yr={};rn(yr,{DEFAULT_API_BASE_URL:()=>z,DEFAULT_REDIRECT_TIMEOUT_MS:()=>Mt,ENRICHMENT_STATE_ID:()=>Le,IDENTITY_INFO_ANSWER_KEYS:()=>xt,JOURNEY_COOKIE_NAME:()=>re,LEAD_DATA_STORAGE_KEY:()=>te,LEAD_DATA_TTL_MS:()=>Ft,RECENT_VISIT_COOKIE_NAME:()=>oe,SurfaceForms:()=>zt,attachEmailValidation:()=>qe,attachEnrichment:()=>Oe,bindForm:()=>ie,buildIdentifyPayload:()=>Ce,buildRedirectUrl:()=>We,buildResponsesArray:()=>Ke,buildStepTransitionEventBatch:()=>Se,buildUrlData:()=>Te,constructUrlParamsObject:()=>Je,createEmailValidator:()=>ye,createEmitter:()=>be,createFormEngine:()=>Ee,createFormJourneyTracker:()=>Ae,createJourneyTracker:()=>Me,createPushEventClient:()=>ke,createSchedulerClient:()=>fe,createStartedDetector:()=>we,createSubmitResponsePayload:()=>Ie,createTransport:()=>ve,createUpdateResponsePayload:()=>Y,enrichmentSourcesOf:()=>ce,ensureIdentified:()=>ne,fetchRuntimeConfig:()=>de,getBrowserFingerprint:()=>_e,getHash:()=>Ye,hasEnabledEnrichmentProvider:()=>me,identifyLead:()=>xe,mountBookingWidget:()=>ae,mountScheduler:()=>Et,observeDropoff:()=>Re,observeFormView:()=>se,parseCookiesObject:()=>Qe,parsePrefillParams:()=>Ot,parseQuestionId:()=>ze,performRedirect:()=>Lt,readLeadData:()=>G,schedulerQuestionsOf:()=>pe,statefulQuestionIdsOf:()=>it,statefulQuestionsOf:()=>Q,stepsOf:()=>ue,submitResponse:()=>he,toSchedulerAnswerState:()=>vt,updateResponse:()=>ee,writeLeadData:()=>Pe});var se=(e,n)=>{if(typeof IntersectionObserver>"u")return n(),()=>{};let t=!1,r=new IntersectionObserver(o=>{let[a]=o;!a?.isIntersecting||t||(t=!0,r.disconnect(),n())});return r.observe(e),()=>r.disconnect()};var nt="input, select, textarea",an=e=>e.matches(nt)?[e]:Array.from(e.querySelectorAll(nt)).filter(n=>n.closest("[data-question-id]")===e),dn=(e,n,t)=>{let r=e.getAttribute("data-field-name")??n.getAttribute("data-field-name");return r||(t==="Dropdown"&&n instanceof HTMLSelectElement?"selected":n instanceof HTMLInputElement&&n.type==="email"?"email":"input")},rt=(e,n)=>{let t=e.getAttribute("data-question-type")??n.getAttribute("data-question-type");return t||(n instanceof HTMLInputElement&&n.type==="email"?"EmailForm":"ShortInput")},ot=e=>e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")&&e.type==="checkbox"?e.checked:e.value,ln=e=>e instanceof HTMLInputElement&&(e.type==="radio"||e.type==="checkbox"),st=e=>{let n=e.findIndex(t=>t.checked);return{value:n===-1?"":e[n].value,index:n}},un={MultipleOptionsQuestion:e=>({choices:e.map((n,t)=>({key:n.value,value:n.checked,index:t}))}),MultipleChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),MMChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),GraphicOptions:st,MultipleChoiceSingleAnswer:st},ie=({engine:e,root:n,expectedQuestionIds:t})=>{let r=[],o=new Set,a=(u,c,p)=>{u.addEventListener(c,p),r.push(()=>u.removeEventListener(c,p))};for(let u of Array.from(n.querySelectorAll("[data-question-id]"))){let c=u.getAttribute("data-question-id"),p=an(u);if(p.length===0)continue;o.add(c);let C=rt(u,p[0]),y=un[C],m=p.filter(ln);if(y&&m.length>0){let h=()=>e.setAnswer(c,{type:C,...y(m)});for(let v of m)a(v,"change",h);m.some(v=>v.checked)&&h();continue}for(let h of p){let v=rt(u,h),g=dn(u,h,v),L=()=>e.setAnswer(c,{type:v,[g]:ot(h)});a(h,"input",L),a(h,"change",L);let P=ot(h);P!==""&&P!==!1&&L()}}let i=(t??[]).filter(u=>!o.has(u));i.length>0&&console.warn(`Surface SDK: form record declares questionIds with no bound element: ${i.join(", ")}. Answers for these will never be captured — check data-question-id attributes (validate_form_html catches this at authoring time).`);let s="[data-surface-goto-step], .surface-disqualify-button, .surface-submit-button, .surface-next-button";for(let u of Array.from(n.querySelectorAll(s))){let c=u.getAttribute("data-surface-goto-step"),p=[c!=null?"goto":null,u.classList.contains("surface-disqualify-button")?"disqualify":null,u.classList.contains("surface-submit-button")?"submit":null,u.classList.contains("surface-next-button")?"next":null].filter(y=>y!=null),C=p[0];p.length>1&&console.warn(`Surface SDK: element carries multiple navigation markers (${p.join(", ")}); only "${C}" is bound.`),a(u,"click",y=>{y.preventDefault(),C==="goto"?e.goToStep(c).catch(m=>console.warn(`Surface SDK: ${String(m)}`)):C==="disqualify"?e.disqualify():C==="submit"?e.submit():e.next()})}n instanceof HTMLFormElement&&a(n,"submit",u=>{u.preventDefault(),e.submit()});let d=Array.from(n.querySelectorAll("[data-step-id]")),l=()=>{let{currentStepId:u}=e.state();for(let c of d)c.hidden=c.getAttribute("data-step-id")!==u};return d.length>0&&(l(),r.push(e.on("stepChanged",l))),r.push(se(n,()=>e.markViewed())),()=>r.forEach(u=>u())};var cn=()=>{let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`},pn=e=>{let[n,t]=e.split("-").map(Number);return new Date(n,t-1,1).toLocaleDateString(void 0,{month:"long",year:"numeric"})},mn=e=>{let[n,t,r]=e.split("-").map(Number);return new Date(n,t-1,r).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"})},fn=(e,n)=>{let[t,r]=e.split("-").map(Number),o=new Date(t,r-1+n,1);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}`},ae=({container:e,scheduler:n,eventTypeId:t,timezone:r=Intl.DateTimeFormat().resolvedOptions().timeZone,duration:o,prefill:a,identity:i,formatters:s,onEvent:d,onComplete:l})=>{let u=s?.month??pn,c=s?.date??mn,p=s?.time??(O=>new Date(O.start).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:r})),C=document.createElement("div");C.className="surface-booking",e.appendChild(C);let y=cn(),m=!0,h=[],v=null,g=null,L=!1,P=0,k=(O,S,w)=>{let _=document.createElement(O);return _.className=S,w!=null&&(_.textContent=w),_},T=O=>{L||C.replaceChildren(...O)},U=(O,S)=>{let w=k("p","surface-booking-error",O),_=k("button","surface-booking-retry","Try again");_.type="button",_.addEventListener("click",S),T([w,_])},b=async()=>{let O=y,S=++P;T([k("p","surface-booking-loading","Loading availability…")]);let w=await n.getMonthAvailability({eventTypeId:t,month:O,timezone:r,duration:o});if(L||S!==P)return;if(!w.ok){U("Unable to load availability.",()=>{b()});return}h=w.data.data?.dates??[];let _=h.filter(E=>E.slots&&E.slots.length>0);if(m&&(m=!1,_.length===0&&o==null)){let E=await n.getAvailabilitySummary({eventTypeId:t,timezone:r});if(L||S!==P)return;let R=E.ok?E.data.data?.next_available_date:null;if(R&&!R.startsWith(O)){y=R.slice(0,7),b();return}}let q=k("p","surface-booking-month",u(O));q.dataset.value=O;let F=k("div","surface-booking-month-nav");for(let[E,R]of[["Previous month",-1],["Next month",1]]){let D=k("button","surface-booking-month-button",E);D.type="button",D.addEventListener("click",()=>{y=fn(y,R),b()}),F.appendChild(D)}let M=k("ul","surface-booking-dates");for(let E of _){let R=k("li","surface-booking-date"),D=k("button","surface-booking-date-button",c(E.date));D.dataset.value=E.date,D.type="button",D.addEventListener("click",()=>{v=E,d?.({type:"date_selected",date:E.date}),A()}),R.appendChild(D),M.appendChild(R)}M.childElementCount===0&&M.appendChild(k("li","surface-booking-no-dates","No availability this month.")),T([q,F,M])},A=async()=>{if(!v)return;let O=++P,S=v.slots??[];if(S.length===0){let F=await n.getSlots({eventTypeId:t,date:v.date,timezone:r,duration:o});if(L||O!==P)return;if(!F.ok){U("Unable to load times.",()=>{A()});return}S=F.data.data?.slots??[]}let w=k("p","surface-booking-day",c(v.date));w.dataset.value=v.date;let _=k("button","surface-booking-back","Back");_.type="button",_.addEventListener("click",()=>{b()});let q=k("ul","surface-booking-slots");for(let F of S){let M=k("li","surface-booking-slot"),E=k("button","surface-booking-slot-button",p(F));E.dataset.value=F.start,E.type="button",E.addEventListener("click",()=>{g=F,d?.({type:"slot_selected",slot:F}),x()}),M.appendChild(E),q.appendChild(M)}T([w,_,q])},x=O=>{if(!g)return;O==null&&d?.({type:"form_opened"});let S=k("form","surface-booking-form"),w=k("input","surface-booking-name");w.name="name",w.placeholder="Name",w.value=a?.name??"";let _=k("input","surface-booking-email");_.type="email",_.name="email",_.placeholder="Email",_.value=a?.email??"";let q=k("button","surface-booking-submit","Book");q.type="submit",S.append(w,_,q),O&&S.appendChild(k("p","surface-booking-error",O)),S.addEventListener("submit",F=>{F.preventDefault(),(async()=>{q.disabled=!0;let M=typeof i=="function"?await i():i,E=await n.book({eventTypeId:t,startTime:g.start,endTime:g.end,timezone:r,inviteeName:w.value,inviteeEmail:_.value,duration:o,...M});if(!L){if(!E.ok){x("Booking failed. Please try again.");return}T([k("p","surface-booking-booked","Booked!")]),d?.({type:"booking_confirmed",booking:E.data}),l(E.data)}})()}),T([S])};return d?.({type:"viewed"}),b(),()=>{L=!0,C.remove()}};var de=(e,n,{preview:t=!1,previewToken:r}={})=>e.get(`/api/v1/public/forms/${n}/runtime-config${t?`?preview=1${r?`&pt=${encodeURIComponent(r)}`:""}`:""}`),le=e=>{let n=e.components;if(Array.isArray(n))return n;let t=n?.layout;return Array.isArray(t)?t.flatMap(r=>{let o=r.row;return Array.isArray(o)?o.map(a=>a.type==="GridLayoutRowItem"?a.component:a):[]}):[]},ue=e=>(e.steps??[]).map(n=>({id:n.id,...n.endStepKind!==void 0&&{endStepKind:n.endStepKind}})),Q=e=>(e.steps??[]).flatMap(le).flatMap(n=>{let t=n;return typeof t?.state?.questionId!="string"?[]:[{questionId:t.state.questionId,...typeof t.type=="string"&&{componentType:t.type}}]}),it=e=>Q(e).map(n=>n.questionId),ce=e=>(e.steps??[]).flatMap(le).flatMap(n=>{let t=n;if(typeof t?.state?.questionId!="string")return[];if(t.type==="IdentityInfo"){let r=typeof t.content?.enrichmentSourceField=="string"?t.content.enrichmentSourceField:"emailAddress";return[{questionId:t.state.questionId,fieldNames:[...new Set([r,"websiteUrl"])]}]}return t.type==="EmailForm"?[{questionId:t.state.questionId,fieldNames:["email"]}]:[]}),at=e=>{let n=e;return typeof n?.stepId=="string"&&typeof n?.questionId=="string"?{stepId:n.stepId,questionId:n.questionId}:void 0},gn=e=>{let n=at(e),t=e?.variable;return n&&typeof t=="string"?{...n,variable:t}:void 0},pe=e=>(e.steps??[]).flatMap(n=>le(n).flatMap(t=>{let r=t;if(r?.type!=="CalendlyScreen"&&r?.type!=="DynamicScheduler")return[];if(typeof r.state?.questionId!="string")return[];let o=r.content??{},a={};for(let s of["dataUrl","eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);for(let s of["addSchedulerQueryParams","skipFormIfPrefilled"])typeof o[s]=="boolean"&&(a[s]=o[s]);for(let s of["linkNameToStep","linkLastNameToStep","linkEmailToStep"]){let d=at(o[s]);d&&(a[s]=d)}let i=Object.entries(o.dataUrlParams??{}).flatMap(([s,d])=>{let l=gn(d);return l?[[s,l]]:[]});return i.length>0&&(a.dataUrlParams=Object.fromEntries(i)),Array.isArray(o.calendars)&&(a.calendars=o.calendars),o.defaultCalendar!=null&&(a.defaultCalendar=o.defaultCalendar),[{questionId:r.state.questionId,stepId:n.id,componentType:r.type,calendarType:typeof o.calendarType=="string"?o.calendarType:"Calendly",content:a}]})),dt=e=>(e.steps??[]).flatMap(le).some(n=>typeof n?.content?.enrichmentSourceField=="string"),me=e=>{let n=e?.enrichment;return n?.version!==2||!Array.isArray(n.providers)?!1:n.providers.some(t=>t?.enabled===!0&&Array.isArray(t.enabledFields)&&t.enabledFields.length>0)};var X=e=>/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`,B=(e,n)=>{let t;try{t=new URL(X(e))}catch{return null}for(let[r,o]of Object.entries(n))o!=null&&!t.searchParams.has(r)&&t.searchParams.set(r,o);return t.toString()},yn=(e,n)=>{let t=document.createElement("iframe");return t.className="surface-scheduler-frame",t.src=n,t.style.width="100%",t.style.height="100%",t.style.border="0",e.appendChild(t),t},W=e=>new Promise((n,t)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.surfaceLoaded==="true")return n();r.addEventListener("load",()=>n()),r.addEventListener("error",()=>t(new Error(`Failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.async=!0,o.addEventListener("load",()=>{o.dataset.surfaceLoaded="true",n()}),o.addEventListener("error",()=>{o.remove(),t(new Error(`Failed to load ${e}`))}),document.head.appendChild(o)}),hn=(e,n)=>{let t;try{t=new URL(e)}catch{return!1}return n.some(r=>"exact"in r?e===r.exact:t.protocol!=="https:"?!1:"hostRegex"in r?r.hostRegex.test(t.hostname):t.hostname===r.hostSuffix||t.hostname.endsWith(`.${r.hostSuffix}`))},N=(e,n)=>(console.warn(`Surface SDK: scheduler question "${e.questionId}" is missing ${n} on the record.`),()=>{}),j=e=>{let n=!1,t;return e().then(r=>{n?r?.():t=r}).catch(r=>console.warn("Surface SDK: scheduler embed failed",r)),()=>{n=!0,t?.()}},Z=(e,n)=>{let t=r=>{if(hn(r.origin,e))try{n(r.data)}catch(o){console.warn("Surface SDK: scheduler message handler failed",o)}};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},V=(e,{needsResponseId:n=!1,build:t})=>j(async()=>{let r=n?await e.ensureResponseId():null,o=t(r);if(o.src==null)return;let a=yn(e.container,o.src),i=o.origins&&o.onMessage?Z(o.origins,o.onMessage):void 0,s=o.poll&&r!=null?vn({transport:e.form.transport,...o.poll}):void 0;return()=>{i?.(),s?.(),a.remove()}}),vn=({transport:e,path:n,onResult:t,intervalMs:r=2e3,timeoutMs:o=3e5})=>{let a=Date.now(),i=!1,s=null,d=()=>{i=!0,s!=null&&clearInterval(s),s=null},l=async()=>{if(i)return;if(Date.now()-a>o)return d();let u=await e.get(n);i||!u.ok||t(u.data)==="stop"&&d()};return l(),s=setInterval(()=>{l()},r),d};var lt=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=X(n),r=t.split("/").pop()?.split("?")[0]??"surface",o=t.replace(/^https?:\/\/(app\.)?cal\.com\//,""),a=`surface-cal-${e.question.questionId}`,i=document.createElement("div");i.id=a,e.container.appendChild(i);let s=l=>{let u=l.detail?.data?.booking?.uid;e.confirmBooking({uri:u?`https://app.cal.com/booking/${u}`:"",raw:l.detail})};window.addEventListener(`CAL:${r}:bookingSuccessful`,s);let d=j(async()=>{await W("https://app.cal.com/embed/embed.js");let l=window.Cal;l&&(l("init",r,{origin:"https://cal.com"}),l.ns?.[r]?.("inline",{elementOrSelector:`#${a}`,calLink:o,config:{...e.prefill.name&&{name:e.prefill.name},...e.prefill.email&&{email:e.prefill.email}}}))});return()=>{window.removeEventListener(`CAL:${r}:bookingSuccessful`,s),d(),i.remove()}};var ut=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=!1,r=(a,i)=>{t||(t=!0,e.confirmBooking({uri:a,raw:i}))},o=e.content.addSchedulerQueryParams!==!1;return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed_domain:"1",embed_type:"Inline",...o&&{hide_event_type_details:"1",hide_gdpr_banner:"1"},...Object.keys(e.urlParams).length>0?e.urlParams:{name:e.prefill.name,email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`}}),origins:[{exact:"https://calendly.com"}],onMessage:i=>{let s=i;typeof s?.event!="string"||!s.event.startsWith("calendly.")||(s.event==="calendly.event_type_viewed"&&e.emit({type:"viewed"}),s.event==="calendly.date_and_time_selected"&&e.emit({type:"slot_selected"}),s.event==="calendly.event_scheduled"&&r(s.payload?.invitee?.uri??"",i))},poll:{path:`/api/v1/calendly/check-event/${a}`,onResult:i=>i.status==="pending"?"continue":i.status==="canceled"?(t&&e.cancelBooking(),"stop"):typeof i.url=="string"&&i.url&&i.responseId===a?(r(i.url,i),"stop"):t?"stop":"continue"}})})};var ct=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams}),origins:[{hostSuffix:"chilipiper.com"}],onMessage:t=>{let r=t;r?.action==="booking-confirmed"&&e.confirmBooking({uri:r.args?.eventId??"",raw:t})}})}):N(e.question,"dataUrl")};var pt=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams})})}):N(e.question,"dataUrl")};var mt=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=B(n,{embed:"true",...e.urlParams});if(t==null)return()=>{};let r=`surface-hubspot-${e.question.questionId}`,o=document.createElement("div");o.id=r,o.className="meetings-iframe-container",o.dataset.src=t,e.container.appendChild(o);let a=Z([{exact:"https://meetings.hubspot.com"},{hostRegex:/^meetings-[a-z0-9]+\.hubspot\.com$/}],s=>{s?.meetingBookSucceeded===!0&&e.confirmBooking({uri:" ",raw:s})}),i=j(async()=>{await W("https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js"),window.MeetingsEmbedCode?.createMeetingsIframe(`#${r}`)});return()=>{a(),i(),o.remove()}};var bn=["reclaim.ai","reclaim.com","reclaimai.com"],ft=e=>{let n=e.content.dataUrl,t=(()=>{try{return new URL(X(n??"")).hostname}catch{return null}})(),r=t!=null&&bn.some(o=>t===o||t.endsWith(`.${o}`));return!n||!r?N(e.question,"a valid reclaim.ai dataUrl"):V(e,{needsResponseId:!0,build:o=>({src:B(n,{...o!=null&&{"data-responseId":o},...e.urlParams}),poll:{path:`/api/v1/reclaimai/check-event/${o}`,onResult:a=>{if(a.status==="pending")return"continue";if(a.meetingId!=null&&a.responseId===o){let i=[a.schedulingLinkId,a.meetingId].find(s=>typeof s=="string"&&s.length>0);return e.confirmBooking({uri:i??"",raw:a}),"stop"}return"continue"}}})})};var gt=e=>{let n=e.content.revenueHeroRouterId;if(!n)return N(e.question,"revenueHeroRouterId");let t=`surface-revenuehero-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=Z([{hostSuffix:"revenuehero.io"}],i=>{let s=i;s?.type!=="MEETING_BOOKED"||s.meeting==null||e.confirmBooking({uri:s.meeting.id??"",...s.meeting.attributes?.meeting_time!=null&&{meetingTime:s.meeting.attributes.meeting_time},raw:i})}),a=j(async()=>{await W("https://assets.revenuehero.io/scheduler.min.js");let i=window.RevenueHero;if(!i)return;let s=new i({routerId:n,showLoader:!1}),d={...e.urlParams,...e.prefill.email&&{email:e.prefill.email},...e.prefill.name&&{name:e.prefill.name}},l=await s.submit(d);s.dialog.setEmbedTarget(`#${t}`),s.dialog.open(l)});return()=>{o(),a(),r.remove()}};var yt=e=>{let n=e.content.savvyCalLinkId;if(!n)return N(e.question,"savvyCalLinkId");let t=`surface-savvycal-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=i=>{let s=i.detail;s&&e.confirmBooking({uri:s.url??"",raw:s})};window.addEventListener("savvycal.scheduled",o);let a=j(async()=>{await W("https://embed.savvycal.com/v1/embed.js");let i=window.SavvyCal;if(!i)return;i("init");let s=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");i("inline",{link:n,selector:`#${t}`,...s&&{displayName:s},...e.prefill.email&&{email:e.prefill.email}})});return()=>{window.removeEventListener("savvycal.scheduled",o),a(),r.remove()}};var ht=e=>new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,n])=>n!=null))),fe=({transport:e,preview:n=!1})=>{let t=n?"true":void 0,r=o=>{if(!o.ok)return o;let a=o.data.data;return a?.id?{ok:!0,data:a}:{ok:!1,error:{kind:"http",status:200,body:o.data}}};return{getPublicEventType:o=>e.get(`/api/v1/scheduler/event-types/${o}/public`),getAvailabilitySummary:({eventTypeId:o,timezone:a})=>{let i=new URLSearchParams({eventTypeId:o,timezone:a??Intl.DateTimeFormat().resolvedOptions().timeZone});return e.get(`/api/v1/scheduler/availability-summary?${i}`)},getMonthAvailability:({eventTypeId:o,month:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let[u,c]=a.split("-").map(Number),p=ht({eventTypeId:o,month:String(c),year:String(u),timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/availability?${p}`)},getSlots:({eventTypeId:o,date:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let u=ht({eventTypeId:o,date:a,timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/slots?${u}`)},book:async({eventTypeId:o,startTime:a,endTime:i,timezone:s,inviteeName:d,inviteeEmail:l,duration:u,intakeResponses:c,guestEmails:p,captchaToken:C,responseId:y,leadSessionId:m,fingerprint:h,hostRouting:v})=>{if(n)return{ok:!0,data:{id:"preview-booking-"+Date.now(),startTime:a,endTime:i,timezone:s,inviteeName:d||"Test User",inviteeEmail:l||"test@example.com",meetingJoinLink:null,cancelToken:"preview-cancel-"+Date.now(),rescheduleToken:"preview-reschedule-"+Date.now(),attendees:[{name:"Host",email:"host@example.com",isHost:!0}]}};let g=await e.post("/api/v1/scheduler/book",{eventTypeId:o,startTime:a,timezone:s,inviteeName:d,inviteeEmail:l.trim(),...u?{duration:u}:{},...c&&Object.keys(c).length>0?{intakeResponses:c}:{},...p&&p.length>0?{guestEmails:p}:{},...C?{captchaToken:C}:{},meta:{source:"form",...y?{responseId:y}:{},...m?{leadSessionId:m}:{},...h?{fingerprint:h}:{},...v?{hostRouting:v}:{}}});return r(g)},reschedule:async({bookingId:o,rescheduleToken:a,newStartTime:i,timezone:s})=>{let d=await e.post(`/api/v1/scheduler/bookings/${o}/reschedule`,{rescheduleToken:a,newStartTime:i,timezone:s});return r(d)}}},vt=e=>{let n=e.attendees?.find(t=>t.isHost);return{type:"DynamicScheduler",eventScheduled:!0,uri:e.id,meetingTime:e.startTime,meetingEndTime:e.endTime,ownerEmails:n?.email??"",guestEmails:e.inviteeEmail,inviteeName:e.inviteeName,googleMeetLink:e.meetingJoinLink??""}};var bt=e=>{let n=e.content.eventTypeId;if(!n)throw new Error(`mountScheduler: Surface scheduler question "${e.question.questionId}" has no eventTypeId on the record.`);let t=fe({transport:e.form.transport,preview:e.form.preview}),r=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");return e.mergeAnswer({eventScheduled:!1,uri:"",schedulerSubStep:"date"}),ae({container:e.container,scheduler:t,eventTypeId:n,prefill:{...r&&{name:r},...e.prefill.email&&{email:e.prefill.email}},formatters:e.formatters,identity:async()=>{let o=await e.ensureResponseId(),a=e.form.identity();return{...o!=null&&{responseId:o},...a.leadSessionId!=null&&{leadSessionId:a.leadSessionId},...a.fingerprint!=null&&{fingerprint:a.fingerprint}}},onEvent:o=>{if(o.type==="booking_confirmed"){let{booking:i}=o,s=i.attendees?.find(d=>d.isHost);e.confirmBooking({uri:i.id,meetingTime:i.startTime,meetingEndTime:i.endTime,inviteeName:i.inviteeName,guestEmails:i.inviteeEmail,ownerEmails:s?.email??"",joinLink:i.meetingJoinLink??"",raw:i},{schedulerSubStep:"booked"});return}let a={date_selected:"time",form_opened:"form"}[o.type];a&&e.mergeAnswer({schedulerSubStep:a}),e.emit(o)},onComplete:()=>{}})};var Sn={hostEmail:"ownerEmails",startTime:"meetingTime",endTime:"meetingEndTime",joinUrl:"googleMeetLink",duration:"durationMinutes",timezone:"hostTimezone"},St=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let[t,...r]=(e.prefill.name??"").split(/\s+/),o=e.prefill.lastName??(r.length>0?r.join(" "):void 0);return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed:"true",origin:window.location.origin,...t&&{firstname:t},...o&&{lastname:o},...e.prefill.email&&{email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`},...e.urlParams}),origins:[{exact:"https://scheduler.zoom.us"}],onMessage:i=>{let s=i;if(s?.type!=="bookingForm")return;let d=s.payload??{},l=[d.bookerFirstName,d.bookerLastName].filter(Boolean).join(" ");e.confirmBooking({uri:d.scheduledEventId??"",guestEmails:d.bookerEmail??"",...l&&{inviteeName:l},raw:i})},poll:{path:`/api/v1/zoom/check-event/${a}`,onResult:i=>{if(i.status==="pending"||i.hostEmail==null&&i.startTime==null)return"continue";let s={};for(let[d,l]of Object.entries(Sn))typeof i[d]=="string"&&(s[l]=i[d]);return e.mergeAnswer(s,{save:!0}),"stop"}}})})};var kt={Surface:bt,Calendly:ut,Cal:lt,SavvyCal:yt,ChiliCal:ct,Hubspot:mt,RevenueHero:gt,Zoom:St,ReclaimAI:ft,Clari:pt};var wt="surface-scheduler-styles",kn=`\n\${--surface-scheduler-accent:#2563eb;--surface-scheduler-border:#e2e8f0;--surface-scheduler-text:#0f172a;--surface-scheduler-muted:#64748b;--surface-scheduler-radius:8px;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--surface-scheduler-text)}\n%{display:flex;flex-direction:column;gap:12px;max-width:26rem;padding:16px;border:1px solid var(--surface-scheduler-border);border-radius:var(--surface-scheduler-radius)}\n%-month,%-day{margin:0;font-size:1rem;font-weight:600}\n%-month-nav{display:flex;gap:8px}\n$ button{font:inherit;cursor:pointer;border-radius:calc(var(--surface-scheduler-radius) - 2px)}\n%-month-button,%-back,%-retry{padding:4px 10px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-muted)}\n%-month-button:hover,%-back:hover{color:var(--surface-scheduler-text)}\n%-dates,%-slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr));gap:8px;margin:0;padding:0;list-style:none}\n%-date-button,%-slot-button{width:100%;padding:8px 6px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-text)}\n%-date-button:hover,%-slot-button:hover{border-color:var(--surface-scheduler-accent);color:var(--surface-scheduler-accent)}\n%-form{display:flex;flex-direction:column;gap:8px}\n%-name,%-email{font:inherit;padding:8px 10px;border:1px solid var(--surface-scheduler-border);border-radius:calc(var(--surface-scheduler-radius) - 2px)}\n%-name:focus,%-email:focus{outline:2px solid var(--surface-scheduler-accent);outline-offset:-1px}\n%-submit{padding:8px 14px;border:0;background:var(--surface-scheduler-accent);color:#fff}\n%-submit:disabled{opacity:.6;cursor:default}\n%-loading,%-no-dates{color:var(--surface-scheduler-muted)}\n%-error{color:#b91c1c;margin:0}\n%-booked{font-weight:600;color:var(--surface-scheduler-accent)}\n.surface-scheduler-frame{display:block;min-height:640px}\n`,It=()=>{if(document.getElementById(wt))return;let e=document.createElement("style");e.id=wt,e.textContent=kn.replace(/%/g,"$ .surface-booking").replace(/\$/g,".surface-scheduler"),document.head.appendChild(e)};var ge=(e,n)=>{for(let t of Object.values(e.state().answers))if(t[n]!=null)return t[n]},Be=(e,n)=>{for(let t of n){let r=e?.[t];if(typeof r=="string"&&r.length>0)return r}},wn=(e,n,t)=>({name:t?.name??Be(n.linkNameToStep&&ge(e,n.linkNameToStep.questionId),["fullName","firstName","input"]),lastName:t?.lastName??Be(n.linkLastNameToStep&&ge(e,n.linkLastNameToStep.questionId),["lastName","input"]),email:t?.email??Be(n.linkEmailToStep&&ge(e,n.linkEmailToStep.questionId),["email","emailAddress","workEmailAddress","input"])}),In=(e,n)=>{let{content:t}=e;if(e.componentType!=="DynamicScheduler")return t;let r=t.calendars??[],o;if(n!=null){if(o=r.find(s=>s.name===n),!o){let s=r.map(d=>String(d.name)).join(", ")||"(none)";throw new Error(`mountScheduler: no calendar named "${n}" on question "${e.questionId}" — available: ${s}.`)}}else if(o=t.defaultCalendar??void 0,!o&&r.length===1&&(o=r[0]),!o)throw new Error(`mountScheduler: question "${e.questionId}" routes between ${r.length} calendars with no default — pass calendarId to choose one (condition evaluation is the caller's own routing).`);let a={...t},i=[o.dataUrl,o.url].find(s=>typeof s=="string"&&s.length>0);i!=null&&(a.dataUrl=i);for(let s of["eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);return a},En=(e,{questionId:n,stepId:t})=>{if(!e.runtimeConfig)throw new Error("mountScheduler: no record to read scheduler config from (the form was booted with caller-provided steps) — init without `steps`, or mount the widget manually.");let r=pe(e.runtimeConfig.config),o=r.filter(i=>(n==null||i.questionId===n)&&(t==null||i.stepId===t));if(o.length===1)return o[0];let a=r.map(i=>`"${i.questionId}" (${i.calendarType}, step "${i.stepId}")`).join(", ");throw new Error(o.length===0?`mountScheduler: no scheduler question${n?` "${n}"`:""}${t?` on step "${t}"`:""} — the record has: ${a||"none"}.`:`mountScheduler: ${o.length} scheduler questions match — pass questionId. Candidates: ${a}.`)},Et=({form:e,container:n,questionId:t,stepId:r,styled:o=!0,persist:a=!0,prefill:i,formatters:s,calendarId:d,onEvent:l,onComplete:u})=>{let c=En(e,{questionId:t,stepId:r}),p=c.calendarType,C=kt[p];if(!C)throw new Error(`mountScheduler: unsupported provider "${c.calendarType}" on question "${c.questionId}".`);let y=In(c,d),m=!1,h=!1,v=b=>{if(m)return;if(b.type==="viewed"){if(h)return;h=!0}let A={...b,questionId:c.questionId,stepId:c.stepId,provider:p};e.notifyScheduler(A);try{l?.(A)}catch(x){console.warn("Surface SDK: mountScheduler onEvent handler failed",x)}},g=(b,A)=>{a&&(e.setAnswer(c.questionId,{type:c.componentType,...b}),A?.save&&!e.state().finished&&e.savePartial())},L=(b,A)=>{let x={...b,provider:p},O={eventScheduled:!0,uri:x.uri},S={meetingTime:x.meetingTime,meetingEndTime:x.meetingEndTime,ownerEmails:x.ownerEmails,guestEmails:x.guestEmails,inviteeName:x.inviteeName,googleMeetLink:x.joinLink};for(let[w,_]of Object.entries(S))_!==void 0&&(O[w]=_);g({...O,...A},{save:!0}),v({type:"booking_confirmed",booking:x});try{u?.(x)}catch(w){console.warn("Surface SDK: mountScheduler onComplete handler failed",w)}},P=b=>{g({eventScheduled:!1,eventCancelled:!0,...b!=null&&{cancelReason:b}},{save:!0}),v({type:"booking_cancelled",...b!=null&&{reason:b}})},k=async()=>e.preview?null:(e.state().responseId==null&&a&&await e.savePartial(),e.state().responseId);o&&(It(),n.classList.add("surface-scheduler"));let T=Object.fromEntries(Object.entries(y.dataUrlParams??{}).flatMap(([b,A])=>{let x=ge(e,A.questionId)?.[A.variable];return typeof x=="string"&&x.length>0?[[b,x]]:[]})),U=C({form:e,container:n,question:c,content:y,prefill:wn(e,y,i),urlParams:T,formatters:s,styled:o,emit:v,confirmBooking:L,cancelBooking:P,mergeAnswer:g,ensureResponseId:k});return v({type:"viewed"}),()=>{m||(m=!0,o&&n.classList.remove("surface-scheduler"),U())}};var Tn="/api/v1/edge/emailValidation",Tt=e=>({email:e,isValid:!0,status:"unknown",reason:"validation_failed",failed:!0}),Rn=(e,n)=>!n||typeof n.isValid!="boolean"?Tt(e):{email:e,isValid:n.isValid,status:n.status,reason:n.reason,...n.blacklistEntryIds?.length?{blacklistEntryIds:n.blacklistEntryIds}:{},...n.validationSuccessfullyRan===!1?{failed:!0}:{}},ye=({transport:e,environmentId:n,preview:t=!1})=>{let r=new Map,o=a=>{let i=[...new Set(a.map(d=>d.trim()).filter(d=>d!==""))];if(t)for(let d of i)r.has(d)||r.set(d,Promise.resolve({email:d,isValid:!0,status:"preview"}));let s=i.filter(d=>!r.has(d));if(s.length>0){let d=e.post(Tn,{emails:s,environmentId:n}).then(l=>l.ok?l.data.data??{}:{}).catch(()=>({}));for(let l of s)r.set(l,d.then(u=>Rn(l,u[l])))}return Promise.all(i.map(d=>r.get(d)))};return{validateBatch:o,validate:async a=>{let[i]=await o([a]);return i??Tt(a.trim())}}};var An="/api/v1/responses/",Rt="/api/v1/responses/update",_n="/api/v1/responses/getResponse",he=async(e,n)=>{let t=await e.post(An,n,{credentials:!0});if(!t.ok)return t;let r=t.data.data?.id;return r?{ok:!0,data:{responseId:r,leadId:t.data.data?.meta?.leadId??null,resumeToken:t.data.data?.resumeToken??null}}:{ok:!1,error:{kind:"http",status:200,body:t.data}}},ee=(e,n)=>{e.beacon(Rt,n)},At=(e,n)=>e.post(Rt,n,{keepalive:!0,credentials:!0}),Cn=e=>typeof e?.questionId=="string"&&typeof e?.response=="object"&&e.response!==null,_t=async(e,{responseId:n,resumeToken:t})=>{let r=await e.get(`${_n}?rid=${encodeURIComponent(n)}&rt=${encodeURIComponent(t)}`);return r.ok?{ok:!0,data:{answers:(Array.isArray(r.data.data?.data)?r.data.data.data:[]).filter(Cn).filter(a=>a.response.type!=="URL_DATA")}}:r};var z="https://forms.withsurface.com",Ct="0.1.0",Ve=(e={})=>({...e,"X-Surface-Sdk-Version":Ct}),xn=e=>`${e}${e.includes("?")?"&":"?"}sdv=${Ct}`,ve=({apiBaseUrl:e=z}={})=>{let n=e.replace(/\/$/,""),t=i=>`${n}${i}`;return{get:async i=>{try{let s=await fetch(t(i),{headers:Ve()});if(!s.ok){let d=await s.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:s.status,body:d}}}return{ok:!0,data:await s.json()}}catch(s){return{ok:!1,error:{kind:"network",cause:s}}}},post:async(i,s,d)=>{try{let l=await fetch(t(i),{method:"POST",headers:Ve({"Content-Type":"application/json"}),body:JSON.stringify(s),...d?.keepalive?{keepalive:!0}:{},...d?.credentials?{credentials:"include"}:{}});if(!l.ok){let u=await l.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:l.status,body:u}}}return{ok:!0,data:await l.json()}}catch(l){return{ok:!1,error:{kind:"network",cause:l}}}},beacon:(i,s)=>{let d;try{d=JSON.stringify(s)}catch{return!1}let l=xn(t(i));try{if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&navigator.sendBeacon(l,new Blob([d],{type:"application/json"})))return!0}catch{}try{fetch(l,{method:"POST",keepalive:!0,credentials:"include",headers:Ve({"Content-Type":"application/json"}),body:d}).catch(()=>{})}catch{}return!1}}};var xt=["firstName","lastName","fullName","emailAddress","workEmailAddress","phoneNumber","companyName","numberOfEmployees","websiteUrl","title","streetAddress","aptSuiteEtc","city","state","country","zipCode","companyRevenue","profilePictureUrl"];var be=()=>{let e=new Map;return{on:(n,t)=>{let r=e.get(n)??new Set;return r.add(t),e.set(n,r),()=>{r.delete(t)}},emit:(n,t)=>{e.get(n)?.forEach(r=>{try{r(t)}catch(o){console.error(`Surface SDK: "${String(n)}" handler threw`,o)}})}}};var Pn="/api/v1/pushEvent",Mn=/bot|crawl|spider|slurp|baidu|bingpreview|googlebot|yandex|duckduck|ahrefs|semrush|facebookexternalhit|embedly|quora link preview|pinterest|twitterbot|linkedinbot|whatsapp|telegram|discord|headless|lighthouse|pagespeed/i,Ln=()=>{let e=navigator.userAgent;return e?Mn.test(e):!1},On=e=>!!(e?.type&&e?.entityType&&e?.entityId),Se=({sessionId:e,formId:n,currentStepId:t,nextStepId:r,stepCompletionTime:o})=>({events:[{type:"form_step_submitted",entityType:"form_step",entityId:n,stepId:t,leadSessionId:e,properties:[{key:"stepCompletionTime",value:o}]},{type:"form_step_viewed",entityType:"form_step",entityId:n,stepId:r,leadSessionId:e,properties:[]}]}),ke=({transport:e,preview:n=!1})=>({push:t=>{if(n||typeof navigator>"u")return;let r="events"in t?t.events:[t];Ln()||r.some(o=>!On(o))||e.beacon(Pn,t)}});var we=e=>{let n=je(e),t=!1;return r=>t||He(n,r)?!1:(t=!0,!0)},je=e=>{if(Array.isArray(e))return e.map(je);if(e!==null&&typeof e=="object"){let n={};for(let[t,r]of Object.entries(e))n[t]=je(r);return n}return e},He=(e,n)=>{if(Object.is(e,n))return!0;if(Array.isArray(e)||Array.isArray(n))return!Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?!1:e.every((t,r)=>He(t,n[r]));if(e!==null&&n!==null&&typeof e=="object"&&typeof n=="object"){let t=Object.keys(e),r=Object.keys(n);return t.length!==r.length?!1:t.every(o=>He(e[o],n[o]))}return!1};var Ke=(e,n)=>{let t=[],r={},o;for(let a in e){let i=e[a];for(let s in i){let d=i[s];!o&&d?.eventScheduled===!0&&typeof d.uri=="string"&&d.uri.length>0&&!d.uri.includes("calendly.com")&&!d.uri.includes("cal.com")&&(o=d.uri),t.push({questionId:s,response:{...i[s]}})}}for(let a in n){let i=n[a];i.type!=="SCHEDULER_AVAILABILITY_DATA"&&(t.push({questionId:a,response:{...i}}),i.type==="APOLLO_EMAIL_ENRICHMENT"&&i.processed&&(r=i.data??{}))}return{responses:t,enrichedFields:r,bookingId:o}},Pt=({formId:e,answers:n,externalStates:t,submittingOnStepId:r,finished:o,invalidResponse:a,trackCookies:i,meta:s={},personAttributeEnrichedFields:d,fingerprint:l,leadSessionId:u})=>{let{responses:c,enrichedFields:p,bookingId:C}=Ke(n,t),y=i?s:Object.fromEntries(Object.entries(s).filter(([m])=>m!=="cookies"));return{responses:c,enrichedFields:d??p??{},formId:e,finished:o,invalidResponse:a,stepId:r,fingerprint:l,leadSessionId:u,meta:C?{...y,bookingId:C}:y}},Ie=e=>({...Pt(e),responseShapeVersion:"2.0"}),Y=e=>({...Pt(e),responseId:e.responseId});var Ee=({formId:e,environmentId:n,steps:t,transport:r,resolveNextStep:o,trackPartialResponses:a=!0,trackCookies:i=!1,externalStates:s={},meta:d={},identity:l,pushEvents:u,formJourney:c,preview:p=!1,resume:C})=>{if(t.length===0)throw new Error("createFormEngine requires at least one step");let y=o??(f=>{let I=t.findIndex(H=>H.id===f),$=t[I+1];return $?{stepId:$.id,reason:"linear"}:"END"}),m=be(),h=new Set,v=!0,g,L=()=>{v=!0,h.forEach(f=>f())},P=()=>l?.()??{},k={},T=t[0].id,U=C?.responseId??null,b=null;if(C?.answers){let f={};for(let[I,$]of Object.entries(C.answers))f[I]={...$};k[T]=f}let A=!1,x=null,O=!1,S=Date.now(),w=[],_=we(k);c?.setFormId(e),U!=null&&c?.setResponseId(U),c?.recordEntry(T);let q=async(f,I,$)=>{if(p)return;let H={formId:e,answers:k,externalStates:s,submittingOnStepId:f,finished:I,invalidResponse:$,trackCookies:i,meta:d,fingerprint:P().fingerprint,leadSessionId:P().leadSessionId};if(U==null){let K=await he(r,Ie(H));if(!K.ok){K.error.kind==="network"&&u?.push({type:"response_submission_error",entityType:"response",entityId:e,stepId:f,leadSessionId:P().leadSessionId,properties:[{key:"error",value:"network"}]}),m.emit("error",{scope:"submit",error:K.error});return}U=K.data.responseId,b=K.data.resumeToken,c?.setResponseId(U),u?.push({type:"response_submission_created",entityType:"response",entityId:e,stepId:f,leadSessionId:P().leadSessionId,properties:[{key:"responseId",value:U}]})}else if(I){let K=await At(r,Y({...H,responseId:U}));if(!K.ok){ee(r,Y({...H,responseId:U})),m.emit("error",{scope:"submit",error:K.error});return}}else ee(r,Y({...H,responseId:U}));L(),m.emit("saved",{responseId:U,finished:I,resumeToken:b})},F=Promise.resolve(),M=f=>{let I=F.then(()=>A?void 0:f());return F=I.catch(()=>{}),I},E=()=>{if(!A||x==null)return;let f=x;F=F.then(()=>{if(U!=null)return q(f.stepId,!0,f.invalid)}).catch(()=>{})},R=null,D=f=>{if(A)return Promise.resolve();if(R)return R;let I=M(()=>Zt(f)).finally(()=>{R===I&&(R=null)});return R=I,I},J=f=>{if(A||R)return R??Promise.resolve();let I=y(T,k),$=f||I==="END"||I==="INVALID"||I==null;return m.emit("stepCompleted",{stepId:T}),$?D(I==="INVALID"):(tt(I),Promise.resolve())},Ne=f=>{let I=T;for(;w.length>0&&T!==f;)T=w.pop();L(),c?.recordTransition({fromStepId:I,toStepId:T,reason:"back_nav"}),m.emit("stepChanged",{fromStepId:I,toStepId:T})},Yt=f=>t.some(I=>I.id===f)?A||R?R??Promise.resolve():f===T?Promise.resolve():w.includes(f)?(Ne(f),Promise.resolve()):(m.emit("stepCompleted",{stepId:T}),tt({stepId:f,reason:"conditional_match"}),Promise.resolve()):Promise.reject(new Error(`goToStep: no step with id "${f}"`)),Gt=()=>A||R?R??Promise.resolve():(m.emit("stepCompleted",{stepId:T}),D(!0)),tt=f=>{let I=T;u?.push(Se({sessionId:P().leadSessionId,formId:e,currentStepId:I,nextStepId:f.stepId,stepCompletionTime:(Date.now()-S)/1e3})),c?.recordTransition({fromStepId:I,toStepId:f.stepId,reason:f.reason??"linear"}),w.push(I),T=f.stepId,L(),m.emit("stepChanged",{fromStepId:I,toStepId:T}),a&&M(()=>q(I,!1,!1))},Xt=f=>{let I=t.find(H=>H.endStepKind===f);if(!I||I.id===T)return;let $=T;w.push($),T=I.id,L(),m.emit("stepChanged",{fromStepId:$,toStepId:T})},Zt=async f=>{let I=T;A=!0,x={stepId:I,invalid:f},await q(I,!0,f),Xt(f?"disqualified":"thank_you"),f?(c?.recordTerminal({outcome:"disqualified",disqualification:{reason:"conditional_match",atStepId:I}}),m.emit("disqualified",{stepId:I})):(c?.recordTerminal({outcome:"completed"}),u?.push({type:"form_completed",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[],environmentId:n,leadId:P().leadId}),m.emit("completed",{formId:e})),L()};return{setAnswer:(f,I)=>{let $=k[T]??(k[T]={});$[f]={...$[f],...I},_(k)&&(u?.push({type:"form_started",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[]}),m.emit("started",{formId:e})),L(),E()},setExternalState:(f,I)=>{s[f]=I,L(),E()},mergeMeta:f=>{Object.assign(d,f),E()},next:()=>J(!1),goToStep:Yt,submit:()=>J(!0),disqualify:Gt,back:()=>{if(A||R)return;let f=w.pop();if(f==null)return;let I=T;T=f,L(),c?.recordTransition({fromStepId:I,toStepId:f,reason:"back_nav"}),m.emit("stepChanged",{fromStepId:I,toStepId:f})},savePartial:()=>{let f=T;return M(()=>q(f,!1,!1))},notifyScheduler:f=>m.emit("scheduler",f),flush:()=>F.then(()=>{}),markViewed:()=>{O||(O=!0,u?.push({type:"form_viewed",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[],environmentId:n,leadId:P().leadId}),u?.push({type:"form_step_viewed",entityType:"form_step",entityId:e,stepId:t[0].id,leadSessionId:P().leadSessionId,properties:[]}),m.emit("viewed",{formId:e}))},on:m.on,state:()=>(v&&(g={currentStepId:T,answers:k,externalStates:s,responseId:U,resumeToken:b,finished:A},v=!1),g),subscribe:f=>(h.add(f),()=>h.delete(f))}};var Mt=400,Fn=(e,n="https")=>!e||e.startsWith(n)?e:`${n}://${e}`,We=(e,{leadId:n,sessionId:t}={})=>{if(!e||!e.trim())return"";try{let r=new URL(Fn(e));return n&&r.searchParams.set("leadId",n),t&&r.searchParams.set("sessionId",t),r.toString()}catch{return e}},Lt=({url:e,redirectType:n="CurrentWindow",leadId:t,sessionId:r,preview:o=!1})=>{if(!e||o||typeof window>"u")return;let a=We(e,{leadId:t,sessionId:r});a&&(n==="CurrentWindow"?window.location.href=a:n==="NewTab"&&window.open(a,"_blank"))};var Je=e=>{let n=new URL(e);if(!n.search)return{};let t={};return new URLSearchParams(n.search).forEach((r,o)=>{t[o]=r}),t},Qe=e=>{let n={};for(let t of e.split(";")){let r=t.trim(),o=r.indexOf("=");if(o<=0)continue;let a=r.substring(o+1);try{n[r.substring(0,o)]=decodeURIComponent(a)}catch{n[r.substring(0,o)]=a}}return n},Te=({defaultUrl:e,trackCookies:n=!1}={})=>{let t=typeof window<"u",r={type:"URL_DATA",fullUrl:e??(t?window.location.href:void 0),referrer:t&&typeof document<"u"?document.referrer||"":void 0};if(r.fullUrl)try{r.params=Je(r.fullUrl)}catch{}return n?r.cookies=t&&typeof document<"u"?Qe(document.cookie):{}:r.cookies={},r};var ze=e=>{let n=e.indexOf("_");return{originalId:e,questionId:n>=0?e.slice(0,n).trim():e,fieldName:n>=0?e.slice(n+1).trim():null}},Dn=new Set(["url","referrer","cookies"]),Ot=e=>{let n=typeof e=="string"?new URLSearchParams(e):e,t=null;for(let r of n.keys()){if(Dn.has(r))continue;let{originalId:o,questionId:a,fieldName:i}=ze(r);if(i==null)continue;let s={originalId:o,questionId:a,fieldName:i,value:n.get(r)};t??(t=Object.create(null)),t[a]=[...t[a]??[],s]}return t};var Re=(e,n)=>{if(typeof window>"u")return()=>{};let t=r=>{let{started:o,formId:a,stepId:i,sessionId:s}=n();!o||r.persisted||e.push({type:"form_step_dropoff",entityType:"form_step",entityId:a,stepId:i,leadSessionId:s,properties:[]})};return window.addEventListener("pagehide",t),()=>window.removeEventListener("pagehide",t)};var Un="/api/v1/form-journey/track";var qn=new Set(["completed","disqualified","dropped_off","partial"]),Ae=({transport:e,preview:n=!1})=>{let t={responseId:null,formId:null,nextOrdinal:1,enteredAt:new Map,pendingClose:null,visits:[],truncated:!1,terminal:{},frozen:!1,flushScheduled:!1},r=()=>{t.flushScheduled=!1,!n&&(!t.responseId||!t.formId||t.visits.length===0&&!t.terminal.outcome||(e.beacon(Un,{responseId:t.responseId,formId:t.formId,events:t.visits,...t.terminal}),t.terminal={}))},o=()=>{t.flushScheduled||(t.flushScheduled=!0,queueMicrotask(()=>{t.flushScheduled&&r()}))},a=s=>{if(!t.pendingClose)return;let{ordinal:d,stepId:l}=t.pendingClose,u=t.enteredAt.get(d),c=t.visits.find(C=>C.ordinal===d),p=u?Date.parse(s)-Date.parse(u):null;c?(c.exitedAt=s,c.durationMs=p):t.visits.push({ordinal:d,stepId:l,enteredAt:u??s,exitedAt:s,durationMs:p,fromStepId:null,transitionReason:"initial"}),t.pendingClose=null},i=s=>t.visits.length>=50?(t.truncated=!0,!1):(t.visits.push(s),!0);return{hasRecordedTransition:()=>t.nextOrdinal>1,setResponseId:s=>{t.responseId=s,o()},setFormId:s=>{t.formId=s,o()},recordEntry:s=>{if(t.frozen||t.truncated)return;let d=(new Date).toISOString();t.nextOrdinal===1&&(t.enteredAt.set(1,d),t.pendingClose={ordinal:1,stepId:s},t.nextOrdinal=2)},recordTransition:({fromStepId:s,toStepId:d,reason:l,transitionMeta:u})=>{if(t.frozen||t.truncated)return;let c=(new Date).toISOString();a(c);let p=t.nextOrdinal++;t.enteredAt.set(p,c);let C=i({ordinal:p,stepId:d,enteredAt:c,exitedAt:null,durationMs:null,fromStepId:s,transitionReason:l,transitionMeta:u??null});t.pendingClose=C?{ordinal:p,stepId:d}:null,o()},recordTerminal:({outcome:s,disqualification:d})=>{if(t.frozen)return;let l=(new Date).toISOString();a(l),t.terminal={outcome:s,disqualification:d?{reason:d.reason,matched:d.matched}:void 0,disqualifiedAtStepId:d?.atStepId,disqualifiedTriggerStepId:d?.triggerStepId},qn.has(s)&&(t.frozen=!0),s==="in_progress"?r():o()}}};async function Ye(e){let n=(new TextEncoder).encode(e),t=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}var _e=async e=>{let n=navigator.userAgentData||{},t={deviceType:/Mobi|Android/i.test(navigator.userAgent)?"Mobile":"Desktop",screen:{width:screen.width,height:screen.height,colorDepth:screen.colorDepth},userAgent:navigator.userAgent,browser:n.brands||n.uaList||[{brand:"unknown",version:"unknown"}],os:n.platform||"unknown",language:navigator.language,...navigator.plugins!=null?{plugins:Array.from(navigator.plugins).map(r=>r.name)}:{},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,environmentId:e};return{...t,id:await Ye(JSON.stringify(t))}};var Nn="/api/v1/lead/identify",Ce=({environmentId:e,fingerprintId:n,pageUrl:t,source:r="sdkForm",formId:o,leadId:a=null,sessionIdFromParams:i=null,referrer:s})=>{let d=new URL(t);return{environmentId:e,source:r,sourceURL:d.href.replace(/\/$/,""),sourceURLDomain:d.hostname,sourceURLPath:d.pathname.replace(/\/$/,""),sourceUrlSearchParams:d.search,fingerprint:n,formId:o,leadId:a,sessionIdFromParams:i,...s!=null?{referrer:s}:{}}},xe=async(e,n)=>{let t=await e.post(Nn,n,{keepalive:!0,credentials:!0});if(!t.ok)return null;let r=t.data.data?.data;return!r?.leadId||!r?.sessionId?null:{leadId:r.leadId,sessionId:r.sessionId,existing:r.existing,leadHasExistingBookingAttr:r.leadHasExistingBookingAttr,leadHasExistingEmailAttr:r.leadHasExistingEmailAttr}};var te="surfaceLeadData",Ft=6e5,G=()=>{if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(te);if(!e)return null;let n=JSON.parse(e);return Date.now()>(n.expiry??0)?(localStorage.removeItem(te),null):{leadId:n.leadId,leadSessionId:n.leadSessionId,fingerprint:n.fingerprint,landingPageUrl:n.landingPageUrl,expiry:n.expiry}}catch{return null}},Pe=e=>{if(!(typeof localStorage>"u"))try{localStorage.setItem(te,JSON.stringify({...e,expiry:Date.now()+6e5}))}catch{}};var ne=async({transport:e,environmentId:n,formId:t,pageUrl:r,source:o,preview:a=!1})=>{if(a||typeof window>"u")return null;let i=G();if(i?.leadSessionId&&i?.fingerprint)return i;let s=r??window.location.href,d=await _e(n),l=await xe(e,Ce({environmentId:n,fingerprintId:d.id,pageUrl:s,formId:t,source:o,leadId:i?.leadId??null,sessionIdFromParams:i?.leadSessionId??null}));if(l==null)return null;let u={leadId:l.leadId,leadSessionId:l.sessionId,fingerprint:d.id,landingPageUrl:s};return Pe(u),u};var re="surface_journey_id",oe="surface_recent_visit",$n=5184e3,Bn=86400,Dt="/api/v1/lead/track",Ut=e=>{if(typeof document>"u")return null;for(let n of document.cookie.split(";")){let t=n.trim(),r=t.indexOf("=");if(r===-1||t.substring(0,r)!==e)continue;let o=t.substring(r+1);try{return decodeURIComponent(o)}catch{return o}}return null},qt=(e,n,t,r)=>{if(typeof document>"u")return;let o=r?`; domain=${r}`:"";document.cookie=`${e}=${encodeURIComponent(n)}; path=/; max-age=${t}; samesite=lax${o}`},Ge=()=>{let e=typeof window>"u"?"":window.location?.hostname??"";if(!e||!e.includes("."))return;let n=e.split(".");return"."+(n.length===2?e:n.slice(1).join("."))},Me=({transport:e,environmentId:n})=>{let t=Ut(re),r=()=>{t&&qt(re,t,$n,Ge())},o=d=>{let l=G();return{...t?{id:t}:{},data:{type:"page_view",payload:{url:d,timestamp:(new Date).toISOString(),referrer:typeof document>"u"?"":document.referrer||""}},metadata:{environmentId:n,...l?{...l.leadId?{leadId:l.leadId}:{},...l.leadSessionId?{leadSessionId:l.leadSessionId}:{},fingerprint:l.fingerprint,...l.landingPageUrl?{landingPageUrl:l.landingPageUrl}:{}}:{}}}},a=async d=>{if(typeof window>"u")return;let l=d??window.location.href;if(Ut(oe)===l)return;let u=o(l);if(t&&e.beacon(Dt,u))r();else{let c=await e.post(Dt,u);c.ok&&c.data.data?.id&&(t=c.data.data.id),r()}qt(oe,l,Bn,Ge())};return{trackPageView:a,observeRouteChanges:()=>{if(typeof window>"u")return()=>{};let d=window.location.href,l=()=>{let p=window.location.href;p!==d&&(d=p,a(p))};window.addEventListener("popstate",l);let u=history.pushState,c=history.replaceState;return history.pushState=function(...p){u.apply(history,p),setTimeout(l,0)},history.replaceState=function(...p){c.apply(history,p),setTimeout(l,0)},()=>{window.removeEventListener("popstate",l),history.pushState=u,history.replaceState=c}},clear:()=>{let d=Ge(),l=d?`; domain=${d}`:"";typeof document>"u"||(document.cookie=`${re}=; path=/; max-age=0; samesite=lax${l}`,document.cookie=`${oe}=; path=/; max-age=0; samesite=lax${l}`,t=null)}}};var Vn="/api/v1/services/enrichment/realtime",Le="selfServeEnrichment";var jn=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,Hn=/^(?:https?:\/\/)?(?:www\.)?([a-z0-9-]+(?:\.[a-z0-9-]+)+)/i,Nt=e=>{let n=e.trim();if(jn.test(n))return{email:n};let t=n.match(Hn)?.[1];return t?{domain:t}:null},Oe=({engine:e,transport:n,formId:t,sources:r})=>{let o=new Set,a=new Set,i,s,d=!1,l=async y=>{let m=Nt(y);if(!m)return;let h=m.email??m.domain;if(!(o.has(h)||a.has(h))){a.add(h);try{let v=await n.post(Vn,{formId:t,...m});if(d||!v.ok)return;let g=v.data.data??{};if(Object.keys(g).length===0)return;o.add(h);let L=e.state().externalStates[Le],P=L?.type==="APOLLO_EMAIL_ENRICHMENT"?L.data??{}:{};e.setExternalState(Le,{type:"APOLLO_EMAIL_ENRICHMENT",processed:!0,data:{...g,...P}})}finally{a.delete(h)}}},u=()=>{let y=[],m={};for(let h of Object.values(e.state().answers))Object.assign(m,h);for(let{questionId:h,fieldNames:v}of r){let g=m[h];if(g)for(let L of v){let P=g[L];typeof P=="string"&&P.trim().length>0&&y.push(P)}}return y},c=()=>{let y=u().find(m=>{let h=Nt(m);return h!=null&&!o.has(h.email??h.domain)});y===void 0||y===s||(s=y,clearTimeout(i),i=setTimeout(()=>{s=void 0,l(y)},1e3))},p=()=>{if(s===void 0)return;clearTimeout(i);let y=s;s=void 0,l(y)},C=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{d=!0,clearTimeout(i),C.forEach(y=>y())}};var Kn=new Set(["MultipleOptionsQuestion","MultipleChoiceQuestion","MMChoiceQuestion"]),Wn=(e,n)=>typeof e=="object"&&e!==null&&typeof e.key=="string"&&typeof e.value=="boolean"&&(!n||typeof e.index=="number"),$t=({questions:e,questionId:n,merged:t})=>{let r=`Surface SDK [debug]: setAnswer("${n}")`,o=e.size>0?e.get(n):void 0;if(e.size>0&&!o){console.warn(`${r} — the record has no stateful question with this id; the answer will be dropped.`),console.debug(`Surface SDK [debug]: answer ${n}`,t);return}t.type===void 0?console.warn(`${r} — state has no "type" discriminator; the wire schema rejects untyped states. Include type: "${o?.componentType??"<ComponentType>"}".`):o?.componentType!==void 0&&t.type!==o.componentType&&console.warn(`${r} — state type "${String(t.type)}" but the record's component is ${o.componentType}.`);let a=o?.componentType??t.type;if(typeof a=="string"&&Kn.has(a)){let i=a==="MultipleOptionsQuestion";(!Array.isArray(t.choices)||t.choices.some(d=>!Wn(d,i)))&&console.warn(`${r} — ${a} answers need the ENTIRE option list under "choices" as {key, value${i?", index":""}} objects, not ${JSON.stringify(t.choices??t)}. See get_sdk_binding_map's answerShape.`)}console.debug(`Surface SDK [debug]: answer ${n}`,t)};var Jn="Lead",Qn="generate_lead",zn="lead_created",jt=/^tw-([a-z0-9]+)-([a-z0-9]+)$/i,Yn=e=>{let n=e?.trim().match(jt);return n?n[1]:null},Bt=e=>/^\d+$/.test(e?.trim()??""),Gn=e=>{if(e.enabled===!1||(e.trigger??"reached_qualified")==="reached_step"&&!e.triggerStepId?.trim())return!1;switch(e.provider){case"x":return jt.test(e.eventId?.trim()??"");case"meta":case"openai":return!!e.pixelId?.trim();case"ga4":return!!e.measurementId?.trim();case"linkedin":return Bt(e.partnerId)&&Bt(e.conversionId);default:return!1}},Xn=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o},Vt=(e,n)=>{let t=Xn(n,e.param)?.trim()??"",r=e.values??[];switch(e.operator){case"is_present":return t.length>0;case"equals_any":return r.some(o=>o.trim().toLowerCase()===t.toLowerCase());case"contains":return t.length>0&&r.some(o=>t.toLowerCase().includes(o.trim().toLowerCase()));default:return!1}},Zn=(e,n,t="and")=>e.length===0?!0:t==="or"?e.some(r=>Vt(r,n)):e.every(r=>Vt(r,n)),er=e=>{if(!Gn(e))return null;switch(e.provider){case"x":{let n=Yn(e.eventId);return n?{provider:"x",event:{event_id:e.eventId.trim(),pixel_id:n}}:null}case"meta":return{provider:"meta",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||Jn}};case"openai":return{provider:"openai",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||zn}};case"ga4":return{provider:"ga4",event:{measurement_id:e.measurementId.trim(),event_name:e.eventName?.trim()||Qn}};case"linkedin":return{provider:"linkedin",event:{partner_id:e.partnerId.trim(),conversion_id:e.conversionId.trim()}};default:return null}},Fe=(e,n,t,r)=>{let o=[];for(let a of e){if((a.trigger??"reached_qualified")!==n||n==="reached_step"&&(!r||a.triggerStepId!==r)||!Zn(a.conditions??[],t,a.conditionsOperator??"and"))continue;let i=er(a);i&&o.push({rule:a,conversion:i})}return o},tr=(e,n)=>{if(!e.twq){let t=e.twq=function(...o){t.exe?t.exe.apply(t,o):t.queue.push(o)};t.version="1.1",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://static.ads-twitter.com/uwt.js",e.document.head.appendChild(r)}e.twq("config",n)},nr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...o){t.callMethod?t.callMethod.apply(t,o):t.queue.push(o)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://connect.facebook.net/en_US/fbevents.js",e.document.head.appendChild(r)}e.fbq("init",n)},rr=(e,n)=>{if(!e.oaiq){let t=e.oaiq=function(...o){t.q.push(o)};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://bzrcdn.openai.com/sdk/oaiq.min.js",e.document.head.appendChild(r)}e.oaiq("init",{pixelId:n})},or=(e,n)=>{if(!e.gtag){e.dataLayer=e.dataLayer||[],e.gtag=function(...r){e.dataLayer.push(r)};let t=e.document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`,e.document.head.appendChild(t),e.gtag("js",new Date)}e.gtag("config",n,{send_page_view:!1})},sr=(e,n)=>{if(!e.lintrk){e._linkedin_partner_id=n;let t=e.lintrk=function(o,a){t.q.push([o,a])};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://snap.licdn.com/li.lms-analytics/insight.min.js",e.document.head.appendChild(r)}e._linkedin_data_partner_ids=e._linkedin_data_partner_ids||[],e._linkedin_data_partner_ids.includes(n)||e._linkedin_data_partner_ids.push(n)},Ht=(e,n,t)=>{let r=e;try{switch(n.provider){case"x":return tr(r,n.event.pixel_id),r.twq("event",n.event.event_id,{conversion_id:t.responseId,...t.twclid?{twclid:t.twclid}:{},...t.email?{email_address:t.email}:{}}),!0;case"meta":return nr(r,n.event.pixel_id),r.fbq("track",n.event.event_name,{},{eventID:t.responseId}),!0;case"openai":return rr(r,n.event.pixel_id),r.oaiq("measure",n.event.event_name,{type:"customer_action"},{event_id:t.responseId}),!0;case"ga4":return or(r,n.event.measurement_id),r.gtag("event",n.event.event_name,{transaction_id:t.responseId,send_to:n.event.measurement_id}),!0;case"linkedin":return sr(r,n.event.partner_id),r.lintrk("track",{conversion_id:n.event.conversion_id}),!0;default:return!1}}catch{return!1}};var Xe=(e,n)=>e.document.querySelector(`script[src="${n}"]`)!=null,De=(e,n,t,r)=>{if(Xe(e,n))return;let o=e.document.createElement("script");o.async=!0,o.src=n,r&&(o.id=r),e.document[t].appendChild(o)},ir=(e,n)=>{let t=`https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(n)}`;Xe(e,t)||(e.dataLayer=e.dataLayer||[],e.dataLayer.push({"gtm.start":(new Date).getTime(),event:"gtm.js"}),De(e,t,"head"))},ar=(e,n)=>{let t=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`;if(Xe(e,t))return;e.dataLayer=e.dataLayer||[],e.gtag||(e.gtag=function(){e.dataLayer.push(arguments)},e.gtag("js",new Date)),De(e,t,"head");let r=e.self!==e.top;e.gtag("config",n,{...r&&{cookie_flags:"SameSite=None;Secure;Partitioned"}})},dr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...r){t.callMethod?t.callMethod.apply(t,r):t.queue.push(r)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],De(e,"https://connect.facebook.net/en_US/fbevents.js","head")}e.fbq("init",n)},lr=(e,n)=>{De(e,`https://js.hs-scripts.com/${n}.js`,"body","hs-script-loader")},Kt=(e,n)=>{let t=e;n.gtmId&&ir(t,n.gtmId),n.gaMeasurementId&&ar(t,n.gaMeasurementId),n.metaPixelId&&dr(t,n.metaPixelId),n.hubspotTracking?.trackingId&&lr(t,n.hubspotTracking.trackingId);let r=i=>{n.gtmId&&(t.dataLayer=t.dataLayer||[],t.dataLayer.push(i))},o=(i,s)=>{n.gaMeasurementId&&t.gtag?.("event",i,s)},a=(i,s)=>{n.metaPixelId&&t.fbq?.("trackCustom",i,s)};return{formStarted:(i,s)=>{r({event:"SurfaceFormStarted",formId:i,...s}),a("SurfaceFormStarted",{formId:i,...s}),o("SurfaceFormStarted",{formId:i,...s})},stepSubmitted:i=>{r({event:"SurfaceFormStepSubmitted",...i}),a("SurfaceFormStepSubmitted",i),o("SurfaceFormStepSubmitted",i)},formCompleted:(i,s)=>{r({event:"SurfaceFormSubmitEvent",formId:i,...s}),a("SurfaceFormCompleted",{formId:i,...s}),o("SurfaceFormCompleted",{formId:i,...s})}}};var ur=e=>{try{return Object.fromEntries(new URLSearchParams(e.location.search).entries())}catch{return{}}},Ue=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o?.trim()||void 0},cr=e=>({twclid:Ue(e,"twclid"),fbclid:Ue(e,"fbclid"),gclid:Ue(e,"gclid"),li_fat_id:Ue(e,"li_fat_id")}),pr=["email","emailAddress","workEmailAddress"],Ze=e=>{for(let n of Object.values(e))for(let t of pr){let r=n[t];if(typeof r=="string"&&r.trim().length>0)return r.trim()}},Wt=e=>Object.values(e).some(n=>n.eventScheduled===!0),et=e=>{let n={};for(let t of Object.values(e.state().answers))Object.assign(n,t);return n},Jt=({engine:e,formId:n,settings:t,win:r})=>{let o=r??window,a=Kt(o,t),i=t.adsConversions??[],s=ur(o),d={url:o.location.href,urlParams:s},l=new Set,u=new Set,c=new Set,p=new Set,C=!1,y=!1,m=!1,h=!1,v=!1,g=e.state().responseId==null,L=!g,P=(S,w)=>{let _=S.filter(({rule:F})=>!l.has(F.id));if(_.length===0)return;_.forEach(({rule:F})=>l.add(F.id));let q={responseId:w,email:Ze(et(e)),...cr(s)};_.forEach(({conversion:F})=>Ht(o,F,q))},k=(S,w)=>{if(!w){p.add(S);return}P(Fe(i,S,s),w)},T=(S,w)=>{if(!w){c.add(S);return}P(Fe(i,"reached_step",s,S),w)},U=S=>{if(!S){C=!0;return}y=!0,C=!1;let w=new Map;for(let _ of["reached_qualified","form_submitted"])for(let q of Fe(i,_,s))w.set(q.rule.id,q);P(Array.from(w.values()),S)},b=()=>{let S=et(e);!h&&g&&Ze(S)!==void 0&&(h=!0,k("email_provided",e.state().responseId)),!v&&g&&Wt(S)&&(v=!0,k("meeting_booked",e.state().responseId))},A=[];A.push(e.on("started",()=>{a.formStarted(n,d)}));let x;A.push(e.on("stepCompleted",({stepId:S})=>{let w=et(e);x={stepId:S,formId:n,emailProvided:Ze(w)!==void 0,meetingBooked:Wt(w),...d},!m&&g&&(m=!0,k("step_submitted",e.state().responseId))})),A.push(e.on("stepChanged",({toStepId:S})=>{x&&(e.state().finished||a.stepSubmitted(x),x=void 0),!u.has(S)&&(u.add(S),T(S,e.state().responseId))})),A.push(e.on("completed",()=>{x=void 0,a.formCompleted(n,d),y||U(e.state().responseId)})),A.push(e.on("saved",({responseId:S})=>{if(L||(L=!0,k("form_started",S)),C&&U(S),c.size>0){let w=Array.from(c);c.clear(),w.forEach(_=>T(_,S))}if(p.size>0){let w=Array.from(p);p.clear(),w.forEach(_=>k(_,S))}})),A.push(e.subscribe(b));let O=e.state().currentStepId;return u.add(O),T(O,e.state().responseId),b(),()=>A.forEach(S=>S())};var mr=["email","emailAddress","workEmailAddress"],fr=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,qe=({engine:e,validator:n})=>{let t=new Set,r=new Map,o,a=!1,i,s=!1,d=()=>{let y=[];for(let m of Object.values(e.state().answers))for(let h of Object.values(m))for(let v of mr){let g=h[v];typeof g=="string"&&fr.test(g.trim())&&y.push(g.trim())}return y},l=()=>{let y=new Set(d()),m=[...r.values()].filter(g=>y.has(g.email));if(m.length===0)return;let h=JSON.stringify(m.map(g=>[g.email,g.isValid,g.failed===!0]));if(h===i)return;i=h;let v=m.find(g=>g.status&&g.reason);e.mergeMeta({isEmailValid:m.some(g=>g.isValid),emailValidation:v?{status:v.status,reason:v.reason,...v.blacklistEntryIds?.length&&{blacklistEntryIds:v.blacklistEntryIds}}:void 0,emailValidationFailed:m.some(g=>g.failed===!0)})},u=async()=>{let y=d().filter(h=>!t.has(h));if(y.length===0)return;y.forEach(h=>t.add(h));let m=await n.validateBatch(y);s||(m.forEach(h=>r.set(h.email,h)),l())},c=()=>{if(!d().some(y=>!t.has(y))){l();return}a=!0,clearTimeout(o),o=setTimeout(()=>{a=!1,u()},300)},p=()=>{a&&(a=!1,clearTimeout(o),u())},C=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{s=!0,clearTimeout(o),C.forEach(y=>y())}};var Qt=new Set(["surfaceTagStatus","isEmailValid","emailValidation","emailValidationFailed"]),gr=new Set(["CalendlyScreen","DynamicScheduler","FileUploader"]),zt={init:async({environmentId:e,formId:n,steps:t,settings:r={},apiBaseUrl:o,container:a,expectedQuestionIds:i,resolveNextStep:s,urlDataStateId:d,source:l,journey:u=!1,emailValidation:c=!1,preview:p=!1,previewToken:C,debug:y=!1,resume:m,meta:h})=>{let v=ve({apiBaseUrl:o}),g;if(!t){let M=await de(v,n,{preview:p,previewToken:C});if(!M.ok||!M.data.data){let R=(o??z).replace(/\/$/,""),D=M.ok?"empty response":M.error.kind==="http"?`HTTP ${M.error.status}`:"network error";throw new Error(`SurfaceForms.init: could not fetch runtime config for form "${n}" (${D} from ${R}/api/v1/public/forms/${n}/runtime-config). If this environment is not served from ${z}, pass apiBaseUrl — the get_sdk_binding_map MCP tool returns the correct value.`)}g=M.data.data,t=ue(g.config),i=i??Q(g.config).filter(R=>!gr.has(R.componentType??"")).map(R=>R.questionId);let E=g.settings??{};r={trackPartialResponses:E.trackPartialResponses,trackCookies:E.trackCookie,gtmId:E.gtmId,gaMeasurementId:E.gaMeasurementId,metaPixelId:E.metaPixelId,hubspotTracking:E.hubspotTracking,adsConversions:E.adsConversions,...r}}let L=r.trackCookies??!1,P;if(m&&!p){let M=await _t(v,m);M.ok?P={responseId:m.responseId,answers:Object.fromEntries(M.data.answers.map(E=>[E.questionId,E.response]))}:console.warn(`Surface SDK: resume fetch for response "${m.responseId}" failed — starting a fresh session.`)}let k=await ne({transport:v,environmentId:e,formId:n,source:l,preview:p}),T=ke({transport:v,preview:p}),U=Ae({transport:v,preview:p}),b=Ee({formId:n,environmentId:e,steps:t,transport:v,resolveNextStep:s,trackPartialResponses:r.trackPartialResponses??!0,trackCookies:L,externalStates:d?{[d]:Te({trackCookies:L})}:{},meta:{...h,surfaceTagStatus:"sdk"},identity:()=>({fingerprint:k?.fingerprint,leadSessionId:k?.leadSessionId??void 0,leadId:k?.leadId??void 0}),pushEvents:T,formJourney:U,preview:p,resume:P}),A=[],x=b;if(y){let M=new Map((g?Q(g.config):[]).map(R=>[R.questionId,R])),E=(R,D)=>(...J)=>(console.debug(`Surface SDK [debug]: ${R} requested from step ${b.state().currentStepId}`),D(...J));x={...b,setAnswer:(R,D)=>{let J=b.state().currentStepId;b.setAnswer(R,D);let Ne=b.state().answers[J]?.[R]??D;$t({questions:M,questionId:R,merged:Ne})},next:E("next",b.next),back:E("back",b.back),goToStep:E("goToStep",b.goToStep),submit:E("submit",b.submit),disqualify:E("disqualify",b.disqualify)};for(let R of["viewed","started","stepChanged","stepCompleted","completed","disqualified","saved","error","scheduler"])A.push(b.on(R,D=>console.debug(`Surface SDK [debug]: ${R}`,D)))}let O=!1;A.push(b.on("started",()=>{O=!0})),A.push(Re(T,()=>({started:O,formId:n,stepId:b.state().currentStepId,sessionId:k?.leadSessionId??void 0}))),a&&A.push(ie({engine:x,root:a,expectedQuestionIds:i}));let S=!!r.gtmId||!!r.gaMeasurementId||!!r.metaPixelId||!!r.hubspotTracking?.trackingId||(r.adsConversions?.length??0)>0;S&&!p&&typeof window<"u"&&A.push(Jt({engine:b,formId:n,settings:r}));let w=g?ce(g.config):[],_=g!=null&&w.length>0&&me(g.settings);_&&!p?A.push(Oe({engine:b,transport:v,formId:n,sources:w})):y&&g&&!_&&dt(g.config)&&console.warn("Surface SDK: the record declares an enrichmentSourceField, but this environment has no enabled enrichment provider — no enrichment will run (capabilities.enrichment is false).");let q=ye({transport:v,environmentId:e,preview:p});c&&!p&&A.push(qe({engine:b,validator:q}));let F;return u&&!p&&(F=Me({transport:v,environmentId:e}),F.trackPageView(),A.push(F.observeRouteChanges())),{setAnswer:x.setAnswer,setExternalState:b.setExternalState,next:x.next,back:x.back,goToStep:x.goToStep,submit:x.submit,disqualify:x.disqualify,savePartial:b.savePartial,notifyScheduler:b.notifyScheduler,flush:b.flush,markViewed:b.markViewed,mergeMeta:M=>{let E=Object.entries(M),R=E.filter(([D])=>Qt.has(D));R.length>0&&console.warn(`Surface SDK: mergeMeta dropped reserved key(s) ${R.map(([D])=>D).join(", ")} — these are SDK-owned response markers.`),b.mergeMeta(Object.fromEntries(E.filter(([D])=>!Qt.has(D))))},capabilities:{enrichment:_,emailValidation:c,tracking:S},on:b.on,state:b.state,subscribe:b.subscribe,identify:async()=>{let M=await ne({transport:v,environmentId:e,formId:n,source:l,preview:p});return M&&(k=M),M},validateEmail:q.validate,runtimeConfig:g,transport:v,identity:()=>({fingerprint:k?.fingerprint,leadSessionId:k?.leadSessionId??void 0,leadId:k?.leadId??void 0}),preview:p,destroy:()=>A.forEach(M=>M())}}};return sn(yr)})();
@@ -1,6 +1,7 @@
1
1
  import type { Transport } from "../../core/client/transport";
2
2
  import type { ProviderContext } from "./types";
3
3
 
4
+
4
5
  export declare const withProtocol: (url: string) => string;
5
6
 
6
7
  export declare const buildEmbedUrl: (dataUrl: string, params: Record<string, string | undefined>) => string | null;
@@ -59,10 +59,12 @@ export type FormEngine = {
59
59
  } & Record<string, unknown>) => void;
60
60
 
61
61
  mergeMeta: (partial: Record<string, unknown>) => void;
62
+
62
63
  next: () => Promise<void>;
63
64
  back: () => void;
64
65
 
65
66
  goToStep: (stepId: string) => Promise<void>;
67
+
66
68
  submit: () => Promise<void>;
67
69
 
68
70
  disqualify: () => Promise<void>;
package/docs/api.md CHANGED
@@ -64,7 +64,7 @@ Full method semantics, event payloads, and delivery guarantees:
64
64
  | Member | Signature | Semantics |
65
65
  | ------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
66
66
  | `setAnswer` | `(questionId, state) => void` | Merges a partial state into the question's answer. Use the typed answer states (§6) — wrong shapes are the classic production 400. |
67
- | `next` / `back` | `() => Promise<void>` / `() => void` | Linear advance (saves progress; the step being LEFT is stamped on the write) / rewind (never writes). |
67
+ | `next` / `back` | `() => Promise<void>` / `() => void` | Linear advance switches the step immediately and resolves on the step change; the partial save (stamped with the step being LEFT) lands behind it / rewind (never writes). |
68
68
  | `goToStep` | `(stepId) => Promise<void>` | Customer-owned routing: forward jumps save like `next()`; jumps to a visited step rewind like `back()`. Rejects unknown ids. |
69
69
  | `submit` | `() => Promise<void>` | Finishes the form. **The terminal write is awaited** — when this resolves (and `saved` fires with `finished: true`), the server has the finished response; a delivery failure emits `error` instead. Then reveals the record's `thank_you` step. |
70
70
  | `disqualify` | `() => Promise<void>` | Finishes as disqualified (`invalidResponse: true`); reveals the `disqualified` ending. |
@@ -186,9 +186,12 @@ Semantics that matter:
186
186
 
187
187
  - Partial saves happen on forward movement only, stamped with the step being
188
188
  left; the first forward move creates the response, later moves update it.
189
- - Every write-initiating call runs through one queue double-clicks advance
190
- once, a `submit()` during an in-flight `next()` queues behind it, nothing
191
- writes after the finishing submit.
189
+ They run BEHIND the step change `next()`/`goToStep()` never wait on the
190
+ network.
191
+ - Every write runs through one queue (the first move's create settles the
192
+ responseId before any update needs it). Finishing is the only navigation
193
+ that waits; a re-entrant `submit()`/`next()`/`disqualify()` while a finish
194
+ is pending joins it, and nothing writes after the finishing submit.
192
195
  - The FINISHING write is an awaited `fetch(keepalive)`; partial updates are
193
196
  beacons. A failed terminal write emits `error` (with a best-effort beacon
194
197
  fallback) and never fires `saved`.
@@ -315,7 +318,8 @@ dependency; the main entry is React-free.
315
318
  throwing; event-handler exceptions are isolated.
316
319
  - **Preview writes nothing**: identify, responses, events, journey, enrichment,
317
320
  tracking, and email validation (synthetic verdicts) are all blocked.
318
- - **Delivery**: creates + the finishing update are awaited; mid-form updates
321
+ - **Delivery**: the finishing update is awaited; the create and mid-form
322
+ updates run behind the step change (navigation never waits on the network)
319
323
  and analytics are beacon-first fire-and-forget. `flush()` before
320
324
  programmatic teardown.
321
325
  - Send `X-Surface-Sdk-Version` on everything — visible server-side for rate
@@ -85,12 +85,15 @@ resumeToken, finished}`. The snapshot is cached until the next mutation, so it i
85
85
 
86
86
  ### Write serialization + delivery
87
87
 
88
- - One queue serializes every write-initiating call: a double-clicked `next()` joins the pending
89
- advance (advances once); `submit()` during an in-flight `next()` queues behind it and then
90
- finishes (submit intent never dropped); queued ops re-check `finished` when they run, so
91
- nothing writes after the finishing submit.
92
- - First forward write CREATES the response (`POST /api/v1/responses/`, awaited, credentialed);
93
- later writes UPDATE it. Every write resends the FULL answer set + external states.
88
+ - Navigation is synchronous: `next()`/`goToStep()` switch the step and resolve immediately; the
89
+ partial save is queued behind the transition. Finishing is the only navigation that waits, and
90
+ a re-entrant `submit()`/`next()`/`disqualify()` while a finish is pending joins it (a
91
+ double-clicked submit finishes once; submit intent never dropped).
92
+ - One queue serializes every write; queued writes re-check `finished` when they run, so nothing
93
+ writes after the finishing submit.
94
+ - First forward write CREATES the response (`POST /api/v1/responses/`, credentialed, settled
95
+ before any later write runs); later writes UPDATE it. Every write resends the FULL answer set +
96
+ external states.
94
97
  - A failed create: `error` event; `response_submission_error` pushEvent only for network-kind
95
98
  failures (the server logs HTTP-level ones itself); the responseId stays null (the next write
96
99
  retries the create).
package/llms.txt CHANGED
@@ -136,9 +136,18 @@ Markers, most specific wins, ONE per element:
136
136
 
137
137
  A `<form>` container's native submit also finishes. Conditional branching =
138
138
  your JS choosing which goto button to show, or calling the API below. Driving
139
- navigation/submit entirely from JS (async gates like email validation)?
140
- Put `data-surface-nav="js"` on any element — it tells `validate_form_html`
141
- the page submits in code, silencing its advance/submit warnings.
139
+ navigation/submit entirely from JS (custom branching, an owner-requested
140
+ gate)? Put `data-surface-nav="js"` on any element — it tells
141
+ `validate_form_html` the page submits in code, silencing its advance/submit
142
+ warnings.
143
+
144
+ Timing: `next()`/`goToStep()` switch the step IMMEDIATELY and resolve on the
145
+ step change — the partial save runs behind it (`saved`/`error` report it). A
146
+ visitor never waits on a partial save, so don't disable the CTA for one, and
147
+ don't put async work of your own in front of the step change unless the form
148
+ owner asked for a gate (see Email validation). `submit()`/`disqualify()` are
149
+ the one wait: they await the finishing write before the ending step shows —
150
+ disable that button while the promise is pending.
142
151
 
143
152
  Finishing reveals the record's matching ending step: after the terminal write,
144
153
  `submit()` moves to the step with `endStepKind: "thank_you"` and `disqualify()`
@@ -166,10 +175,12 @@ answer (booking prefill, a summary screen) indexes by that step's id:
166
175
 
167
176
  Delivery guarantees: the FINISHING write is awaited — when `submit()` resolves
168
177
  (and `saved` fires with `finished: true`) the server has the finished response;
169
- a failure emits `error` instead of lying. Mid-form partial saves are
170
- fire-and-forget beacons reconciled server-side. `await form.flush()` before
171
- tearing the page down programmatically (SPA unmount, test harness closing the
172
- browser) so no queued write is cut off.
178
+ a failure emits `error` instead of lying. Partial saves never block: `next()`
179
+ resolves on the step change and the write lands behind it — the first one
180
+ creates the response and settles `responseId` (later writes queue behind it),
181
+ the rest are fire-and-forget beacons reconciled server-side. `await
182
+ form.flush()` before tearing the page down programmatically (SPA unmount, test
183
+ harness closing the browser) so no queued write is cut off.
173
184
 
174
185
  `mergeMeta(partial)` records caller-computed values (a qualification score, an
175
186
  experiment bucket) onto the response `meta` — they ride the next save, or amend
@@ -210,31 +221,38 @@ wire shapes; during development, `debug: true` audits them at runtime too.
210
221
 
211
222
  ## Email validation
212
223
 
224
+ Two mechanisms share one per-address verdict cache (an address is billed once
225
+ no matter which path asks). Automatic mode — `emailValidation: true` on
226
+ `init` — validates email answers as they're captured (debounced) and writes
227
+ the same `meta` verdict keys native forms write (`isEmailValid`,
228
+ `emailValidation`, `emailValidationFailed`) for dashboards and workflows.
213
229
  `form.validateEmail(email)` resolves the server-side deliverability verdict
214
230
  (provider waterfall + the environment's spam blacklist; keys stay
215
- server-side): `{ isValid, status, reason, failed? }`. Verdicts are cached per
216
- address for the form's lifetime and FAIL OPEN: when no validator can run, the
217
- result is `{ isValid: true, failed: true, status: "unknown" }`never lock a
218
- visitor out on a vendor outage. Two consequences to design for: (1) check
219
- `failed` if you want to soft-warn instead of hard-block; (2) the same address
220
- can be accepted today (fail-open) and return a definitive `invalid` tomorrow —
221
- that's the waterfall resolving, not a bug; don't write tests that assume a
222
- fixed verdict for a fresh domain. Use it to drive your own navigation:
231
+ server-side) on demand: `{ isValid, status, reason, failed? }`.
232
+
233
+ **What happens on an invalid address is the form owner's decision ask
234
+ before authoring, never assume.** The default is ANNOTATE ONLY: pass
235
+ `emailValidation: true`, let the visitor continue, and the response carries
236
+ `isEmailValid: false` for the owner's workflows and lead scoring to act on.
237
+ Automatic mode never blocks navigation or submission, and the visitor never
238
+ waits on a verdict. Only when the owner explicitly wants a gate do you call
239
+ `validateEmail` in your own navigation:
223
240
 
224
241
  ```js
242
+ // Owner chose BLOCK: keep the visitor on the step with a message.
225
243
  const { isValid, reason, failed } = await form.validateEmail(emailInput.value);
226
244
  if (isValid) form.next();
227
245
  else showError(`Email rejected: ${reason}`);
246
+ // Owner chose DISQUALIFY: form.disqualify() instead of showError.
228
247
  ```
229
248
 
230
- Pass `emailValidation: true` to `init` for automatic mode: email answers are
231
- validated as they're captured (debounced; per-address, so nothing is billed
232
- twice) and the response carries the same `meta` verdict keys native forms
233
- write (`isEmailValid`, `emailValidation`, `emailValidationFailed`) for
234
- dashboards and workflows. Automatic mode ANNOTATES ONLYit never blocks
235
- navigation or submission (an invalid address still submits, with
236
- `isEmailValid: false` on the response); to actually gate, call
237
- `validateEmail` in your own navigation as above. Preview resolves synthetic valid verdicts with no
249
+ Verdicts FAIL OPEN: when no validator can run, the result is
250
+ `{ isValid: true, failed: true, status: "unknown" }` — never lock a visitor
251
+ out on a vendor outage. Two consequences to design for: (1) check `failed` if
252
+ you want to soft-warn instead of hard-block; (2) the same address can be
253
+ accepted today (fail-open) and return a definitive `invalid` tomorrowthat's
254
+ the waterfall resolving, not a bug; don't write tests that assume a fixed
255
+ verdict for a fresh domain. Preview resolves synthetic valid verdicts with no
238
256
  network. Offline callers wire it themselves: `createEmailValidator({
239
257
  transport, environmentId })` and optionally `attachEmailValidation({ engine,
240
258
  validator })`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parag.more.withsurface.com/forms-sdk",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Thin-client Surface Forms SDK: headless core over the public runtime endpoints (field-test build).",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,