@sprig-technologies/sprig-browser 2.31.3 → 2.31.5

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.
package/dist/replay.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var Ee=Object.defineProperty;var Re=(e,t,n)=>t in e?Ee(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var A=(e,t,n)=>(Re(e,typeof t!="symbol"?t+"":t,n),n);const o=require("./metricsReporter-D-24kpOB.cjs");var k=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(k||{});class Pe{constructor(t){A(this,"awaitingResolvers",[]);A(this,"activeCount",0);this.capacity=t}async acquire(){if(this.activeCount<this.capacity){this.activeCount++;return}return new Promise(t=>{this.awaitingResolvers.push(t)})}release(){const t=this.awaitingResolvers.shift();t&&this.activeCount<=this.capacity?t():this.activeCount--}async execute(t){try{return await this.acquire(),await t()}finally{this.release()}}setLimit(t){this.capacity=t}}const se=new Pe(2),xe=e=>se.setLimit(e),Be=async e=>se.execute(async()=>{var r;o.info(`Beginning upload of chunk ${e.chunkIndex} for survey: ${e.surveyId}`);const t=await o.sprigFetch(e.uploadUrl,{body:e.data,method:"PUT"});o.info(`Completed upload of chunk ${e.chunkIndex} for survey: ${e.surveyId}`);const n=(r=t.headers)==null?void 0:r.get("ETag");if(!n)throw new Error(`Upload response did not include etag for upload ${e.uploadId}, part ${e.chunkIndex}`);return n}),oe=async({apiUrl:e,surveyId:t,uploadId:n,etags:r,headers:a,responseGroupUuid:s,replayDuration:i,eventDigest:c},l=!1)=>{var p;if(!l&&!n&&!r){o.info(`Cannot mark upload complete: isMobile: ${l} / uploadId: ${n} / etags: ${r}`);return}o.info(`Marking upload complete for survey: ${t}`);const d=await o.sprigFetch(`${e}/sdk/1/completeSessionReplay`,{method:"POST",body:JSON.stringify({etags:r,uploadId:n,responseGroupUuid:s,surveyId:t,replayDuration:i,eventDigest:c,userAgent:(p=window==null?void 0:window.navigator)==null?void 0:p.userAgent}),headers:a,shouldRetryRequest:!0});return o.info(`Done marking upload complete for survey: ${t}`),d},N=(e,t)=>t.some(n=>e instanceof n);let q,Q;function Te(){return q||(q=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Ae(){return Q||(Q=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const _=new WeakMap,$=new WeakMap,B=new WeakMap;function $e(e){const t=new Promise((n,r)=>{const a=()=>{n(D(e.result))},s=()=>{r(e.error)};e.onsuccess=a,e.onerror=s});return B.set(t,e),t}function Ue(e){if(_.has(e))return;const t=new Promise((n,r)=>{const a=()=>{n()},s=()=>{r(e.error||new DOMException("AbortError","AbortError"))};e.oncomplete=a,e.onerror=s,e.onabort=s});_.set(e,t)}let L={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return _.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return D(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function ie(e){L=e(L)}function Ne(e){return Ae().includes(e)?function(...t){return e.apply(M(this),t),D(this.request)}:function(...t){return D(e.apply(M(this),t))}}function _e(e){return typeof e=="function"?Ne(e):(e instanceof IDBTransaction&&Ue(e),N(e,Te())?new Proxy(e,L):e)}function D(e){if(e instanceof IDBRequest)return $e(e);if($.has(e))return $.get(e);const t=_e(e);return t!==e&&($.set(e,t),B.set(t,e)),t}const M=e=>B.get(e);function Le(e,t,{blocked:n,upgrade:r,blocking:a,terminated:s}={}){const i=indexedDB.open(e,t),c=D(i);return r&&(i.onupgradeneeded=l=>{r(D(i.result),l.oldVersion,l.newVersion,D(i.transaction),l)}),n&&(i.onblocked=l=>n(l.oldVersion,l.newVersion,l)),c.then(l=>{s&&(l.onclose=()=>s()),a&&(l.onversionchange=d=>a(d.oldVersion,d.newVersion,d))}).catch(()=>{}),c}function G(e,{blocked:t}={}){const n=indexedDB.deleteDatabase(e);return t&&(n.onblocked=r=>t(r.oldVersion,r)),D(n).then(()=>{})}const Me=["get","getKey","getAll","getAllKeys","count"],Oe=["put","add","delete","clear"],U=new Map;function X(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(U.get(t))return U.get(t);const n=t.replace(/FromIndex$/,""),r=t!==n,a=Oe.includes(n);if(!(n in(r?IDBIndex:IDBObjectStore).prototype)||!(a||Me.includes(n)))return;const s=async function(i,...c){const l=this.transaction(i,a?"readwrite":"readonly");let d=l.store;return r&&(d=d.index(c.shift())),(await Promise.all([d[n](...c),a&&l.done]))[0]};return U.set(t,s),s}ie(e=>({...e,get:(t,n,r)=>X(t,n)||e.get(t,n,r),has:(t,n)=>!!X(t,n)||e.has(t,n)}));const He=["continue","continuePrimaryKey","advance"],Y={},O=new WeakMap,ce=new WeakMap,Fe={get(e,t){if(!He.includes(t))return e[t];let n=Y[t];return n||(n=Y[t]=function(...r){O.set(this,ce.get(this)[t](...r))}),n}};async function*je(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;t=t;const n=new Proxy(t,Fe);for(ce.set(n,t),B.set(n,M(t));t;)yield n,t=await(O.get(n)||t.continue()),O.delete(n)}function Z(e,t){return t===Symbol.asyncIterator&&N(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&N(e,[IDBIndex,IDBObjectStore])}ie(e=>({...e,get(t,n,r){return Z(t,n)?je:e.get(t,n,r)},has(t,n){return Z(t,n)||e.has(t,n)}}));const Ke=e=>{if(e instanceof Attr)return null;let t=1;for(let n=e.previousSibling;n;n=n.previousSibling)n.nodeName===e.nodeName&&++t;return t},le=e=>{if(e===null)return"";const t=[];if(e instanceof Document)return"/";for(let n=e;n&&!(n instanceof Document)&&n!==null;n=n instanceof Attr?n.ownerElement:n.parentElement){const r=t[t.length]={name:void 0,position:null};switch(n.nodeType){case Node.TEXT_NODE:r.name="text()";break;case Node.ATTRIBUTE_NODE:r.name="@"+n.nodeName;break;case Node.PROCESSING_INSTRUCTION_NODE:r.name="processing-instruction()";break;case Node.COMMENT_NODE:r.name="comment()";break;case Node.ELEMENT_NODE:r.name=n.nodeName;break}r.position=Ke(n)}return"/"+t.reverse().map(n=>n.position!==null?`/${n.name}[${n.position}]`:`/${n.name}`).join("")},S={capture:!0,passive:!0},Ve=["a","button","input","option","li","link"],Ge=["Escape","Enter","Backspace","F5","Tab"];let P=!1;const We=["label","type","role","title","placeholder","errormessage","valuetext","href"],ee="aria-",ze=e=>{if(!e.tagName)return"No tagName";const t=e.getAttribute("type");return t?`${t} ${e.tagName.toLowerCase()}`:e.tagName.toLowerCase()},te=e=>{var r;if(((r=e.tagName)==null?void 0:r.toLowerCase())==="html")return{element:"html"};const t=e.textContent,n=t?{text:t}:{};n.element=ze(e);for(const a of e.attributes){let s=a.name;const i=a.value;s.startsWith(ee)&&(s=s.substring(ee.length)),We.includes(s)&&(n[s]=i)}return n},Je=e=>{var a;if(!e)return{};const n={...te(e)},r=e.parentElement;if(r&&Ve.includes((a=r.tagName)==null?void 0:a.toLowerCase())){const s=te(r);Object.assign(n,s)}return n},de=(e,t)=>{var n;lt({x:t.x,y:t.y,type:e,elementAttributes:Je(t.target),windowHeight:window.innerHeight,windowWidth:window.innerWidth,...t.target instanceof HTMLElement?{rect:(n=t.target)==null?void 0:n.getBoundingClientRect(),xPath:le(t.target)}:{}})},qe=e=>t=>de(e,t),ue=e=>{Ge.includes(e.key)&&gt({key:e.key})},Qe=()=>{window.performance.getEntriesByType("navigation").map(t=>t.type).includes("reload")&&mt({url:window.location.href,currentPageTitle:document.title})},Xe=()=>{window.performance.getEntriesByType("navigation").map(t=>t.type).includes("back_forward")&&ft({curUrl:window.location.href,fromUrl:document.referrer,currentPageTitle:document.title})},Ye=(e,t)=>{let n;return r=>{clearTimeout(n),n=window.setTimeout(()=>e(r),t)}},Ze=e=>{if(!(e.target instanceof HTMLElement||e.target instanceof Document))return;let t=e.target;"scrollTop"in t||(t=t.documentElement),wt({xPath:le(t),x:t.scrollLeft,y:t.scrollTop,elementAttributes:{targetScrollWidth:t.scrollWidth,targetClientWidth:t.clientWidth,targetScrollHeight:t.scrollHeight,targetClientHeight:t.clientHeight}})},pe=Ye(Ze,750),me=qe("left_click"),fe=e=>{e.button===2&&de("right_click",e)},et=()=>{P||(window.addEventListener("click",me,S),window.addEventListener("mousedown",fe,S),window.addEventListener("keydown",ue,S),window.addEventListener("scroll",pe,S),P=!0,Qe(),Xe())},tt=()=>{P&&(window.removeEventListener("click",me,S),window.removeEventListener("mousedown",fe,S),window.removeEventListener("keydown",ue,S),window.removeEventListener("scroll",pe,S),P=!1)},nt=3e4,m={isRecording:!1,scrollEventUuids:{},stopRecording:()=>{}},rt=.5,at=async()=>{var e;if(!window.indexedDB||!window.IDBKeyRange)return!0;if((e=window.navigator.storage)!=null&&e.estimate)try{const{quota:t=0,usage:n=0}=await window.navigator.storage.estimate(),r=(t-n)/1024**3;return o.warn(`Storage: ${r}GB`),r<rt}catch{return!0}return!1},st=()=>{const e=o.sessionStorageHelper.getItem("sprig.sessionId");if(e)return o.info(`Found saved session id: ${e}`),o.sessionStorageHelper.removeItem("sprig.sessionId"),e;const t=o.v4();return o.info(`Generating new uuid: ${t}`),t},w=st(),H=()=>{o.sessionStorageHelper.setItem("sprig.disableReplayRecording","disabled")},b=()=>!!o.sessionStorageHelper.getItem("sprig.disableReplayRecording");window.addEventListener("beforeunload",()=>{o.info(`Before page unload saving session id: ${w}`),o.sessionStorageHelper.setItem("sprig.sessionId",w)});const ot=()=>b()?o.info("ReolayDisabledPendingHeatmap"):h(async()=>{const e=(await u.getPendingCaptures({isHeatmap:!0})).map(n=>({eventId:n.captureParams.eventId,uuid:n.uuid})),t=[];e.forEach(({eventId:n,uuid:r})=>{o.checkUrlStillMatching(n)||t.push(r)}),t.length&&await u.markPendingHeatmapsReady(t)},"Error marking pending heatmaps ready"),it=e=>{Date.now()-e>=nt&&h(()=>u.markPendingHeatmapsReady(),"Error in heatmap inactivity")},W=e=>e&&e.trim().substring(0,500).replace(/\s\s+/g," ").replace(/\r?\n|\r/g," ").substring(0,250),I=(e,t)=>{var n,r;if(m.isRecording)try{(r=(n=window.rrwebRecord)==null?void 0:n.addCustomEvent)==null||r.call(n,e,t)}catch(a){T("Error recording custom event",a)}},ct=e=>{e.description&&(e.description=W(e.description)),I("Sprig_PageView",e)},lt=e=>{var t;(t=e==null?void 0:e.elementAttributes)!=null&&t.text&&(e.elementAttributes.text=W(e.elementAttributes.text)),I("Sprig_Click",e)},dt=e=>{I("Sprig_TrackEvent",e)},ut=e=>{I("Sprig_ShowSurvey",e)},pt=e=>{I("Sprig_SubmitSurvey",e)},mt=e=>{I("Sprig_Refresh",e)},ft=e=>{e.currentPageTitle&&(e.currentPageTitle=W(e.currentPageTitle)),I("Sprig_BackForward",e)},gt=e=>{I("Sprig_Keystroke",e)},wt=async e=>{const{x:t,xPath:n,y:r}=e,a=m.scrollEventUuids[n];if(a)return h(async()=>{var c,l,d,p;const s=await u.openDB(),i=await s.get("events",a);if(i!=null&&i.event){const f=JSON.parse(i.event),y=t>((l=(c=f.data)==null?void 0:c.payload)==null?void 0:l.x),g=r>((p=(d=f.data)==null?void 0:d.payload)==null?void 0:p.y);if(!(y||g))return null;y&&(f.data.payload.x=t),g&&(f.data.payload.y=r),f.data.payload.elementAttributes=e.elementAttributes,i.event=JSON.stringify(f),await s.put("events",i)}else I("Sprig_Scroll",e)},"Error updating scroll event");I("Sprig_Scroll",e)},yt=()=>m.isRecording,ge=()=>{m.stopRecording&&(m.stopRecording(),m.stopRecording=void 0),m.isRecording=!1,["cleanupInterval","inactivityInterval","pendingCheckInterval"].forEach(e=>{m[e]&&(clearInterval(m[e]),m[e]=void 0)}),tt()},ht=["did not allow mutations","called in an invalid security context"],It=e=>{if(!e)return!0;for(const t of ht)if(e.toLowerCase().includes(t))return!1;return!0},vt=(e,t,{reportError:n=!0,extraInfo:r})=>{b()||t instanceof Error&&(H(),It(t==null?void 0:t.message)&&(n&&window.UserLeap.reportError(e,t,r),u.clearAll()))},bt=async(e,t,{reportError:n}={reportError:!0})=>{let r={};try{const{quota:a=0,usage:s=0}=await window.navigator.storage.estimate();r={availableSpaceInMB:(a-s)/2**20,quota:a,usage:s}}catch{r.availableSpaceInMB=null}vt(e,t,{reportError:n,extraInfo:r})},T=(e,t,{reportError:n}={reportError:!0})=>(ge(),o.error(`${e} - ${t.message} - ${t.name}`),bt(e,t,{reportError:n})),h=async(e,t)=>{try{await e()}catch(n){T(t,n)}},St=()=>{m.isRecording&&h(()=>{var e,t;return(t=(e=window.rrwebRecord)==null?void 0:e.takeFullSnapshot)==null?void 0:t.call(e,!0)},"Error recording full snapshot")},Dt=async({surveyId:e,responseGroupUuid:t,eventDigest:n,headers:r})=>{if(!e||!t)return!1;const a=window.UserLeap._API_URL,s=await oe({surveyId:e,responseGroupUuid:t,eventDigest:n,apiUrl:a,headers:r},!0);return!(s!=null&&s.error)},ne=30,Ct=1;G("replayStorage").catch(console.error);G("sprig.replay").catch(console.error);class kt{openDB(){return Le("sprigReplay",Ct,{upgrade:(t,n,r)=>{if(r===0&&o.sessionStorageHelper.setItem("sprig.pendingCount","0"),!t.objectStoreNames.contains("events")){const a=t.createObjectStore("events",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+timestamp]",["sessionId","timestamp"])}if(!t.objectStoreNames.contains("chunkUploads")){const a=t.createObjectStore("chunkUploads",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+status]",["sessionId","status"]),a.createIndex("[uploadId+status]",["uploadId","status"]),a.createIndex("[sessionId+status+uploadId]",["sessionId","status","uploadId"])}if(!t.objectStoreNames.contains("pendingCaptures")){const a=t.createObjectStore("pendingCaptures",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+targetTimestamp]",["sessionId","targetTimestamp"])}}})}deleteDB(){return G("sprigReplay").catch(console.error)}async bulkAdd(t,n){const r=(await this.openDB()).transaction(t,"readwrite");return Promise.all([...n.map(a=>r.store.add(a)),r.done])}async clearAll(){const t=(await this.openDB()).transaction(["events","chunkUploads","pendingCaptures"],"readwrite");return Promise.all([t.objectStore("events").clear(),t.objectStore("chunkUploads").clear(),t.objectStore("pendingCaptures").clear()])}async deleteBySessionId(t,n){const r=IDBKeyRange.only(n),a=(await this.openDB()).transaction(t,"readwrite");let i=await a.store.index("sessionId").openCursor(r);for(;i;)i.delete(),i=await i.continue();await a.done}async updatePartial(t,n,r){const s=(await this.openDB()).transaction(t,"readwrite"),i=await s.store.get(n);i&&await s.store.put({...i,...r}),await s.done}async deleteRowsBefore(t,n,r=()=>!0){const a=IDBKeyRange.upperBound(n,!0),s=(await this.openDB()).transaction(t,"readwrite");let c=await s.store.index("timestamp").openCursor(a);for(;c;)r(c.value)&&c.delete(),c=await c.continue();await s.done}async getEventsBetween(t,n=Date.now()){if(t>=n)return Promise.resolve([]);const r=IDBKeyRange.bound([w,t],[w,n],!1,!0);return(await this.openDB()).getAllFromIndex("events","[sessionId+timestamp]",r)}async updateEventsExpiredAt(t,n,r=ne){const a=new Date,s=a.setMinutes(a.getMinutes()+(r??ne)),i=(await this.openDB()).transaction("events","readwrite"),c=i.store.index("[sessionId+timestamp]"),l=IDBKeyRange.bound([w,t],[w,n],!1,!0);let d=await c.openCursor(l);for(;d;)d.update({...d.value,expiredAt:s}),d=await d.continue();await i.done}async deleteChunkUploads(t,n){const r=IDBKeyRange.only([n,t]),a=(await this.openDB()).transaction("chunkUploads","readwrite");let i=await a.store.index("[uploadId+status]").openCursor(r);for(;i;)i.delete(),i=await i.continue();await a.done}async getChunkUploadsByStatus({sessionId:t,status:n,uploadId:r}){const s=(await this.openDB()).transaction("chunkUploads","readonly"),i=r?s.store.index("[uploadId+status]"):s.store.index("[sessionId+status]"),c=r?IDBKeyRange.only([r,n]):IDBKeyRange.only([t,n]);return i.getAll(c)}async getPendingCaptures(t={}){return(await(await this.openDB()).getAllFromIndex("pendingCaptures","sessionId",w)).filter(a=>!t.beforePresent||a.targetTimestamp<Date.now()).filter(a=>!t.isHeatmap||(a.captureParams.isHeatmap??!1))}async markPendingCaptureToCanUpload(t){const n=(await this.openDB()).transaction("pendingCaptures","readwrite");let a=await n.store.index("sessionId").openCursor(w);for(;a;){const s=a.value;s.captureParams.responseGroupId===t&&a.update({...s,canUpload:!0}),a=await a.continue()}await n.done}async markPendingHeatmapsReady(t){if(parseInt(o.sessionStorageHelper.getItem("sprig.pendingCount")??"0")===0)return null;const r=Date.now(),a=(await this.openDB()).transaction("pendingCaptures","readwrite");let i=await a.store.index("sessionId").openCursor(w);for(;i;){const c=i.value;c.captureParams.isHeatmap&&(!t||t.includes(c.uuid))&&i.update({...c,targetTimestamp:r,captureParams:{...c.captureParams,triggerTimestamp:r,replayParams:{...c.captureParams.replayParams,replayDurationSeconds:Math.floor((r-c.timestamp)/1e3)}}}),i=await i.continue()}await a.done}}const u=new kt,Et=async(e,t,n)=>new Promise((r,a)=>{const s=e.createElement("script");s.src=t,s.onload=r,s.onerror=a,n&&(s.nonce=n),e.head.appendChild(s)}),we=async(e,t)=>{const n=performance.now();let r;try{r=await e()}finally{const a=performance.now()-n;let s=o.PerformanceMetrics[t];s||(s=o.registerMetric(t)),s.report(a/1e3)}return r},ye=(e,t)=>{const n=performance.now();try{e()}finally{const r=performance.now()-n;let a=o.PerformanceMetrics[t];a||(a=o.registerMetric(t)),a.report(r/1e3)}};let F=5e3,R=6e4,j=0;const Rt=5,he=30,x=he+Rt;let C,K=!1,V=[];const Pt=async({viewDocument:e,maxReplayDurationSeconds:t,replayNonce:n,maxInflightRequests:r=2,replaySettings:a,teardownAfter:s=!1})=>{if(C=o.sessionStorageHelper.getItem("sprig.pendingCount"),!m.isRecording){if(s&&o.sessionStorageHelper.setItem("sprig.teardownAfterCapture","true"),b())return o.info("ReplayDisabled");if(await at())return o.error("IDBNotSupported"),H();try{await u.openDB()}catch(i){return o.error(`ReplayError-${i.message}-${i.name}`),i.name==="VersionError"&&u.deleteDB(),H()}if(!t)return o.info("MissingReplaySeconds");o.info("ReplayInit"),await h(async()=>{if(a!=null&&a.minDuration&&(F=a.minDuration),a!=null&&a.batchDuration&&(R=a.batchDuration),xe(r),_t(),At(t+x,30*60,t+x),$t(),!window.rrwebRecord){const d=window.UserLeap.replayLibraryURL??"https://cdn.sprig.com/dependencies/record-2.0.0-alpha.6.min.js";await Et(e,d,n)}const i=window.rrwebRecord;if(!i)return o.warn("RecordScriptFailed");let c=!0,l=0;m.stopRecording=i({checkoutEveryNms:he*1e3,sampling:{input:"last",scroll:250,media:800},emit:(d,p)=>{if(d.type===k.Custom&&(j=Date.now()),b())return;if(p&&d.type===k.Meta)l=performance.now();else if(p&&l&&d.type===k.FullSnapshot){const y=performance.now()-l;o.reportAndRegister("sdk_replay_snapshot_seconds",y/1e3)}const f=c||!!p&&d.type===k.Meta;c=!1,xt({uuid:o.v4(),event:JSON.stringify(d),isValidStart:f,timestamp:Date.now()})},...a}),m.isRecording=!!m.stopRecording,m.isRecording&&(o.eventEmitter.on("survey.complete",d=>{pt({id:d,userAgent:window.navigator.userAgent})}),et())},"Error initializing replay")}},xt=e=>{var t,n,r,a;if((t=e.event)!=null&&t.includes("Sprig_Scroll")){const s=(a=(r=(n=JSON.parse(e.event))==null?void 0:n.data)==null?void 0:r.payload)==null?void 0:a.xPath;if(!s)return;m.scrollEventUuids[s]=e.uuid}V.push(e),K||Tt()},Bt=async e=>{const t=e.map(n=>({...n,sessionId:n.sessionId??w}));if(t.length!==0)return h(()=>u.bulkAdd("events",t),"Error storing replay events")},Tt=()=>{K=!0,setTimeout(async()=>{if(b())return;const e=V;V=[],K=!1,ye(async()=>{await Bt(e)},"sdk_replay_add_event_batch_seconds")},500)},At=(e,t,n)=>{m.cleanupInterval=window.setInterval(()=>{const r=Date.now();b()||(o.debug(`CleanUp Secs - Events: ${e}, Chunks: ${t}, Captures: ${n}`),we(()=>h(async()=>{await Promise.all([u.deleteRowsBefore("events",r-e*1e3,a=>a.expiredAt===void 0||a.expiredAt<r-e*1e3),u.deleteRowsBefore("chunkUploads",r-t*1e3),u.deleteRowsBefore("pendingCaptures",r-n*1e3,a=>!a.canUpload)])},"Error deleting table rows"),"sdk_replay_cleanup_seconds"),o.info("Cleanup complete"))},3e4)},$t=()=>{m.pendingCheckInterval=window.setInterval(async()=>{h(async()=>{const e=parseInt(C??"0");if(e===0)return;const t=await u.getPendingCaptures({beforePresent:!0}),n=await u.openDB();await Promise.all(t.map(async r=>(await n.delete("pendingCaptures",r.uuid),be(r.captureParams,r.canUpload)))),C=(e-t.length).toString(),o.sessionStorageHelper.setItem("sprig.pendingCount",C)},"Error initiating pending captures")},5e3)},Ut=async(e,t,n,r,a)=>{const s=Math.min(e+a,n),i=`from: ${new Date(e).toLocaleTimeString()} to ${new Date(s).toLocaleTimeString()}`;o.info(`Getting event batch ${i}`);const c=await we(()=>u.getEventsBetween(e,s),"sdk_replay_get_events_between_seconds");if(!(c!=null&&c.length))return o.info(`No events found ${i}`),{validStartFound:r,events:[]};if(!r){o.info(`Searching for valid start in ${c.length} events ${i}`);let l=-1;if(c==null||c.forEach((p,f)=>{if(!p.isValidStart)return;const y=p.timestamp<=t;(l<0||y)&&(l=f)}),l<0)return o.info(`No valid start found in ${c.length} events ${i}`),{validStartFound:r,events:[]};const d=c[l].timestamp;return o.info(`Found valid start at: ${new Date(d).toLocaleTimeString()} in events ${i}`),{validStartFound:!0,events:c==null?void 0:c.slice(l)}}return{validStartFound:r,events:c}},Nt=(e,t,n)=>{const r=e.length,a=t*1024*1024,s=Math.ceil(r/n),i=Math.max(a,s);o.info(`Total file bytes: ${r} / target chunk size: ${i}`);const c=[];let l=0;for(;l<r;)c.push(e.slice(l,l+i)),l+=i;return c},Ie=e=>Promise.all(e.map(async t=>{const n=await Be(t);return await u.updatePartial("chunkUploads",t.uuid,{data:null,etag:n,status:"UploadComplete"}),t.uploadId})),ve=async e=>{o.info(`Marking upload complete if finished: ${e}`);const t=await u.getChunkUploadsByStatus({status:"UploadComplete",uploadId:e});if(!(t!=null&&t.length)){o.info(`No finished chunks found for upload: ${e}`);return}const n=t.reduce((s,i)=>(s.find(c=>c.chunkIndex===i.chunkIndex)||s.push(i),s),[]);n.sort((s,i)=>s.chunkIndex-i.chunkIndex);const r=n.map(s=>({ETag:s.etag,PartNumber:s.chunkIndex})).filter(s=>s.ETag!==null),a=n[0];await oe({apiUrl:a.apiUrl,surveyId:a.surveyId,uploadId:e,responseGroupUuid:a.responseGroupId,etags:r,headers:a.completeUploadHeaders,replayDuration:a.replayDuration}),o.info(`Cleaning up chunks for ${e}`),await u.deleteChunkUploads("UploadComplete",e),o.info(`Done cleaning up chunks for ${e}`)},_t=()=>{h(async()=>{const e=await u.getChunkUploadsByStatus({sessionId:w,status:"ReadyForUpload"});if(!(e!=null&&e.length))return;const t=await Ie(e);o.info(`Finished uploading unfinished chunks for ${t}`),t!=null&&t.length&&await Promise.all(t.map(n=>{if(n)return ve(n)}))},"Error uploading unfinished chunks")},Lt=async(e,t)=>{await Ie(t),o.info(`Done uploading chunks for uploads: ${e.join(",")}`),await Promise.all(e.map(n=>ve(n)))},Mt=e=>{let t=0;e.forEach(a=>{t+=a.length});const n=new Uint8Array(t);let r=0;return e.forEach(a=>{n.set(a,r),r+=a.length}),n},re=async(e,t,n)=>{const r=new TextEncoder;let a=null,s=null,i=null,c=!1,l=!1,[d,p]=[0,0];const f=e-x*1e3,y=[];let g=[];o.info(`Getting events between ${new Date(e).toLocaleTimeString()} and ${new Date(t).toLocaleTimeString()}`),o.info(`Using batch duration: ${R}ms`);for(let E=f;E<t;E+=R){if({validStartFound:l,events:g}=await Ut(E,e,t,l,R),!(g!=null&&g.length)){o.info("No events found");continue}d===0&&(d=g[0].timestamp),p=g[g.length-1].timestamp,o.info(`Last event time in batch: ${new Date(p).toLocaleTimeString()}`);const z=g.map(ke=>ke.event);z.push(`{"timestamp":${t}}`);const Ce=`${c?",":"["}${z}`,J=r.encode(Ce);n&&s===null&&(o.debug("Attempting compression"),i=new window.CompressionStream("gzip"),s=i.writable.getWriter()),ye(()=>{n&&s?s.write(J):y.push(J)},"sdk_replay_compression_seconds"),c=!0}if(p-d<F)return o.info(`Replay duration is shorter than minimum of ${F}ms / Start:${d} / End:${p}`),null;const v=r.encode("]");return o.debug("Writing final close brace"),s&&i?(s.write(v),s.close(),a=new Uint8Array(await new Response(i.readable).arrayBuffer())):(y.push(v),a=Mt(y)),o.info("Finished generating file data"),a},Ot=async(e,t)=>{const n=window.CompressionStream!==void 0;let r=null;const a=t??Date.now(),s=a-e;try{r=await re(s,a,n)}catch(i){i instanceof Error&&window.UserLeap.reportError("Error compressing replay",i),n&&h(async()=>{await re(s,a,!1)},"fileData fallback failed")}return r},ae=async e=>{const{surveyId:t,responseGroupId:n,visitorId:r,apiUrl:a,completeUploadHeaders:s,replayParams:i,triggerTimestamp:c}=e,l=await Ot(i.replayDurationSeconds*1e3,c);if(l!=null&&l.length)o.info(`Found file data for survey: ${t}`);else{o.info(`File data is empty for survey: ${t}`);return}const d=Nt(l,i.minimumChunkSizeMb,i.signedUrls.length);o.info(`Got ${d.length} chunks for survey: ${t}`);const p=await Promise.all(d.map(async(f,y)=>{const g=o.v4(),v={apiUrl:a,chunkIndex:y+1,completeUploadHeaders:s,etag:null,responseGroupId:n,status:"ReadyForUpload",surveyId:t,timestamp:c,totalChunks:d.length,data:f,uploadId:i.uploadId,uploadUrl:i.signedUrls[y].url,uuid:g,visitorId:r};return o.info(`Recording chunk upload: ${JSON.stringify({index:v.chunkIndex,surveyId:v.surveyId,uploadId:v.uploadId,size:f.length,id:g},null,2)}`),await(await u.openDB()).add("chunkUploads",{...v,sessionId:v.sessionId??w}),o.info(`Done creating chunk upload: ${g}`),v}));o.info(`All chunk records created. Beginning upload for survey: ${t}`),await Lt([i.uploadId],p)},be=async(e,t)=>{if(o.info(`Attempting replay capture: ${JSON.stringify({isStandalone:e.isStandalone,duration:e.replayParams.replayDurationSeconds,type:e.replayParams.replayDurationType,responseGroupId:e.responseGroupId,surveyId:e.surveyId,triggerTimestamp:e.triggerTimestamp,visitorId:e.visitorId},null,2)}`),b())return o.info(`Replay recording is disabled: ${e.surveyId}`);o.info(`Replay recording enabled: ${e.surveyId}`);const{isHeatmap:n,isStandalone:r,replayParams:a,triggerTimestamp:s,responseGroupId:i}=e,c=async()=>{setTimeout(()=>o.eventEmitter.removeListener(o.SprigEvent.QuestionAnswered,c),0),h(async()=>{a.replayDurationType==="before"?await ae(e):await u.markPendingCaptureToCanUpload(i)},"Error in schedule/capture callback")};h(async()=>{if(a.replayDurationType==="after"||a.replayDurationType==="beforeAndAfter"){!r&&!n&&(o.info("Attaching QuestionAnswered listener for non-standalone replay"),o.eventEmitter.on(o.SprigEvent.QuestionAnswered,c)),o.info(`Scheduling capture for replay of type: ${a.replayDurationType}`),await De(e);return}if(r||n||t)o.info(`Proceeding to capture replay for survey: ${e.surveyId} / standalone? ${r} / canUpload? ${t}`),await ae(e),n&&Ht();else{const d=x+a.replayDurationSeconds,p=s-d*1e3,f=s;o.info(`Setting expiry minutes to ${a.expirationTimeLimitMinutes} for events from ${new Date(p).toLocaleTimeString()} to ${new Date(f).toLocaleTimeString()}`),await u.updateEventsExpiredAt(p,f,a.expirationTimeLimitMinutes),o.info("Attaching QuestionAnswered listener"),o.eventEmitter.on(o.SprigEvent.QuestionAnswered,c)}},"Error in scheduling/capturing replay")},Ht=async()=>{parseInt(C??"0")||o.sessionStorageHelper.removeItem("sprig.isCapturingHeatmap"),o.sessionStorageHelper.getItem("sprig.teardownAfterCapture")&&(ge(),Se(),o.sessionStorageHelper.removeItem("sprig.teardownAfterCapture"))},Se=async()=>b()?o.debug("Not clearing user data, replay is disabled"):Promise.all([u.deleteBySessionId("events",w),u.deleteBySessionId("pendingCaptures",w)]).catch(e=>{T("Error clearing user replay data",e)}),De=async e=>{if(b())return;o.info(`Scheduling replay capture: ${JSON.stringify(e)}`);const{isHeatmap:t,surveyId:n}=e,r=await u.getPendingCaptures(),a=r==null?void 0:r.filter(l=>l.captureParams.surveyId===n);if(a!=null&&a.length){o.info(`Pending capture exists for survey: ${n}`);return}t&&(St(),o.sessionStorageHelper.setItem("sprig.isCapturingHeatmap","true"),j=Date.now(),m.inactivityInterval||(m.inactivityInterval=window.setInterval(()=>{it(j)},1e3)));const s={...e,replayParams:{...e.replayParams}};e.replayParams.replayDurationType==="beforeAndAfter"&&(s.replayParams.replayDurationSeconds*=2),s.replayParams.replayDurationType="before";const i=e.triggerTimestamp+e.replayParams.replayDurationSeconds*1e3;s.triggerTimestamp=i,C=(parseInt(C??"0")+1).toString(),o.sessionStorageHelper.setItem("sprig.pendingCount",C),await(await u.openDB()).add("pendingCaptures",{canUpload:!1,captureParams:s,sessionId:w,targetTimestamp:i,timestamp:Date.now(),uuid:o.v4()})},Ft=Object.freeze(Object.defineProperty({__proto__:null,RecordEvent:dt,RecordPageView:ct,RecordSurveyShown:ut,_completeSessionReplay:Dt,checkPendingHeatmapsUrl:ot,clearUserReplayData:Se,disableRecording:T,initializeReplay:Pt,isReplayRecording:yt,scheduleCapture:De,scheduleOrCaptureReplay:be,tryReplayAction:h},Symbol.toStringTag,{value:"Module"}));o.registerReplay(Ft);
1
+ "use strict";var De=Object.defineProperty;var Ee=(e,t,n)=>t in e?De(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var x=(e,t,n)=>(Ee(e,typeof t!="symbol"?t+"":t,n),n);const i=require("./metricsReporter-BJNGF-rH.cjs");var v=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(v||{});class ve{constructor(t){x(this,"awaitingResolvers",[]);x(this,"activeCount",0);this.capacity=t}async acquire(){if(this.activeCount<this.capacity){this.activeCount++;return}return new Promise(t=>{this.awaitingResolvers.push(t)})}release(){const t=this.awaitingResolvers.shift();t&&this.activeCount<=this.capacity?t():this.activeCount--}async execute(t){try{return await this.acquire(),await t()}finally{this.release()}}setLimit(t){this.capacity=t}}const te=new ve(2),Re=e=>te.setLimit(e),ke=async e=>te.execute(async()=>{var r;i.breadcrumbsLogger.info("UploadChunkStart",{chunkIndex:e.chunkIndex,surveyId:e.surveyId});const t=await i.sprigFetch(e.uploadUrl,{body:e.data,method:"PUT"});i.breadcrumbsLogger.http("UploadChunkEnd",{url:e.uploadUrl,method:"PUT",status_code:t.status,reason:t.statusText??"OK",chunkIndex:e.chunkIndex,surveyId:e.surveyId});const n=(r=t.headers)==null?void 0:r.get("ETag");if(!n)throw new Error(`Upload response did not include etag for upload ${e.uploadId}, part ${e.chunkIndex}`);return n}),ne=async({apiUrl:e,surveyId:t,uploadId:n,etags:r,headers:a,responseGroupUuid:s,replayDuration:o,eventDigest:c},d=!1)=>{var m;if(!d&&!n&&!r){i.breadcrumbsLogger.error("UploadErr",{isMobile:d,uploadId:n,etags:r});return}i.breadcrumbsLogger.info("MarkUploadComplete",{surveyId:t});const l=await i.sprigFetch(`${e}/sdk/1/completeSessionReplay`,{method:"POST",body:JSON.stringify({etags:r,uploadId:n,responseGroupUuid:s,surveyId:t,replayDuration:o,eventDigest:c,userAgent:(m=window==null?void 0:window.navigator)==null?void 0:m.userAgent}),headers:a,shouldRetryRequest:!0});return i.breadcrumbsLogger.info("MarkUploadDone",{surveyId:t}),l},U=(e,t)=>t.some(n=>e instanceof n);let G,z;function Pe(){return G||(G=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Be(){return z||(z=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const L=new WeakMap,A=new WeakMap,P=new WeakMap;function xe(e){const t=new Promise((n,r)=>{const a=()=>{n(S(e.result))},s=()=>{r(e.error)};e.onsuccess=a,e.onerror=s});return P.set(t,e),t}function Ae(e){if(L.has(e))return;const t=new Promise((n,r)=>{const a=()=>{n()},s=()=>{r(e.error||new DOMException("AbortError","AbortError"))};e.oncomplete=a,e.onerror=s,e.onabort=s});L.set(e,t)}let _={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return L.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return S(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function re(e){_=e(_)}function Te(e){return Be().includes(e)?function(...t){return e.apply(N(this),t),S(this.request)}:function(...t){return S(e.apply(N(this),t))}}function Ue(e){return typeof e=="function"?Te(e):(e instanceof IDBTransaction&&Ae(e),U(e,Pe())?new Proxy(e,_):e)}function S(e){if(e instanceof IDBRequest)return xe(e);if(A.has(e))return A.get(e);const t=Ue(e);return t!==e&&(A.set(e,t),P.set(t,e)),t}const N=e=>P.get(e);function Le(e,t,{blocked:n,upgrade:r,blocking:a,terminated:s}={}){const o=indexedDB.open(e,t),c=S(o);return r&&(o.onupgradeneeded=d=>{r(S(o.result),d.oldVersion,d.newVersion,S(o.transaction),d)}),n&&(o.onblocked=d=>n(d.oldVersion,d.newVersion,d)),c.then(d=>{s&&(d.onclose=()=>s()),a&&(d.onversionchange=l=>a(l.oldVersion,l.newVersion,l))}).catch(()=>{}),c}function j(e,{blocked:t}={}){const n=indexedDB.deleteDatabase(e);return t&&(n.onblocked=r=>t(r.oldVersion,r)),S(n).then(()=>{})}const _e=["get","getKey","getAll","getAllKeys","count"],Ne=["put","add","delete","clear"],T=new Map;function q(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(T.get(t))return T.get(t);const n=t.replace(/FromIndex$/,""),r=t!==n,a=Ne.includes(n);if(!(n in(r?IDBIndex:IDBObjectStore).prototype)||!(a||_e.includes(n)))return;const s=async function(o,...c){const d=this.transaction(o,a?"readwrite":"readonly");let l=d.store;return r&&(l=l.index(c.shift())),(await Promise.all([l[n](...c),a&&d.done]))[0]};return T.set(t,s),s}re(e=>({...e,get:(t,n,r)=>q(t,n)||e.get(t,n,r),has:(t,n)=>!!q(t,n)||e.has(t,n)}));const Me=["continue","continuePrimaryKey","advance"],J={},M=new WeakMap,ae=new WeakMap,Oe={get(e,t){if(!Me.includes(t))return e[t];let n=J[t];return n||(n=J[t]=function(...r){M.set(this,ae.get(this)[t](...r))}),n}};async function*He(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;t=t;const n=new Proxy(t,Oe);for(ae.set(n,t),P.set(n,N(t));t;)yield n,t=await(M.get(n)||t.continue()),M.delete(n)}function X(e,t){return t===Symbol.asyncIterator&&U(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&U(e,[IDBIndex,IDBObjectStore])}re(e=>({...e,get(t,n,r){return X(t,n)?He:e.get(t,n,r)},has(t,n){return X(t,n)||e.has(t,n)}}));const Fe=e=>{if(e instanceof Attr)return null;let t=1;for(let n=e.previousSibling;n;n=n.previousSibling)n.nodeName===e.nodeName&&++t;return t},se=e=>{if(e===null)return"";const t=[];if(e instanceof Document)return"/";for(let n=e;n&&!(n instanceof Document)&&n!==null;n=n instanceof Attr?n.ownerElement:n.parentElement){const r=t[t.length]={name:void 0,position:null};switch(n.nodeType){case Node.TEXT_NODE:r.name="text()";break;case Node.ATTRIBUTE_NODE:r.name="@"+n.nodeName;break;case Node.PROCESSING_INSTRUCTION_NODE:r.name="processing-instruction()";break;case Node.COMMENT_NODE:r.name="comment()";break;case Node.ELEMENT_NODE:r.name=n.nodeName;break}r.position=Fe(n)}return"/"+t.reverse().map(n=>n.position!==null?`/${n.name}[${n.position}]`:`/${n.name}`).join("")},C={capture:!0,passive:!0},Ve=["a","button","input","option","li","link"],Ke=["Escape","Enter","Backspace","F5","Tab"];let R=!1;const je=["label","type","role","title","placeholder","errormessage","valuetext","href"],Y="aria-",We=e=>{if(!e.tagName)return"No tagName";const t=e.getAttribute("type");return t?`${t} ${e.tagName.toLowerCase()}`:e.tagName.toLowerCase()},Q=e=>{var r;if(((r=e.tagName)==null?void 0:r.toLowerCase())==="html")return{element:"html"};const t=e.textContent,n=t?{text:t}:{};n.element=We(e);for(const a of e.attributes){let s=a.name;const o=a.value;s.startsWith(Y)&&(s=s.substring(Y.length)),je.includes(s)&&(n[s]=o)}return n},$e=e=>{var a;if(!e)return{};const n={...Q(e)},r=e.parentElement;if(r&&Ve.includes((a=r.tagName)==null?void 0:a.toLowerCase())){const s=Q(r);Object.assign(n,s)}return n},oe=(e,t)=>{var n;ot({x:t.x,y:t.y,type:e,elementAttributes:$e(t.target),windowHeight:window.innerHeight,windowWidth:window.innerWidth,...t.target instanceof HTMLElement?{rect:(n=t.target)==null?void 0:n.getBoundingClientRect(),xPath:se(t.target)}:{}})},Ge=e=>t=>oe(e,t),ie=e=>{Ke.includes(e.key)&&pt({key:e.key})},ze=()=>{window.performance.getEntriesByType("navigation").map(t=>t.type).includes("reload")&&lt({url:window.location.href,currentPageTitle:document.title})},qe=()=>{window.performance.getEntriesByType("navigation").map(t=>t.type).includes("back_forward")&&ut({curUrl:window.location.href,fromUrl:document.referrer,currentPageTitle:document.title})},Je=(e,t)=>{let n;return r=>{clearTimeout(n),n=window.setTimeout(()=>e(r),t)}},Xe=e=>{if(!(e.target instanceof HTMLElement||e.target instanceof Document))return;let t=e.target;"scrollTop"in t||(t=t.documentElement),gt({xPath:se(t),x:t.scrollLeft,y:t.scrollTop,elementAttributes:{targetScrollWidth:t.scrollWidth,targetClientWidth:t.clientWidth,targetScrollHeight:t.scrollHeight,targetClientHeight:t.clientHeight}})},ce=Je(Xe,750),de=Ge("left_click"),le=e=>{e.button===2&&oe("right_click",e)},Ye=()=>{R||(window.addEventListener("click",de,C),window.addEventListener("mousedown",le,C),window.addEventListener("keydown",ie,C),window.addEventListener("scroll",ce,C),R=!0,ze(),qe())},Qe=()=>{R&&(window.removeEventListener("click",de,C),window.removeEventListener("mousedown",le,C),window.removeEventListener("keydown",ie,C),window.removeEventListener("scroll",ce,C),R=!1)},Ze=3e4,g={isRecording:!1,scrollEventUuids:{},stopRecording:()=>{}},et=.5,tt=async()=>{var e;if(!window.indexedDB||!window.IDBKeyRange||!window.CompressionStream)return!0;if((e=window.navigator.storage)!=null&&e.estimate)try{const{quota:t=0,usage:n=0}=await window.navigator.storage.estimate(),r=(t-n)/1024**3;return i.breadcrumbsLogger.info("Storage",{availableGb:r}),r<et}catch{return!0}return!1},nt=()=>{const e=i.sessionStorageHelper.getItem("sprig.sessionId");if(e)return i.breadcrumbsLogger.info("SessionIDFound",{savedSessionId:e}),i.sessionStorageHelper.removeItem("sprig.sessionId"),e;const t=i.v4();return i.breadcrumbsLogger.info("GeneratedSessionID",{uuid:t}),t},f=nt(),O=()=>{i.sessionStorageHelper.setItem("sprig.disableReplayRecording","disabled")},y=()=>!!i.sessionStorageHelper.getItem("sprig.disableReplayRecording");window.addEventListener("beforeunload",()=>{i.breadcrumbsLogger.info("BeforeUnload",{sessionId:f}),i.sessionStorageHelper.setItem("sprig.sessionId",f)});const rt=()=>y()?i.breadcrumbsLogger.debug("ReplayDisabled-PendingHeatmaps"):w(async()=>{const e=(await u.getPendingCaptures({isHeatmap:!0})).map(n=>({eventId:n.captureParams.eventId,uuid:n.uuid})),t=[];e.forEach(({eventId:n,uuid:r})=>{i.checkUrlStillMatching(n)||t.push(r)}),t.length&&await u.markPendingHeatmapsReady(t)},"Error marking pending heatmaps ready"),at=e=>{Date.now()-e>=Ze&&w(()=>u.markPendingHeatmapsReady(),"Error in heatmap inactivity")},W=e=>e&&e.trim().substring(0,500).replace(/\s\s+/g," ").replace(/\r?\n|\r/g," ").substring(0,250),h=(e,t)=>{var n,r;if(!(y()||!g.isRecording))try{(r=(n=window.rrwebRecord)==null?void 0:n.addCustomEvent)==null||r.call(n,e,t)}catch(a){B("Error recording custom event",a)}},st=e=>{e.description&&(e.description=W(e.description)),h("Sprig_PageView",e)},ot=e=>{var t;(t=e==null?void 0:e.elementAttributes)!=null&&t.text&&(e.elementAttributes.text=W(e.elementAttributes.text)),h("Sprig_Click",e)},it=e=>{h("Sprig_TrackEvent",e)},ct=e=>{h("Sprig_ShowSurvey",e)},dt=e=>{h("Sprig_SubmitSurvey",e)},lt=e=>{h("Sprig_Refresh",e)},ut=e=>{e.currentPageTitle&&(e.currentPageTitle=W(e.currentPageTitle)),h("Sprig_BackForward",e)},pt=e=>{h("Sprig_Keystroke",e)},gt=async e=>{const{x:t,xPath:n,y:r}=e,a=g.scrollEventUuids[n];if(a)return w(async()=>{var c,d,l,m;const s=await u.openDB(),o=await s.get("events",a);if(o!=null&&o.event){const p=JSON.parse(o.event),b=t>((d=(c=p.data)==null?void 0:c.payload)==null?void 0:d.x),I=r>((m=(l=p.data)==null?void 0:l.payload)==null?void 0:m.y);if(!(b||I))return null;b&&(p.data.payload.x=t),I&&(p.data.payload.y=r),p.data.payload.elementAttributes=e.elementAttributes,o.event=JSON.stringify(p),await s.put("events",o)}else h("Sprig_Scroll",e)},"Error updating scroll event");h("Sprig_Scroll",e)},mt=()=>g.isRecording,ue=()=>{g.stopRecording&&(g.stopRecording(),g.stopRecording=void 0),g.isRecording=!1,["cleanupInterval","inactivityInterval","pendingCheckInterval"].forEach(e=>{g[e]&&(clearInterval(g[e]),g[e]=void 0)}),Qe()},ft=["did not allow mutations","called in an invalid security context"],wt=e=>{if(!e)return!0;for(const t of ft)if(e.toLowerCase().includes(t))return!1;return!0},yt=(e,t,{reportError:n=!0,extraInfo:r})=>{if(!y()&&t instanceof Error){if(O(),t.name==="VersionError")return i.breadcrumbsLogger.error("VersionErr",{message:e}),u.deleteDB();wt(t==null?void 0:t.message)&&(n&&window.UserLeap.reportError(e,t,r),u.clearAll())}},ht=async(e,t,{reportError:n}={reportError:!0})=>{let r={};try{const{quota:a=0,usage:s=0}=await window.navigator.storage.estimate();r={availableSpaceInMB:(a-s)/2**20,quota:a,usage:s}}catch{r.availableSpaceInMB=null}yt(e,t,{reportError:n,extraInfo:r})},B=(e,t,{reportError:n}={reportError:!0})=>(ue(),i.breadcrumbsLogger.error("ReplayErr",{code:t.code,name:t.name}),ht(e,t,{reportError:n})),w=async(e,t)=>{try{await e()}catch(n){B(t,n)}},bt=()=>{g.isRecording&&w(()=>{var e,t;return(t=(e=window.rrwebRecord)==null?void 0:e.takeFullSnapshot)==null?void 0:t.call(e,!0)},"Error recording full snapshot")},It=async({surveyId:e,responseGroupUuid:t,eventDigest:n,headers:r})=>{if(!e||!t)return!1;const a=window.UserLeap._API_URL,s=await ne({surveyId:e,responseGroupUuid:t,eventDigest:n,apiUrl:a,headers:r},!0);return!(s!=null&&s.error)},Z=30,Ct=1;j("replayStorage").catch(console.error);j("sprig.replay").catch(console.error);class St{openDB(){return Le("sprigReplay",Ct,{upgrade:(t,n,r)=>{if(r===0&&i.sessionStorageHelper.setItem("sprig.pendingCount","0"),!t.objectStoreNames.contains("events")){const a=t.createObjectStore("events",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+timestamp]",["sessionId","timestamp"])}if(!t.objectStoreNames.contains("chunkUploads")){const a=t.createObjectStore("chunkUploads",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+status]",["sessionId","status"]),a.createIndex("[uploadId+status]",["uploadId","status"]),a.createIndex("[sessionId+status+uploadId]",["sessionId","status","uploadId"])}if(!t.objectStoreNames.contains("pendingCaptures")){const a=t.createObjectStore("pendingCaptures",{keyPath:"uuid"});a.createIndex("sessionId","sessionId"),a.createIndex("timestamp","timestamp"),a.createIndex("[sessionId+targetTimestamp]",["sessionId","targetTimestamp"])}}})}deleteDB(){return j("sprigReplay").catch(console.error)}async bulkAdd(t,n){const r=(await this.openDB()).transaction(t,"readwrite");return Promise.all([...n.map(a=>r.store.add(a)),r.done])}async clearAll(){const t=(await this.openDB()).transaction(["events","chunkUploads","pendingCaptures"],"readwrite");return Promise.all([t.objectStore("events").clear(),t.objectStore("chunkUploads").clear(),t.objectStore("pendingCaptures").clear()])}async deleteBySessionId(t,n){const r=IDBKeyRange.only(n),a=(await this.openDB()).transaction(t,"readwrite"),s=a.store.index("sessionId");for await(const o of s.iterate(r))await o.delete();await a.done}async updatePartial(t,n,r){const s=(await this.openDB()).transaction(t,"readwrite"),o=await s.store.get(n);o&&await s.store.put({...o,...r}),await s.done}async deleteRowsBefore(t,n,r=()=>!0){const a=IDBKeyRange.upperBound(n,!0),s=(await this.openDB()).transaction(t,"readwrite"),o=s.store.index("timestamp");for await(const c of o.iterate(a))r(c.value)&&await c.delete();await s.done}async getEventsBetween(t,n=Date.now()){if(t>=n)return Promise.resolve([]);const r=IDBKeyRange.bound([f,t],[f,n],!1,!0);return(await this.openDB()).getAllFromIndex("events","[sessionId+timestamp]",r)}async updateEventsExpiredAt(t,n,r=Z){const a=new Date,s=a.setMinutes(a.getMinutes()+(r??Z)),o=(await this.openDB()).transaction("events","readwrite"),c=o.store.index("[sessionId+timestamp]"),d=IDBKeyRange.bound([f,t],[f,n],!1,!0);for await(const l of c.iterate(d))await l.update({...l.value,expiredAt:s});await o.done}async deleteChunkUploads(t,n){const r=IDBKeyRange.only([n,t]),a=(await this.openDB()).transaction("chunkUploads","readwrite");let o=await a.store.index("[uploadId+status]").openCursor(r);for(;o;)o.delete(),o=await o.continue();await a.done}async getChunkUploadsByStatus({sessionId:t,status:n,uploadId:r}){const s=(await this.openDB()).transaction("chunkUploads","readonly"),o=r?s.store.index("[uploadId+status]"):s.store.index("[sessionId+status]"),c=r?IDBKeyRange.only([r,n]):IDBKeyRange.only([t,n]);return o.getAll(c)}async getPendingCaptures(t={}){return(await(await this.openDB()).getAllFromIndex("pendingCaptures","sessionId",f)).filter(a=>!t.beforePresent||a.targetTimestamp<Date.now()).filter(a=>!t.isHeatmap||(a.captureParams.isHeatmap??!1))}async markPendingCaptureToCanUpload(t){const n=(await this.openDB()).transaction("pendingCaptures","readwrite"),r=n.store.index("sessionId");for await(const a of r.iterate(f)){const s=a.value;s.captureParams.responseGroupId===t&&await a.update({...s,canUpload:!0})}await n.done}async markPendingHeatmapsReady(t){if(parseInt(i.sessionStorageHelper.getItem("sprig.pendingCount")??"0")===0)return null;const r=Date.now(),a=(await this.openDB()).transaction("pendingCaptures","readwrite"),s=a.store.index("sessionId");for await(const o of s.iterate(f)){const c=o.value;c.captureParams.isHeatmap&&(!t||t.includes(c.uuid))&&await o.update({...c,targetTimestamp:r,captureParams:{...c.captureParams,triggerTimestamp:r,replayParams:{...c.captureParams.replayParams,replayDurationSeconds:Math.floor((r-c.timestamp)/1e3)}}})}await a.done}}const u=new St,Dt=async(e,t,n)=>new Promise((r,a)=>{const s=e.createElement("script");s.src=t,s.onload=r,s.onerror=a,n&&(s.nonce=n),e.head.appendChild(s)}),pe=async(e,t)=>{const n=performance.now();let r;try{r=await e()}finally{const a=performance.now()-n;let s=i.PerformanceMetrics[t];s||(s=i.registerMetric(t)),s.report(a/1e3)}return r},ge=(e,t)=>{const n=performance.now();try{e()}finally{const r=performance.now()-n;let a=i.PerformanceMetrics[t];a||(a=i.registerMetric(t)),a.report(r/1e3)}};let me=5e3,H=6e4,F=0;const Et=5,fe=30,k=fe+Et;let D,V=!1,K=[];const vt=async({viewDocument:e,maxReplayDurationSeconds:t,replayNonce:n,maxInflightRequests:r=2,replaySettings:a,teardownAfter:s=!1})=>{if(D=i.sessionStorageHelper.getItem("sprig.pendingCount"),!g.isRecording){if(s&&i.sessionStorageHelper.setItem("sprig.teardownAfterCapture","true"),y())return i.breadcrumbsLogger.debug("ReplayDisabled");if(await tt())return i.breadcrumbsLogger.debug("IDBNotSupported"),O();try{const o=await u.openDB();i.breadcrumbsLogger.info("DBVersion",{version:o.version})}catch(o){return i.breadcrumbsLogger.error("ReplayOpenErr",{name:o.name}),o.name==="VersionError"&&u.deleteDB(),O()}if(!t)return i.breadcrumbsLogger.debug("MissingDuration");i.breadcrumbsLogger.debug("ReplayInit"),await w(async()=>{if(a!=null&&a.minDuration&&(me=a.minDuration),a!=null&&a.batchDuration&&(H=a.batchDuration),Re(r),Ut(),Bt(t+k,30*60,t+k),xt(),!window.rrwebRecord){const l=window.UserLeap.replayLibraryURL??"https://cdn.sprig.com/dependencies/record-2.0.0-alpha.6.min.js";await Dt(e,l,n)}const o=window.rrwebRecord;if(!o)return i.breadcrumbsLogger.error("RecordScriptFailed");let c=!0,d=0;g.stopRecording=o({checkoutEveryNms:fe*1e3,sampling:{input:"last",scroll:250,media:800},emit:(l,m)=>{if(l.type===v.Custom&&(F=Date.now()),y())return;if(m&&l.type===v.Meta)d=performance.now();else if(m&&d&&l.type===v.FullSnapshot){const b=performance.now()-d;i.reportAndRegister("sdk_replay_snapshot_seconds",b/1e3)}const p=c||!!m&&l.type===v.Meta;c=!1,Rt({uuid:i.v4(),event:JSON.stringify(l),isValidStart:p,timestamp:Date.now()})},...a}),g.isRecording=!!g.stopRecording,g.isRecording&&(i.eventEmitter.on("survey.complete",l=>{dt({id:l,userAgent:window.navigator.userAgent})}),Ye())},"Error initializing replay")}},Rt=e=>{var t,n,r,a;if((t=e.event)!=null&&t.includes("Sprig_Scroll")){const s=(a=(r=(n=JSON.parse(e.event))==null?void 0:n.data)==null?void 0:r.payload)==null?void 0:a.xPath;if(!s)return;g.scrollEventUuids[s]=e.uuid}K.push(e),V||Pt()},kt=async e=>{const t=e.map(n=>({...n,sessionId:n.sessionId??f}));if(t.length!==0)return w(()=>u.bulkAdd("events",t),"Error storing replay events")},Pt=()=>{V=!0,setTimeout(async()=>{if(y())return;const e=K;K=[],V=!1,ge(async()=>{await kt(e)},"sdk_replay_add_event_batch_seconds")},500)},Bt=(e,t,n)=>{g.cleanupInterval=window.setInterval(()=>{const r=Date.now();pe(()=>w(async()=>{y()||await Promise.all([u.deleteRowsBefore("events",r-e*1e3,a=>a.expiredAt===void 0||a.expiredAt<r-e*1e3),u.deleteRowsBefore("chunkUploads",r-t*1e3),u.deleteRowsBefore("pendingCaptures",r-n*1e3,a=>!a.canUpload)])},"Error deleting table rows"),"sdk_replay_cleanup_seconds"),i.breadcrumbsLogger.debug("CleanupComplete")},3e4)},xt=()=>{g.pendingCheckInterval=window.setInterval(async()=>{w(async()=>{const e=parseInt(D??"0");if(e===0)return;const t=await u.getPendingCaptures({beforePresent:!0}),n=await u.openDB();await Promise.all(t.map(async r=>(await n.delete("pendingCaptures",r.uuid),he(r.captureParams,r.canUpload)))),D=(e-t.length).toString(),i.sessionStorageHelper.setItem("sprig.pendingCount",D)},"Error initiating pending captures")},5e3)},At=async(e,t,n,r,a)=>{const s=Math.min(e+a,n),o=await pe(()=>u.getEventsBetween(e,s),"sdk_replay_get_events_between_seconds");if(!(o!=null&&o.length))return i.breadcrumbsLogger.debug("NoEventsFound"),{validStartFound:r,events:[]};if(!r){i.breadcrumbsLogger.debug("ValidStartSearch");let c=-1;return o==null||o.forEach((d,l)=>{if(!d.isValidStart)return;const m=d.timestamp<=t;(c<0||m)&&(c=l)}),c<0?(i.breadcrumbsLogger.debug("ValidStartNotFound"),{validStartFound:r,events:[]}):{validStartFound:!0,events:o==null?void 0:o.slice(c)}}return{validStartFound:r,events:o}},Tt=(e,t,n)=>{const r=e.length,a=t*1024*1024,s=Math.ceil(r/n),o=Math.max(a,s),c=[];let d=0;for(;d<r;)c.push(e.slice(d,d+o)),d+=o;return c},we=e=>Promise.all(e.map(async t=>{const n=await ke(t);return await u.updatePartial("chunkUploads",t.uuid,{data:null,etag:n,status:"UploadComplete"}),t.uploadId})),ye=async e=>{const t=await u.getChunkUploadsByStatus({status:"UploadComplete",uploadId:e});if(!(t!=null&&t.length)){i.breadcrumbsLogger.info("NoChunksForUpload",{uploadId:e});return}const n=t.reduce((s,o)=>(s.find(c=>c.chunkIndex===o.chunkIndex)||s.push(o),s),[]);n.sort((s,o)=>s.chunkIndex-o.chunkIndex);const r=n.map(s=>({ETag:s.etag,PartNumber:s.chunkIndex})).filter(s=>s.ETag!==null),a=n[0];await ne({apiUrl:a.apiUrl,surveyId:a.surveyId,uploadId:e,responseGroupUuid:a.responseGroupId,etags:r,headers:a.completeUploadHeaders,replayDuration:a.replayDuration}),await u.deleteChunkUploads("UploadComplete",e)},Ut=()=>{w(async()=>{const e=await u.getChunkUploadsByStatus({sessionId:f,status:"ReadyForUpload"});if(!(e!=null&&e.length))return;const t=await we(e);t!=null&&t.length&&await Promise.all(t.map(n=>{if(n)return ye(n)}))},"Error uploading unfinished chunks")},Lt=async(e,t)=>{await we(t),await Promise.all(e.map(n=>ye(n)))},_t=async(e,t)=>{const n=new TextEncoder;let r=null;const a=new CompressionStream("gzip"),s=a.writable.getWriter();let o=!1,c=!1,[d,l]=[0,0];const m=e-k*1e3;let p=[];for(let I=m;I<t;I+=H){if({validStartFound:c,events:p}=await At(I,e,t,c,H),!(p!=null&&p.length)){i.breadcrumbsLogger.debug("NoEventsFound");continue}d===0&&(d=p[0].timestamp),l=p[p.length-1].timestamp;const E=p.map(Se=>Se.event);E.push(`{"timestamp":${t}}`);const $=`${o?",":"["}${E}`,Ce=n.encode($);ge(()=>{s.write(Ce)},"sdk_replay_compression_seconds"),o=!0}if(l-d<me)return i.breadcrumbsLogger.debug("ReplayTooShort"),null;const b=n.encode("]");return s.write(b),s.close(),r=new Uint8Array(await new Response(a.readable).arrayBuffer()),r},Nt=async(e,t)=>{const n=t??Date.now(),r=n-e;return _t(r,n)},ee=async e=>{const{surveyId:t,responseGroupId:n,visitorId:r,apiUrl:a,completeUploadHeaders:s,replayParams:o,triggerTimestamp:c}=e,d=await Nt(o.replayDurationSeconds*1e3,c);if(!(d!=null&&d.length)){i.breadcrumbsLogger.info("FileDataEmpty",{surveyId:t});return}const l=Tt(d,o.minimumChunkSizeMb,o.signedUrls.length),m=await Promise.all(l.map(async(p,b)=>{const I=i.v4(),E={apiUrl:a,chunkIndex:b+1,completeUploadHeaders:s,etag:null,responseGroupId:n,status:"ReadyForUpload",surveyId:t,timestamp:c,totalChunks:l.length,data:p,uploadId:o.uploadId,uploadUrl:o.signedUrls[b].url,uuid:I,visitorId:r};return await(await u.openDB()).add("chunkUploads",{...E,sessionId:E.sessionId??f}),E}));await Lt([o.uploadId],m)},he=async(e,t)=>{if(y())return i.breadcrumbsLogger.debug("ReplayDisabled-ScheduleOrCapture");const{isHeatmap:n,isStandalone:r,replayParams:a,triggerTimestamp:s,responseGroupId:o}=e,c=async()=>{setTimeout(()=>i.eventEmitter.removeListener(i.SprigEvent.QuestionAnswered,c),0),w(async()=>{a.replayDurationType==="before"?await ee(e):await u.markPendingCaptureToCanUpload(o)},"Error in schedule/capture callback")};w(async()=>{if(a.replayDurationType==="after"||a.replayDurationType==="beforeAndAfter"){!r&&!n&&i.eventEmitter.on(i.SprigEvent.QuestionAnswered,c),await Ie(e);return}if(r||n||t)await ee(e),n&&Mt();else{const l=k+a.replayDurationSeconds,m=s-l*1e3,p=s;await u.updateEventsExpiredAt(m,p,a.expirationTimeLimitMinutes),i.eventEmitter.on(i.SprigEvent.QuestionAnswered,c)}},"Error in scheduling/capturing replay")},Mt=async()=>{parseInt(D??"0")||i.sessionStorageHelper.removeItem("sprig.isCapturingHeatmap"),i.sessionStorageHelper.getItem("sprig.teardownAfterCapture")&&(ue(),be(),i.sessionStorageHelper.removeItem("sprig.teardownAfterCapture"))},be=async()=>y()?i.breadcrumbsLogger.debug("ReplayDisabled-ClearData"):Promise.all([u.deleteBySessionId("events",f),u.deleteBySessionId("pendingCaptures",f)]).catch(e=>{B("Error clearing user replay data",e)}),Ie=async e=>{if(y())return;const{isHeatmap:t,surveyId:n}=e,r=await u.getPendingCaptures(),a=r==null?void 0:r.filter(d=>d.captureParams.surveyId===n);if(a!=null&&a.length){i.breadcrumbsLogger.info("PendingCaptureExists",{surveyId:n});return}t&&(bt(),i.sessionStorageHelper.setItem("sprig.isCapturingHeatmap","true"),F=Date.now(),g.inactivityInterval||(g.inactivityInterval=window.setInterval(()=>{at(F)},1e3)));const s={...e,replayParams:{...e.replayParams}};e.replayParams.replayDurationType==="beforeAndAfter"&&(s.replayParams.replayDurationSeconds*=2),s.replayParams.replayDurationType="before";const o=e.triggerTimestamp+e.replayParams.replayDurationSeconds*1e3;s.triggerTimestamp=o,D=(parseInt(D??"0")+1).toString(),i.sessionStorageHelper.setItem("sprig.pendingCount",D),await(await u.openDB()).add("pendingCaptures",{canUpload:!1,captureParams:s,sessionId:f,targetTimestamp:o,timestamp:Date.now(),uuid:i.v4()})},Ot=Object.freeze(Object.defineProperty({__proto__:null,RecordEvent:it,RecordPageView:st,RecordSurveyShown:ct,_completeSessionReplay:It,checkPendingHeatmapsUrl:rt,clearUserReplayData:be,disableRecording:B,initializeReplay:vt,isReplayRecording:mt,scheduleCapture:Ie,scheduleOrCaptureReplay:he,tryReplayAction:w},Symbol.toStringTag,{value:"Module"}));i.registerReplay(Ot);
package/dist/replay.js CHANGED
@@ -1 +1 @@
1
- var _e=Object.defineProperty,Le=(e,t,n)=>t in e?_e(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,ee=(e,t,n)=>(Le(e,typeof t!="symbol"?t+"":t,n),n);import{i,s as te,a as y,v as P,e as _,w as ne,c as Me,P as ae,r as re,b as Oe,d as x,f as B,S as L,g as He}from"./metricsReporter-5CQW74cF.js";var E=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(E||{});class je{constructor(t){ee(this,"awaitingResolvers",[]),ee(this,"activeCount",0),this.capacity=t}async acquire(){if(this.activeCount<this.capacity){this.activeCount++;return}return new Promise(t=>{this.awaitingResolvers.push(t)})}release(){const t=this.awaitingResolvers.shift();t&&this.activeCount<=this.capacity?t():this.activeCount--}async execute(t){try{return await this.acquire(),await t()}finally{this.release()}}setLimit(t){this.capacity=t}}const oe=new je(2),Fe=e=>oe.setLimit(e),Ge=async e=>oe.execute(async()=>{var t;i(`Beginning upload of chunk ${e.chunkIndex} for survey: ${e.surveyId}`);const n=await te(e.uploadUrl,{body:e.data,method:"PUT"});i(`Completed upload of chunk ${e.chunkIndex} for survey: ${e.surveyId}`);const a=(t=n.headers)==null?void 0:t.get("ETag");if(!a)throw new Error(`Upload response did not include etag for upload ${e.uploadId}, part ${e.chunkIndex}`);return a}),se=async({apiUrl:e,surveyId:t,uploadId:n,etags:a,headers:r,responseGroupUuid:o,replayDuration:s,eventDigest:d},l=!1)=>{var u;if(!l&&!n&&!a){i(`Cannot mark upload complete: isMobile: ${l} / uploadId: ${n} / etags: ${a}`);return}i(`Marking upload complete for survey: ${t}`);const p=await te(`${e}/sdk/1/completeSessionReplay`,{method:"POST",body:JSON.stringify({etags:a,uploadId:n,responseGroupUuid:o,surveyId:t,replayDuration:s,eventDigest:d,userAgent:(u=window?.navigator)==null?void 0:u.userAgent}),headers:r,shouldRetryRequest:!0});return i(`Done marking upload complete for survey: ${t}`),p},M=(e,t)=>t.some(n=>e instanceof n);let ie,le;function We(){return ie||(ie=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Ke(){return le||(le=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const O=new WeakMap,H=new WeakMap,R=new WeakMap;function Ve(e){const t=new Promise((n,a)=>{const r=()=>{n(b(e.result))},o=()=>{a(e.error)};e.onsuccess=r,e.onerror=o});return R.set(t,e),t}function qe(e){if(O.has(e))return;const t=new Promise((n,a)=>{const r=()=>{n()},o=()=>{a(e.error||new DOMException("AbortError","AbortError"))};e.oncomplete=r,e.onerror=o,e.onabort=o});O.set(e,t)}let j={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return O.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return b(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function de(e){j=e(j)}function Je(e){return Ke().includes(e)?function(...t){return e.apply(F(this),t),b(this.request)}:function(...t){return b(e.apply(F(this),t))}}function ze(e){return typeof e=="function"?Je(e):(e instanceof IDBTransaction&&qe(e),M(e,We())?new Proxy(e,j):e)}function b(e){if(e instanceof IDBRequest)return Ve(e);if(H.has(e))return H.get(e);const t=ze(e);return t!==e&&(H.set(e,t),R.set(t,e)),t}const F=e=>R.get(e);function Qe(e,t,{blocked:n,upgrade:a,blocking:r,terminated:o}={}){const s=indexedDB.open(e,t),d=b(s);return a&&(s.onupgradeneeded=l=>{a(b(s.result),l.oldVersion,l.newVersion,b(s.transaction),l)}),n&&(s.onblocked=l=>n(l.oldVersion,l.newVersion,l)),d.then(l=>{o&&(l.onclose=()=>o()),r&&(l.onversionchange=u=>r(u.oldVersion,u.newVersion,u))}).catch(()=>{}),d}function G(e,{blocked:t}={}){const n=indexedDB.deleteDatabase(e);return t&&(n.onblocked=a=>t(a.oldVersion,a)),b(n).then(()=>{})}const Xe=["get","getKey","getAll","getAllKeys","count"],Ye=["put","add","delete","clear"],W=new Map;function ue(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(W.get(t))return W.get(t);const n=t.replace(/FromIndex$/,""),a=t!==n,r=Ye.includes(n);if(!(n in(a?IDBIndex:IDBObjectStore).prototype)||!(r||Xe.includes(n)))return;const o=async function(s,...d){const l=this.transaction(s,r?"readwrite":"readonly");let u=l.store;return a&&(u=u.index(d.shift())),(await Promise.all([u[n](...d),r&&l.done]))[0]};return W.set(t,o),o}de(e=>({...e,get:(t,n,a)=>ue(t,n)||e.get(t,n,a),has:(t,n)=>!!ue(t,n)||e.has(t,n)}));const Ze=["continue","continuePrimaryKey","advance"],ce={},K=new WeakMap,pe=new WeakMap,et={get(e,t){if(!Ze.includes(t))return e[t];let n=ce[t];return n||(n=ce[t]=function(...a){K.set(this,pe.get(this)[t](...a))}),n}};async function*tt(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;t=t;const n=new Proxy(t,et);for(pe.set(n,t),R.set(n,F(t));t;)yield n,t=await(K.get(n)||t.continue()),K.delete(n)}function ge(e,t){return t===Symbol.asyncIterator&&M(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&M(e,[IDBIndex,IDBObjectStore])}de(e=>({...e,get(t,n,a){return ge(t,n)?tt:e.get(t,n,a)},has(t,n){return ge(t,n)||e.has(t,n)}}));const nt=e=>{if(e instanceof Attr)return null;let t=1;for(let n=e.previousSibling;n;n=n.previousSibling)n.nodeName===e.nodeName&&++t;return t},me=e=>{if(e===null)return"";const t=[];if(e instanceof Document)return"/";for(let n=e;n&&!(n instanceof Document)&&n!==null;n=n instanceof Attr?n.ownerElement:n.parentElement){const a=t[t.length]={name:void 0,position:null};switch(n.nodeType){case Node.TEXT_NODE:a.name="text()";break;case Node.ATTRIBUTE_NODE:a.name="@"+n.nodeName;break;case Node.PROCESSING_INSTRUCTION_NODE:a.name="processing-instruction()";break;case Node.COMMENT_NODE:a.name="comment()";break;case Node.ELEMENT_NODE:a.name=n.nodeName;break}a.position=nt(n)}return"/"+t.reverse().map(n=>n.position!==null?`/${n.name}[${n.position}]`:`/${n.name}`).join("")},k={capture:!0,passive:!0},at=["a","button","input","option","li","link"],rt=["Escape","Enter","Backspace","F5","Tab"];let $=!1;const ot=["label","type","role","title","placeholder","errormessage","valuetext","href"],ye="aria-",st=e=>{if(!e.tagName)return"No tagName";const t=e.getAttribute("type");return t?`${t} ${e.tagName.toLowerCase()}`:e.tagName.toLowerCase()},we=e=>{var t;if(((t=e.tagName)==null?void 0:t.toLowerCase())==="html")return{element:"html"};const n=e.textContent,a=n?{text:n}:{};a.element=st(e);for(const r of e.attributes){let o=r.name;const s=r.value;o.startsWith(ye)&&(o=o.substring(ye.length)),ot.includes(o)&&(a[o]=s)}return a},it=e=>{var t;if(!e)return{};const n={...we(e)},a=e.parentElement;if(a&&at.includes((t=a.tagName)==null?void 0:t.toLowerCase())){const r=we(a);Object.assign(n,r)}return n},fe=(e,t)=>{var n;St({x:t.x,y:t.y,type:e,elementAttributes:it(t.target),windowHeight:window.innerHeight,windowWidth:window.innerWidth,...t.target instanceof HTMLElement?{rect:(n=t.target)==null?void 0:n.getBoundingClientRect(),xPath:me(t.target)}:{}})},lt=e=>t=>fe(e,t),he=e=>{rt.includes(e.key)&&xt({key:e.key})},dt=()=>{window.performance.getEntriesByType("navigation").map(e=>e.type).includes("reload")&&Et({url:window.location.href,currentPageTitle:document.title})},ut=()=>{window.performance.getEntriesByType("navigation").map(e=>e.type).includes("back_forward")&&Pt({curUrl:window.location.href,fromUrl:document.referrer,currentPageTitle:document.title})},ct=(e,t)=>{let n;return a=>{clearTimeout(n),n=window.setTimeout(()=>e(a),t)}},pt=e=>{if(!(e.target instanceof HTMLElement||e.target instanceof Document))return;let t=e.target;"scrollTop"in t||(t=t.documentElement),Bt({xPath:me(t),x:t.scrollLeft,y:t.scrollTop,elementAttributes:{targetScrollWidth:t.scrollWidth,targetClientWidth:t.clientWidth,targetScrollHeight:t.scrollHeight,targetClientHeight:t.clientHeight}})},ve=ct(pt,750),Ie=lt("left_click"),De=e=>{e.button===2&&fe("right_click",e)},gt=()=>{$||(window.addEventListener("click",Ie,k),window.addEventListener("mousedown",De,k),window.addEventListener("keydown",he,k),window.addEventListener("scroll",ve,k),$=!0,dt(),ut())},mt=()=>{$&&(window.removeEventListener("click",Ie,k),window.removeEventListener("mousedown",De,k),window.removeEventListener("keydown",he,k),window.removeEventListener("scroll",ve,k),$=!1)},yt=3e4,g={isRecording:!1,scrollEventUuids:{},stopRecording:()=>{}},wt=.5,ft=async()=>{var e;if(!window.indexedDB||!window.IDBKeyRange)return!0;if((e=window.navigator.storage)!=null&&e.estimate)try{const{quota:t=0,usage:n=0}=await window.navigator.storage.estimate(),a=(t-n)/1024**3;return ne(`Storage: ${a}GB`),a<wt}catch{return!0}return!1},ht=()=>{const e=y.getItem("sprig.sessionId");if(e)return i(`Found saved session id: ${e}`),y.removeItem("sprig.sessionId"),e;const t=P();return i(`Generating new uuid: ${t}`),t},w=ht(),V=()=>{y.setItem("sprig.disableReplayRecording","disabled")},S=()=>!!y.getItem("sprig.disableReplayRecording");window.addEventListener("beforeunload",()=>{i(`Before page unload saving session id: ${w}`),y.setItem("sprig.sessionId",w)});const vt=()=>S()?i("ReolayDisabledPendingHeatmap"):v(async()=>{const e=(await c.getPendingCaptures({isHeatmap:!0})).map(n=>({eventId:n.captureParams.eventId,uuid:n.uuid})),t=[];e.forEach(({eventId:n,uuid:a})=>{Me(n)||t.push(a)}),t.length&&await c.markPendingHeatmapsReady(t)},"Error marking pending heatmaps ready"),It=e=>{Date.now()-e>=yt&&v(()=>c.markPendingHeatmapsReady(),"Error in heatmap inactivity")},q=e=>e&&e.trim().substring(0,500).replace(/\s\s+/g," ").replace(/\r?\n|\r/g," ").substring(0,250),I=(e,t)=>{var n,a;if(g.isRecording)try{(a=(n=window.rrwebRecord)==null?void 0:n.addCustomEvent)==null||a.call(n,e,t)}catch(r){T("Error recording custom event",r)}},Dt=e=>{e.description&&(e.description=q(e.description)),I("Sprig_PageView",e)},St=e=>{var t;(t=e?.elementAttributes)!=null&&t.text&&(e.elementAttributes.text=q(e.elementAttributes.text)),I("Sprig_Click",e)},bt=e=>{I("Sprig_TrackEvent",e)},kt=e=>{I("Sprig_ShowSurvey",e)},Ct=e=>{I("Sprig_SubmitSurvey",e)},Et=e=>{I("Sprig_Refresh",e)},Pt=e=>{e.currentPageTitle&&(e.currentPageTitle=q(e.currentPageTitle)),I("Sprig_BackForward",e)},xt=e=>{I("Sprig_Keystroke",e)},Bt=async e=>{const{x:t,xPath:n,y:a}=e,r=g.scrollEventUuids[n];if(r)return v(async()=>{var o,s,d,l;const u=await c.openDB(),p=await u.get("events",r);if(p!=null&&p.event){const m=JSON.parse(p.event),h=t>((s=(o=m.data)==null?void 0:o.payload)==null?void 0:s.x),f=a>((l=(d=m.data)==null?void 0:d.payload)==null?void 0:l.y);if(!(h||f))return null;h&&(m.data.payload.x=t),f&&(m.data.payload.y=a),m.data.payload.elementAttributes=e.elementAttributes,p.event=JSON.stringify(m),await u.put("events",p)}else I("Sprig_Scroll",e)},"Error updating scroll event");I("Sprig_Scroll",e)},Rt=()=>g.isRecording,Se=()=>{g.stopRecording&&(g.stopRecording(),g.stopRecording=void 0),g.isRecording=!1,["cleanupInterval","inactivityInterval","pendingCheckInterval"].forEach(e=>{g[e]&&(clearInterval(g[e]),g[e]=void 0)}),mt()},$t=["did not allow mutations","called in an invalid security context"],Tt=e=>{if(!e)return!0;for(const t of $t)if(e.toLowerCase().includes(t))return!1;return!0},Ut=(e,t,{reportError:n=!0,extraInfo:a})=>{S()||t instanceof Error&&(V(),Tt(t?.message)&&(n&&window.UserLeap.reportError(e,t,a),c.clearAll()))},At=async(e,t,{reportError:n}={reportError:!0})=>{let a={};try{const{quota:r=0,usage:o=0}=await window.navigator.storage.estimate();a={availableSpaceInMB:(r-o)/2**20,quota:r,usage:o}}catch{a.availableSpaceInMB=null}Ut(e,t,{reportError:n,extraInfo:a})},T=(e,t,{reportError:n}={reportError:!0})=>(Se(),_(`${e} - ${t.message} - ${t.name}`),At(e,t,{reportError:n})),v=async(e,t)=>{try{await e()}catch(n){T(t,n)}},Nt=()=>{g.isRecording&&v(()=>{var e,t;return(t=(e=window.rrwebRecord)==null?void 0:e.takeFullSnapshot)==null?void 0:t.call(e,!0)},"Error recording full snapshot")},_t=async({surveyId:e,responseGroupUuid:t,eventDigest:n,headers:a})=>{if(!e||!t)return!1;const r=window.UserLeap._API_URL,o=await se({surveyId:e,responseGroupUuid:t,eventDigest:n,apiUrl:r,headers:a},!0);return!(o!=null&&o.error)},be=30,Lt=1;G("replayStorage").catch(console.error),G("sprig.replay").catch(console.error);class Mt{openDB(){return Qe("sprigReplay",Lt,{upgrade:(t,n,a)=>{if(a===0&&y.setItem("sprig.pendingCount","0"),!t.objectStoreNames.contains("events")){const r=t.createObjectStore("events",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+timestamp]",["sessionId","timestamp"])}if(!t.objectStoreNames.contains("chunkUploads")){const r=t.createObjectStore("chunkUploads",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+status]",["sessionId","status"]),r.createIndex("[uploadId+status]",["uploadId","status"]),r.createIndex("[sessionId+status+uploadId]",["sessionId","status","uploadId"])}if(!t.objectStoreNames.contains("pendingCaptures")){const r=t.createObjectStore("pendingCaptures",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+targetTimestamp]",["sessionId","targetTimestamp"])}}})}deleteDB(){return G("sprigReplay").catch(console.error)}async bulkAdd(t,n){const a=(await this.openDB()).transaction(t,"readwrite");return Promise.all([...n.map(r=>a.store.add(r)),a.done])}async clearAll(){const t=(await this.openDB()).transaction(["events","chunkUploads","pendingCaptures"],"readwrite");return Promise.all([t.objectStore("events").clear(),t.objectStore("chunkUploads").clear(),t.objectStore("pendingCaptures").clear()])}async deleteBySessionId(t,n){const a=IDBKeyRange.only(n),r=(await this.openDB()).transaction(t,"readwrite");let o=await r.store.index("sessionId").openCursor(a);for(;o;)o.delete(),o=await o.continue();await r.done}async updatePartial(t,n,a){const r=(await this.openDB()).transaction(t,"readwrite"),o=await r.store.get(n);o&&await r.store.put({...o,...a}),await r.done}async deleteRowsBefore(t,n,a=()=>!0){const r=IDBKeyRange.upperBound(n,!0),o=(await this.openDB()).transaction(t,"readwrite");let s=await o.store.index("timestamp").openCursor(r);for(;s;)a(s.value)&&s.delete(),s=await s.continue();await o.done}async getEventsBetween(t,n=Date.now()){if(t>=n)return Promise.resolve([]);const a=IDBKeyRange.bound([w,t],[w,n],!1,!0);return(await this.openDB()).getAllFromIndex("events","[sessionId+timestamp]",a)}async updateEventsExpiredAt(t,n,a=be){const r=new Date,o=r.setMinutes(r.getMinutes()+(a??be)),s=(await this.openDB()).transaction("events","readwrite"),d=s.store.index("[sessionId+timestamp]"),l=IDBKeyRange.bound([w,t],[w,n],!1,!0);let u=await d.openCursor(l);for(;u;)u.update({...u.value,expiredAt:o}),u=await u.continue();await s.done}async deleteChunkUploads(t,n){const a=IDBKeyRange.only([n,t]),r=(await this.openDB()).transaction("chunkUploads","readwrite");let o=await r.store.index("[uploadId+status]").openCursor(a);for(;o;)o.delete(),o=await o.continue();await r.done}async getChunkUploadsByStatus({sessionId:t,status:n,uploadId:a}){const r=(await this.openDB()).transaction("chunkUploads","readonly"),o=a?r.store.index("[uploadId+status]"):r.store.index("[sessionId+status]"),s=a?IDBKeyRange.only([a,n]):IDBKeyRange.only([t,n]);return o.getAll(s)}async getPendingCaptures(t={}){return(await(await this.openDB()).getAllFromIndex("pendingCaptures","sessionId",w)).filter(n=>!t.beforePresent||n.targetTimestamp<Date.now()).filter(n=>!t.isHeatmap||(n.captureParams.isHeatmap??!1))}async markPendingCaptureToCanUpload(t){const n=(await this.openDB()).transaction("pendingCaptures","readwrite");let a=await n.store.index("sessionId").openCursor(w);for(;a;){const r=a.value;r.captureParams.responseGroupId===t&&a.update({...r,canUpload:!0}),a=await a.continue()}await n.done}async markPendingHeatmapsReady(t){if(parseInt(y.getItem("sprig.pendingCount")??"0")===0)return null;const n=Date.now(),a=(await this.openDB()).transaction("pendingCaptures","readwrite");let r=await a.store.index("sessionId").openCursor(w);for(;r;){const o=r.value;o.captureParams.isHeatmap&&(!t||t.includes(o.uuid))&&r.update({...o,targetTimestamp:n,captureParams:{...o.captureParams,triggerTimestamp:n,replayParams:{...o.captureParams.replayParams,replayDurationSeconds:Math.floor((n-o.timestamp)/1e3)}}}),r=await r.continue()}await a.done}}const c=new Mt,Ot=async(e,t,n)=>new Promise((a,r)=>{const o=e.createElement("script");o.src=t,o.onload=a,o.onerror=r,n&&(o.nonce=n),e.head.appendChild(o)}),ke=async(e,t)=>{const n=performance.now();let a;try{a=await e()}finally{const r=performance.now()-n;let o=ae[t];o||(o=re(t)),o.report(r/1e3)}return a},Ce=(e,t)=>{const n=performance.now();try{e()}finally{const a=performance.now()-n;let r=ae[t];r||(r=re(t)),r.report(a/1e3)}};let J=5e3,U=6e4,z=0;const Ht=5,Ee=30,A=Ee+Ht;let C,Q=!1,X=[];const jt=async({viewDocument:e,maxReplayDurationSeconds:t,replayNonce:n,maxInflightRequests:a=2,replaySettings:r,teardownAfter:o=!1})=>{if(C=y.getItem("sprig.pendingCount"),!g.isRecording){if(o&&y.setItem("sprig.teardownAfterCapture","true"),S())return i("ReplayDisabled");if(await ft())return _("IDBNotSupported"),V();try{await c.openDB()}catch(s){return _(`ReplayError-${s.message}-${s.name}`),s.name==="VersionError"&&c.deleteDB(),V()}if(!t)return i("MissingReplaySeconds");i("ReplayInit"),await v(async()=>{if(r!=null&&r.minDuration&&(J=r.minDuration),r!=null&&r.batchDuration&&(U=r.batchDuration),Fe(a),zt(),Kt(t+A,30*60,t+A),Vt(),!window.rrwebRecord){const u=window.UserLeap.replayLibraryURL??"https://cdn.sprig.com/dependencies/record-2.0.0-alpha.6.min.js";await Ot(e,u,n)}const s=window.rrwebRecord;if(!s)return ne("RecordScriptFailed");let d=!0,l=0;g.stopRecording=s({checkoutEveryNms:Ee*1e3,sampling:{input:"last",scroll:250,media:800},emit:(u,p)=>{if(u.type===E.Custom&&(z=Date.now()),S())return;if(p&&u.type===E.Meta)l=performance.now();else if(p&&l&&u.type===E.FullSnapshot){const h=performance.now()-l;Oe("sdk_replay_snapshot_seconds",h/1e3)}const m=d||!!p&&u.type===E.Meta;d=!1,Ft({uuid:P(),event:JSON.stringify(u),isValidStart:m,timestamp:Date.now()})},...r}),g.isRecording=!!g.stopRecording,g.isRecording&&(x.on("survey.complete",u=>{Ct({id:u,userAgent:window.navigator.userAgent})}),gt())},"Error initializing replay")}},Ft=e=>{var t,n,a,r;if((t=e.event)!=null&&t.includes("Sprig_Scroll")){const o=(r=(a=(n=JSON.parse(e.event))==null?void 0:n.data)==null?void 0:a.payload)==null?void 0:r.xPath;if(!o)return;g.scrollEventUuids[o]=e.uuid}X.push(e),Q||Wt()},Gt=async e=>{const t=e.map(n=>({...n,sessionId:n.sessionId??w}));if(t.length!==0)return v(()=>c.bulkAdd("events",t),"Error storing replay events")},Wt=()=>{Q=!0,setTimeout(async()=>{if(S())return;const e=X;X=[],Q=!1,Ce(async()=>{await Gt(e)},"sdk_replay_add_event_batch_seconds")},500)},Kt=(e,t,n)=>{g.cleanupInterval=window.setInterval(()=>{const a=Date.now();S()||(B(`CleanUp Secs - Events: ${e}, Chunks: ${t}, Captures: ${n}`),ke(()=>v(async()=>{await Promise.all([c.deleteRowsBefore("events",a-e*1e3,r=>r.expiredAt===void 0||r.expiredAt<a-e*1e3),c.deleteRowsBefore("chunkUploads",a-t*1e3),c.deleteRowsBefore("pendingCaptures",a-n*1e3,r=>!r.canUpload)])},"Error deleting table rows"),"sdk_replay_cleanup_seconds"),i("Cleanup complete"))},3e4)},Vt=()=>{g.pendingCheckInterval=window.setInterval(async()=>{v(async()=>{const e=parseInt(C??"0");if(e===0)return;const t=await c.getPendingCaptures({beforePresent:!0}),n=await c.openDB();await Promise.all(t.map(async a=>(await n.delete("pendingCaptures",a.uuid),$e(a.captureParams,a.canUpload)))),C=(e-t.length).toString(),y.setItem("sprig.pendingCount",C)},"Error initiating pending captures")},5e3)},qt=async(e,t,n,a,r)=>{const o=Math.min(e+r,n),s=`from: ${new Date(e).toLocaleTimeString()} to ${new Date(o).toLocaleTimeString()}`;i(`Getting event batch ${s}`);const d=await ke(()=>c.getEventsBetween(e,o),"sdk_replay_get_events_between_seconds");if(!(d!=null&&d.length))return i(`No events found ${s}`),{validStartFound:a,events:[]};if(!a){i(`Searching for valid start in ${d.length} events ${s}`);let l=-1;if(d?.forEach((p,m)=>{if(!p.isValidStart)return;const h=p.timestamp<=t;(l<0||h)&&(l=m)}),l<0)return i(`No valid start found in ${d.length} events ${s}`),{validStartFound:a,events:[]};const u=d[l].timestamp;return i(`Found valid start at: ${new Date(u).toLocaleTimeString()} in events ${s}`),{validStartFound:!0,events:d?.slice(l)}}return{validStartFound:a,events:d}},Jt=(e,t,n)=>{const a=e.length,r=t*1024*1024,o=Math.ceil(a/n),s=Math.max(r,o);i(`Total file bytes: ${a} / target chunk size: ${s}`);const d=[];let l=0;for(;l<a;)d.push(e.slice(l,l+s)),l+=s;return d},Pe=e=>Promise.all(e.map(async t=>{const n=await Ge(t);return await c.updatePartial("chunkUploads",t.uuid,{data:null,etag:n,status:"UploadComplete"}),t.uploadId})),xe=async e=>{i(`Marking upload complete if finished: ${e}`);const t=await c.getChunkUploadsByStatus({status:"UploadComplete",uploadId:e});if(!(t!=null&&t.length)){i(`No finished chunks found for upload: ${e}`);return}const n=t.reduce((o,s)=>(o.find(d=>d.chunkIndex===s.chunkIndex)||o.push(s),o),[]);n.sort((o,s)=>o.chunkIndex-s.chunkIndex);const a=n.map(o=>({ETag:o.etag,PartNumber:o.chunkIndex})).filter(o=>o.ETag!==null),r=n[0];await se({apiUrl:r.apiUrl,surveyId:r.surveyId,uploadId:e,responseGroupUuid:r.responseGroupId,etags:a,headers:r.completeUploadHeaders,replayDuration:r.replayDuration}),i(`Cleaning up chunks for ${e}`),await c.deleteChunkUploads("UploadComplete",e),i(`Done cleaning up chunks for ${e}`)},zt=()=>{v(async()=>{const e=await c.getChunkUploadsByStatus({sessionId:w,status:"ReadyForUpload"});if(!(e!=null&&e.length))return;const t=await Pe(e);i(`Finished uploading unfinished chunks for ${t}`),t!=null&&t.length&&await Promise.all(t.map(n=>{if(n)return xe(n)}))},"Error uploading unfinished chunks")},Qt=async(e,t)=>{await Pe(t),i(`Done uploading chunks for uploads: ${e.join(",")}`),await Promise.all(e.map(n=>xe(n)))},Xt=e=>{let t=0;e.forEach(r=>{t+=r.length});const n=new Uint8Array(t);let a=0;return e.forEach(r=>{n.set(r,a),a+=r.length}),n},Be=async(e,t,n)=>{const a=new TextEncoder;let r=null,o=null,s=null,d=!1,l=!1,[u,p]=[0,0];const m=e-A*1e3,h=[];let f=[];i(`Getting events between ${new Date(e).toLocaleTimeString()} and ${new Date(t).toLocaleTimeString()}`),i(`Using batch duration: ${U}ms`);for(let N=m;N<t;N+=U){if({validStartFound:l,events:f}=await qt(N,e,t,l,U),!(f!=null&&f.length)){i("No events found");continue}u===0&&(u=f[0].timestamp),p=f[f.length-1].timestamp,i(`Last event time in batch: ${new Date(p).toLocaleTimeString()}`);const Y=f.map(Ne=>Ne.event);Y.push(`{"timestamp":${t}}`);const Ae=`${d?",":"["}${Y}`,Z=a.encode(Ae);n&&o===null&&(B("Attempting compression"),s=new window.CompressionStream("gzip"),o=s.writable.getWriter()),Ce(()=>{n&&o?o.write(Z):h.push(Z)},"sdk_replay_compression_seconds"),d=!0}if(p-u<J)return i(`Replay duration is shorter than minimum of ${J}ms / Start:${u} / End:${p}`),null;const D=a.encode("]");return B("Writing final close brace"),o&&s?(o.write(D),o.close(),r=new Uint8Array(await new Response(s.readable).arrayBuffer())):(h.push(D),r=Xt(h)),i("Finished generating file data"),r},Yt=async(e,t)=>{const n=window.CompressionStream!==void 0;let a=null;const r=t??Date.now(),o=r-e;try{a=await Be(o,r,n)}catch(s){s instanceof Error&&window.UserLeap.reportError("Error compressing replay",s),n&&v(async()=>{await Be(o,r,!1)},"fileData fallback failed")}return a},Re=async e=>{const{surveyId:t,responseGroupId:n,visitorId:a,apiUrl:r,completeUploadHeaders:o,replayParams:s,triggerTimestamp:d}=e,l=await Yt(s.replayDurationSeconds*1e3,d);if(l!=null&&l.length)i(`Found file data for survey: ${t}`);else{i(`File data is empty for survey: ${t}`);return}const u=Jt(l,s.minimumChunkSizeMb,s.signedUrls.length);i(`Got ${u.length} chunks for survey: ${t}`);const p=await Promise.all(u.map(async(m,h)=>{const f=P(),D={apiUrl:r,chunkIndex:h+1,completeUploadHeaders:o,etag:null,responseGroupId:n,status:"ReadyForUpload",surveyId:t,timestamp:d,totalChunks:u.length,data:m,uploadId:s.uploadId,uploadUrl:s.signedUrls[h].url,uuid:f,visitorId:a};return i(`Recording chunk upload: ${JSON.stringify({index:D.chunkIndex,surveyId:D.surveyId,uploadId:D.uploadId,size:m.length,id:f},null,2)}`),await(await c.openDB()).add("chunkUploads",{...D,sessionId:D.sessionId??w}),i(`Done creating chunk upload: ${f}`),D}));i(`All chunk records created. Beginning upload for survey: ${t}`),await Qt([s.uploadId],p)},$e=async(e,t)=>{if(i(`Attempting replay capture: ${JSON.stringify({isStandalone:e.isStandalone,duration:e.replayParams.replayDurationSeconds,type:e.replayParams.replayDurationType,responseGroupId:e.responseGroupId,surveyId:e.surveyId,triggerTimestamp:e.triggerTimestamp,visitorId:e.visitorId},null,2)}`),S())return i(`Replay recording is disabled: ${e.surveyId}`);i(`Replay recording enabled: ${e.surveyId}`);const{isHeatmap:n,isStandalone:a,replayParams:r,triggerTimestamp:o,responseGroupId:s}=e,d=async()=>{setTimeout(()=>x.removeListener(L.QuestionAnswered,d),0),v(async()=>{r.replayDurationType==="before"?await Re(e):await c.markPendingCaptureToCanUpload(s)},"Error in schedule/capture callback")};v(async()=>{if(r.replayDurationType==="after"||r.replayDurationType==="beforeAndAfter"){!a&&!n&&(i("Attaching QuestionAnswered listener for non-standalone replay"),x.on(L.QuestionAnswered,d)),i(`Scheduling capture for replay of type: ${r.replayDurationType}`),await Ue(e);return}if(a||n||t)i(`Proceeding to capture replay for survey: ${e.surveyId} / standalone? ${a} / canUpload? ${t}`),await Re(e),n&&Zt();else{const l=A+r.replayDurationSeconds,u=o-l*1e3,p=o;i(`Setting expiry minutes to ${r.expirationTimeLimitMinutes} for events from ${new Date(u).toLocaleTimeString()} to ${new Date(p).toLocaleTimeString()}`),await c.updateEventsExpiredAt(u,p,r.expirationTimeLimitMinutes),i("Attaching QuestionAnswered listener"),x.on(L.QuestionAnswered,d)}},"Error in scheduling/capturing replay")},Zt=async()=>{parseInt(C??"0")||y.removeItem("sprig.isCapturingHeatmap"),y.getItem("sprig.teardownAfterCapture")&&(Se(),Te(),y.removeItem("sprig.teardownAfterCapture"))},Te=async()=>S()?B("Not clearing user data, replay is disabled"):Promise.all([c.deleteBySessionId("events",w),c.deleteBySessionId("pendingCaptures",w)]).catch(e=>{T("Error clearing user replay data",e)}),Ue=async e=>{if(S())return;i(`Scheduling replay capture: ${JSON.stringify(e)}`);const{isHeatmap:t,surveyId:n}=e,a=await c.getPendingCaptures(),r=a?.filter(d=>d.captureParams.surveyId===n);if(r!=null&&r.length){i(`Pending capture exists for survey: ${n}`);return}t&&(Nt(),y.setItem("sprig.isCapturingHeatmap","true"),z=Date.now(),g.inactivityInterval||(g.inactivityInterval=window.setInterval(()=>{It(z)},1e3)));const o={...e,replayParams:{...e.replayParams}};e.replayParams.replayDurationType==="beforeAndAfter"&&(o.replayParams.replayDurationSeconds*=2),o.replayParams.replayDurationType="before";const s=e.triggerTimestamp+e.replayParams.replayDurationSeconds*1e3;o.triggerTimestamp=s,C=(parseInt(C??"0")+1).toString(),y.setItem("sprig.pendingCount",C),await(await c.openDB()).add("pendingCaptures",{canUpload:!1,captureParams:o,sessionId:w,targetTimestamp:s,timestamp:Date.now(),uuid:P()})},en=Object.freeze(Object.defineProperty({__proto__:null,RecordEvent:bt,RecordPageView:Dt,RecordSurveyShown:kt,_completeSessionReplay:_t,checkPendingHeatmapsUrl:vt,clearUserReplayData:Te,disableRecording:T,initializeReplay:jt,isReplayRecording:Rt,scheduleCapture:Ue,scheduleOrCaptureReplay:$e,tryReplayAction:v},Symbol.toStringTag,{value:"Module"}));He(en);
1
+ var Be=Object.defineProperty,Ue=(e,t,n)=>t in e?Be(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,z=(e,t,n)=>(Ue(e,typeof t!="symbol"?t+"":t,n),n);import{b as u,s as J,a as w,v as P,c as Te,P as Q,r as X,d as _e,e as x,S as _,f as Ae}from"./metricsReporter-FejRrxF4.js";var k=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(k||{});class Ne{constructor(t){z(this,"awaitingResolvers",[]),z(this,"activeCount",0),this.capacity=t}async acquire(){if(this.activeCount<this.capacity){this.activeCount++;return}return new Promise(t=>{this.awaitingResolvers.push(t)})}release(){const t=this.awaitingResolvers.shift();t&&this.activeCount<=this.capacity?t():this.activeCount--}async execute(t){try{return await this.acquire(),await t()}finally{this.release()}}setLimit(t){this.capacity=t}}const Y=new Ne(2),Le=e=>Y.setLimit(e),Me=async e=>Y.execute(async()=>{var t;u.info("UploadChunkStart",{chunkIndex:e.chunkIndex,surveyId:e.surveyId});const n=await J(e.uploadUrl,{body:e.data,method:"PUT"});u.http("UploadChunkEnd",{url:e.uploadUrl,method:"PUT",status_code:n.status,reason:n.statusText??"OK",chunkIndex:e.chunkIndex,surveyId:e.surveyId});const a=(t=n.headers)==null?void 0:t.get("ETag");if(!a)throw new Error(`Upload response did not include etag for upload ${e.uploadId}, part ${e.chunkIndex}`);return a}),Z=async({apiUrl:e,surveyId:t,uploadId:n,etags:a,headers:r,responseGroupUuid:o,replayDuration:s,eventDigest:d},i=!1)=>{var l;if(!i&&!n&&!a){u.error("UploadErr",{isMobile:i,uploadId:n,etags:a});return}u.info("MarkUploadComplete",{surveyId:t});const g=await J(`${e}/sdk/1/completeSessionReplay`,{method:"POST",body:JSON.stringify({etags:a,uploadId:n,responseGroupUuid:o,surveyId:t,replayDuration:s,eventDigest:d,userAgent:(l=window?.navigator)==null?void 0:l.userAgent}),headers:r,shouldRetryRequest:!0});return u.info("MarkUploadDone",{surveyId:t}),g},A=(e,t)=>t.some(n=>e instanceof n);let ee,te;function Oe(){return ee||(ee=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function He(){return te||(te=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const N=new WeakMap,L=new WeakMap,R=new WeakMap;function Fe(e){const t=new Promise((n,a)=>{const r=()=>{n(D(e.result))},o=()=>{a(e.error)};e.onsuccess=r,e.onerror=o});return R.set(t,e),t}function je(e){if(N.has(e))return;const t=new Promise((n,a)=>{const r=()=>{n()},o=()=>{a(e.error||new DOMException("AbortError","AbortError"))};e.oncomplete=r,e.onerror=o,e.onabort=o});N.set(e,t)}let M={get(e,t,n){if(e instanceof IDBTransaction){if(t==="done")return N.get(e);if(t==="store")return n.objectStoreNames[1]?void 0:n.objectStore(n.objectStoreNames[0])}return D(e[t])},set(e,t,n){return e[t]=n,!0},has(e,t){return e instanceof IDBTransaction&&(t==="done"||t==="store")?!0:t in e}};function ne(e){M=e(M)}function Ve(e){return He().includes(e)?function(...t){return e.apply(O(this),t),D(this.request)}:function(...t){return D(e.apply(O(this),t))}}function Ke(e){return typeof e=="function"?Ve(e):(e instanceof IDBTransaction&&je(e),A(e,Oe())?new Proxy(e,M):e)}function D(e){if(e instanceof IDBRequest)return Fe(e);if(L.has(e))return L.get(e);const t=Ke(e);return t!==e&&(L.set(e,t),R.set(t,e)),t}const O=e=>R.get(e);function Ge(e,t,{blocked:n,upgrade:a,blocking:r,terminated:o}={}){const s=indexedDB.open(e,t),d=D(s);return a&&(s.onupgradeneeded=i=>{a(D(s.result),i.oldVersion,i.newVersion,D(s.transaction),i)}),n&&(s.onblocked=i=>n(i.oldVersion,i.newVersion,i)),d.then(i=>{o&&(i.onclose=()=>o()),r&&(i.onversionchange=l=>r(l.oldVersion,l.newVersion,l))}).catch(()=>{}),d}function H(e,{blocked:t}={}){const n=indexedDB.deleteDatabase(e);return t&&(n.onblocked=a=>t(a.oldVersion,a)),D(n).then(()=>{})}const We=["get","getKey","getAll","getAllKeys","count"],$e=["put","add","delete","clear"],F=new Map;function ae(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&typeof t=="string"))return;if(F.get(t))return F.get(t);const n=t.replace(/FromIndex$/,""),a=t!==n,r=$e.includes(n);if(!(n in(a?IDBIndex:IDBObjectStore).prototype)||!(r||We.includes(n)))return;const o=async function(s,...d){const i=this.transaction(s,r?"readwrite":"readonly");let l=i.store;return a&&(l=l.index(d.shift())),(await Promise.all([l[n](...d),r&&i.done]))[0]};return F.set(t,o),o}ne(e=>({...e,get:(t,n,a)=>ae(t,n)||e.get(t,n,a),has:(t,n)=>!!ae(t,n)||e.has(t,n)}));const qe=["continue","continuePrimaryKey","advance"],re={},j=new WeakMap,oe=new WeakMap,ze={get(e,t){if(!qe.includes(t))return e[t];let n=re[t];return n||(n=re[t]=function(...a){j.set(this,oe.get(this)[t](...a))}),n}};async function*Je(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;t=t;const n=new Proxy(t,ze);for(oe.set(n,t),R.set(n,O(t));t;)yield n,t=await(j.get(n)||t.continue()),j.delete(n)}function se(e,t){return t===Symbol.asyncIterator&&A(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&A(e,[IDBIndex,IDBObjectStore])}ne(e=>({...e,get(t,n,a){return se(t,n)?Je:e.get(t,n,a)},has(t,n){return se(t,n)||e.has(t,n)}}));const Qe=e=>{if(e instanceof Attr)return null;let t=1;for(let n=e.previousSibling;n;n=n.previousSibling)n.nodeName===e.nodeName&&++t;return t},ie=e=>{if(e===null)return"";const t=[];if(e instanceof Document)return"/";for(let n=e;n&&!(n instanceof Document)&&n!==null;n=n instanceof Attr?n.ownerElement:n.parentElement){const a=t[t.length]={name:void 0,position:null};switch(n.nodeType){case Node.TEXT_NODE:a.name="text()";break;case Node.ATTRIBUTE_NODE:a.name="@"+n.nodeName;break;case Node.PROCESSING_INSTRUCTION_NODE:a.name="processing-instruction()";break;case Node.COMMENT_NODE:a.name="comment()";break;case Node.ELEMENT_NODE:a.name=n.nodeName;break}a.position=Qe(n)}return"/"+t.reverse().map(n=>n.position!==null?`/${n.name}[${n.position}]`:`/${n.name}`).join("")},S={capture:!0,passive:!0},Xe=["a","button","input","option","li","link"],Ye=["Escape","Enter","Backspace","F5","Tab"];let B=!1;const Ze=["label","type","role","title","placeholder","errormessage","valuetext","href"],de="aria-",et=e=>{if(!e.tagName)return"No tagName";const t=e.getAttribute("type");return t?`${t} ${e.tagName.toLowerCase()}`:e.tagName.toLowerCase()},le=e=>{var t;if(((t=e.tagName)==null?void 0:t.toLowerCase())==="html")return{element:"html"};const n=e.textContent,a=n?{text:n}:{};a.element=et(e);for(const r of e.attributes){let o=r.name;const s=r.value;o.startsWith(de)&&(o=o.substring(de.length)),Ze.includes(o)&&(a[o]=s)}return a},tt=e=>{var t;if(!e)return{};const n={...le(e)},a=e.parentElement;if(a&&Xe.includes((t=a.tagName)==null?void 0:t.toLowerCase())){const r=le(a);Object.assign(n,r)}return n},ue=(e,t)=>{var n;yt({x:t.x,y:t.y,type:e,elementAttributes:tt(t.target),windowHeight:window.innerHeight,windowWidth:window.innerWidth,...t.target instanceof HTMLElement?{rect:(n=t.target)==null?void 0:n.getBoundingClientRect(),xPath:ie(t.target)}:{}})},nt=e=>t=>ue(e,t),ce=e=>{Ye.includes(e.key)&&Dt({key:e.key})},at=()=>{window.performance.getEntriesByType("navigation").map(e=>e.type).includes("reload")&&It({url:window.location.href,currentPageTitle:document.title})},rt=()=>{window.performance.getEntriesByType("navigation").map(e=>e.type).includes("back_forward")&&bt({curUrl:window.location.href,fromUrl:document.referrer,currentPageTitle:document.title})},ot=(e,t)=>{let n;return a=>{clearTimeout(n),n=window.setTimeout(()=>e(a),t)}},st=e=>{if(!(e.target instanceof HTMLElement||e.target instanceof Document))return;let t=e.target;"scrollTop"in t||(t=t.documentElement),St({xPath:ie(t),x:t.scrollLeft,y:t.scrollTop,elementAttributes:{targetScrollWidth:t.scrollWidth,targetClientWidth:t.clientWidth,targetScrollHeight:t.scrollHeight,targetClientHeight:t.clientHeight}})},pe=ot(st,750),ge=nt("left_click"),me=e=>{e.button===2&&ue("right_click",e)},it=()=>{B||(window.addEventListener("click",ge,S),window.addEventListener("mousedown",me,S),window.addEventListener("keydown",ce,S),window.addEventListener("scroll",pe,S),B=!0,at(),rt())},dt=()=>{B&&(window.removeEventListener("click",ge,S),window.removeEventListener("mousedown",me,S),window.removeEventListener("keydown",ce,S),window.removeEventListener("scroll",pe,S),B=!1)},lt=3e4,p={isRecording:!1,scrollEventUuids:{},stopRecording:()=>{}},ut=.5,ct=async()=>{var e;if(!window.indexedDB||!window.IDBKeyRange||!window.CompressionStream)return!0;if((e=window.navigator.storage)!=null&&e.estimate)try{const{quota:t=0,usage:n=0}=await window.navigator.storage.estimate(),a=(t-n)/1024**3;return u.info("Storage",{availableGb:a}),a<ut}catch{return!0}return!1},pt=()=>{const e=w.getItem("sprig.sessionId");if(e)return u.info("SessionIDFound",{savedSessionId:e}),w.removeItem("sprig.sessionId"),e;const t=P();return u.info("GeneratedSessionID",{uuid:t}),t},y=pt(),V=()=>{w.setItem("sprig.disableReplayRecording","disabled")},v=()=>!!w.getItem("sprig.disableReplayRecording");window.addEventListener("beforeunload",()=>{u.info("BeforeUnload",{sessionId:y}),w.setItem("sprig.sessionId",y)});const gt=()=>v()?u.debug("ReplayDisabled-PendingHeatmaps"):f(async()=>{const e=(await c.getPendingCaptures({isHeatmap:!0})).map(n=>({eventId:n.captureParams.eventId,uuid:n.uuid})),t=[];e.forEach(({eventId:n,uuid:a})=>{Te(n)||t.push(a)}),t.length&&await c.markPendingHeatmapsReady(t)},"Error marking pending heatmaps ready"),mt=e=>{Date.now()-e>=lt&&f(()=>c.markPendingHeatmapsReady(),"Error in heatmap inactivity")},K=e=>e&&e.trim().substring(0,500).replace(/\s\s+/g," ").replace(/\r?\n|\r/g," ").substring(0,250),h=(e,t)=>{var n,a;if(!(v()||!p.isRecording))try{(a=(n=window.rrwebRecord)==null?void 0:n.addCustomEvent)==null||a.call(n,e,t)}catch(r){U("Error recording custom event",r)}},wt=e=>{e.description&&(e.description=K(e.description)),h("Sprig_PageView",e)},yt=e=>{var t;(t=e?.elementAttributes)!=null&&t.text&&(e.elementAttributes.text=K(e.elementAttributes.text)),h("Sprig_Click",e)},ft=e=>{h("Sprig_TrackEvent",e)},vt=e=>{h("Sprig_ShowSurvey",e)},ht=e=>{h("Sprig_SubmitSurvey",e)},It=e=>{h("Sprig_Refresh",e)},bt=e=>{e.currentPageTitle&&(e.currentPageTitle=K(e.currentPageTitle)),h("Sprig_BackForward",e)},Dt=e=>{h("Sprig_Keystroke",e)},St=async e=>{const{x:t,xPath:n,y:a}=e,r=p.scrollEventUuids[n];if(r)return f(async()=>{var o,s,d,i;const l=await c.openDB(),g=await l.get("events",r);if(g!=null&&g.event){const m=JSON.parse(g.event),I=t>((s=(o=m.data)==null?void 0:o.payload)==null?void 0:s.x),b=a>((i=(d=m.data)==null?void 0:d.payload)==null?void 0:i.y);if(!(I||b))return null;I&&(m.data.payload.x=t),b&&(m.data.payload.y=a),m.data.payload.elementAttributes=e.elementAttributes,g.event=JSON.stringify(m),await l.put("events",g)}else h("Sprig_Scroll",e)},"Error updating scroll event");h("Sprig_Scroll",e)},Ct=()=>p.isRecording,we=()=>{p.stopRecording&&(p.stopRecording(),p.stopRecording=void 0),p.isRecording=!1,["cleanupInterval","inactivityInterval","pendingCheckInterval"].forEach(e=>{p[e]&&(clearInterval(p[e]),p[e]=void 0)}),dt()},Et=["did not allow mutations","called in an invalid security context"],kt=e=>{if(!e)return!0;for(const t of Et)if(e.toLowerCase().includes(t))return!1;return!0},Pt=(e,t,{reportError:n=!0,extraInfo:a})=>{if(!v()&&t instanceof Error){if(V(),t.name==="VersionError")return u.error("VersionErr",{message:e}),c.deleteDB();kt(t?.message)&&(n&&window.UserLeap.reportError(e,t,a),c.clearAll())}},xt=async(e,t,{reportError:n}={reportError:!0})=>{let a={};try{const{quota:r=0,usage:o=0}=await window.navigator.storage.estimate();a={availableSpaceInMB:(r-o)/2**20,quota:r,usage:o}}catch{a.availableSpaceInMB=null}Pt(e,t,{reportError:n,extraInfo:a})},U=(e,t,{reportError:n}={reportError:!0})=>(we(),u.error("ReplayErr",{code:t.code,name:t.name}),xt(e,t,{reportError:n})),f=async(e,t)=>{try{await e()}catch(n){U(t,n)}},Rt=()=>{p.isRecording&&f(()=>{var e,t;return(t=(e=window.rrwebRecord)==null?void 0:e.takeFullSnapshot)==null?void 0:t.call(e,!0)},"Error recording full snapshot")},Bt=async({surveyId:e,responseGroupUuid:t,eventDigest:n,headers:a})=>{if(!e||!t)return!1;const r=window.UserLeap._API_URL,o=await Z({surveyId:e,responseGroupUuid:t,eventDigest:n,apiUrl:r,headers:a},!0);return!(o!=null&&o.error)},ye=30,Ut=1;H("replayStorage").catch(console.error),H("sprig.replay").catch(console.error);class Tt{openDB(){return Ge("sprigReplay",Ut,{upgrade:(t,n,a)=>{if(a===0&&w.setItem("sprig.pendingCount","0"),!t.objectStoreNames.contains("events")){const r=t.createObjectStore("events",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+timestamp]",["sessionId","timestamp"])}if(!t.objectStoreNames.contains("chunkUploads")){const r=t.createObjectStore("chunkUploads",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+status]",["sessionId","status"]),r.createIndex("[uploadId+status]",["uploadId","status"]),r.createIndex("[sessionId+status+uploadId]",["sessionId","status","uploadId"])}if(!t.objectStoreNames.contains("pendingCaptures")){const r=t.createObjectStore("pendingCaptures",{keyPath:"uuid"});r.createIndex("sessionId","sessionId"),r.createIndex("timestamp","timestamp"),r.createIndex("[sessionId+targetTimestamp]",["sessionId","targetTimestamp"])}}})}deleteDB(){return H("sprigReplay").catch(console.error)}async bulkAdd(t,n){const a=(await this.openDB()).transaction(t,"readwrite");return Promise.all([...n.map(r=>a.store.add(r)),a.done])}async clearAll(){const t=(await this.openDB()).transaction(["events","chunkUploads","pendingCaptures"],"readwrite");return Promise.all([t.objectStore("events").clear(),t.objectStore("chunkUploads").clear(),t.objectStore("pendingCaptures").clear()])}async deleteBySessionId(t,n){const a=IDBKeyRange.only(n),r=(await this.openDB()).transaction(t,"readwrite"),o=r.store.index("sessionId");for await(const s of o.iterate(a))await s.delete();await r.done}async updatePartial(t,n,a){const r=(await this.openDB()).transaction(t,"readwrite"),o=await r.store.get(n);o&&await r.store.put({...o,...a}),await r.done}async deleteRowsBefore(t,n,a=()=>!0){const r=IDBKeyRange.upperBound(n,!0),o=(await this.openDB()).transaction(t,"readwrite"),s=o.store.index("timestamp");for await(const d of s.iterate(r))a(d.value)&&await d.delete();await o.done}async getEventsBetween(t,n=Date.now()){if(t>=n)return Promise.resolve([]);const a=IDBKeyRange.bound([y,t],[y,n],!1,!0);return(await this.openDB()).getAllFromIndex("events","[sessionId+timestamp]",a)}async updateEventsExpiredAt(t,n,a=ye){const r=new Date,o=r.setMinutes(r.getMinutes()+(a??ye)),s=(await this.openDB()).transaction("events","readwrite"),d=s.store.index("[sessionId+timestamp]"),i=IDBKeyRange.bound([y,t],[y,n],!1,!0);for await(const l of d.iterate(i))await l.update({...l.value,expiredAt:o});await s.done}async deleteChunkUploads(t,n){const a=IDBKeyRange.only([n,t]),r=(await this.openDB()).transaction("chunkUploads","readwrite");let o=await r.store.index("[uploadId+status]").openCursor(a);for(;o;)o.delete(),o=await o.continue();await r.done}async getChunkUploadsByStatus({sessionId:t,status:n,uploadId:a}){const r=(await this.openDB()).transaction("chunkUploads","readonly"),o=a?r.store.index("[uploadId+status]"):r.store.index("[sessionId+status]"),s=a?IDBKeyRange.only([a,n]):IDBKeyRange.only([t,n]);return o.getAll(s)}async getPendingCaptures(t={}){return(await(await this.openDB()).getAllFromIndex("pendingCaptures","sessionId",y)).filter(n=>!t.beforePresent||n.targetTimestamp<Date.now()).filter(n=>!t.isHeatmap||(n.captureParams.isHeatmap??!1))}async markPendingCaptureToCanUpload(t){const n=(await this.openDB()).transaction("pendingCaptures","readwrite"),a=n.store.index("sessionId");for await(const r of a.iterate(y)){const o=r.value;o.captureParams.responseGroupId===t&&await r.update({...o,canUpload:!0})}await n.done}async markPendingHeatmapsReady(t){if(parseInt(w.getItem("sprig.pendingCount")??"0")===0)return null;const n=Date.now(),a=(await this.openDB()).transaction("pendingCaptures","readwrite"),r=a.store.index("sessionId");for await(const o of r.iterate(y)){const s=o.value;s.captureParams.isHeatmap&&(!t||t.includes(s.uuid))&&await o.update({...s,targetTimestamp:n,captureParams:{...s.captureParams,triggerTimestamp:n,replayParams:{...s.captureParams.replayParams,replayDurationSeconds:Math.floor((n-s.timestamp)/1e3)}}})}await a.done}}const c=new Tt,_t=async(e,t,n)=>new Promise((a,r)=>{const o=e.createElement("script");o.src=t,o.onload=a,o.onerror=r,n&&(o.nonce=n),e.head.appendChild(o)}),fe=async(e,t)=>{const n=performance.now();let a;try{a=await e()}finally{const r=performance.now()-n;let o=Q[t];o||(o=X(t)),o.report(r/1e3)}return a},ve=(e,t)=>{const n=performance.now();try{e()}finally{const a=performance.now()-n;let r=Q[t];r||(r=X(t)),r.report(a/1e3)}};let he=5e3,G=6e4,W=0;const At=5,Ie=30,T=Ie+At;let C,$=!1,q=[];const Nt=async({viewDocument:e,maxReplayDurationSeconds:t,replayNonce:n,maxInflightRequests:a=2,replaySettings:r,teardownAfter:o=!1})=>{if(C=w.getItem("sprig.pendingCount"),!p.isRecording){if(o&&w.setItem("sprig.teardownAfterCapture","true"),v())return u.debug("ReplayDisabled");if(await ct())return u.debug("IDBNotSupported"),V();try{const s=await c.openDB();u.info("DBVersion",{version:s.version})}catch(s){return u.error("ReplayOpenErr",{name:s.name}),s.name==="VersionError"&&c.deleteDB(),V()}if(!t)return u.debug("MissingDuration");u.debug("ReplayInit"),await f(async()=>{if(r!=null&&r.minDuration&&(he=r.minDuration),r!=null&&r.batchDuration&&(G=r.batchDuration),Le(a),Kt(),Ht(t+T,30*60,t+T),Ft(),!window.rrwebRecord){const l=window.UserLeap.replayLibraryURL??"https://cdn.sprig.com/dependencies/record-2.0.0-alpha.6.min.js";await _t(e,l,n)}const s=window.rrwebRecord;if(!s)return u.error("RecordScriptFailed");let d=!0,i=0;p.stopRecording=s({checkoutEveryNms:Ie*1e3,sampling:{input:"last",scroll:250,media:800},emit:(l,g)=>{if(l.type===k.Custom&&(W=Date.now()),v())return;if(g&&l.type===k.Meta)i=performance.now();else if(g&&i&&l.type===k.FullSnapshot){const I=performance.now()-i;_e("sdk_replay_snapshot_seconds",I/1e3)}const m=d||!!g&&l.type===k.Meta;d=!1,Lt({uuid:P(),event:JSON.stringify(l),isValidStart:m,timestamp:Date.now()})},...r}),p.isRecording=!!p.stopRecording,p.isRecording&&(x.on("survey.complete",l=>{ht({id:l,userAgent:window.navigator.userAgent})}),it())},"Error initializing replay")}},Lt=e=>{var t,n,a,r;if((t=e.event)!=null&&t.includes("Sprig_Scroll")){const o=(r=(a=(n=JSON.parse(e.event))==null?void 0:n.data)==null?void 0:a.payload)==null?void 0:r.xPath;if(!o)return;p.scrollEventUuids[o]=e.uuid}q.push(e),$||Ot()},Mt=async e=>{const t=e.map(n=>({...n,sessionId:n.sessionId??y}));if(t.length!==0)return f(()=>c.bulkAdd("events",t),"Error storing replay events")},Ot=()=>{$=!0,setTimeout(async()=>{if(v())return;const e=q;q=[],$=!1,ve(async()=>{await Mt(e)},"sdk_replay_add_event_batch_seconds")},500)},Ht=(e,t,n)=>{p.cleanupInterval=window.setInterval(()=>{const a=Date.now();fe(()=>f(async()=>{v()||await Promise.all([c.deleteRowsBefore("events",a-e*1e3,r=>r.expiredAt===void 0||r.expiredAt<a-e*1e3),c.deleteRowsBefore("chunkUploads",a-t*1e3),c.deleteRowsBefore("pendingCaptures",a-n*1e3,r=>!r.canUpload)])},"Error deleting table rows"),"sdk_replay_cleanup_seconds"),u.debug("CleanupComplete")},3e4)},Ft=()=>{p.pendingCheckInterval=window.setInterval(async()=>{f(async()=>{const e=parseInt(C??"0");if(e===0)return;const t=await c.getPendingCaptures({beforePresent:!0}),n=await c.openDB();await Promise.all(t.map(async a=>(await n.delete("pendingCaptures",a.uuid),Ce(a.captureParams,a.canUpload)))),C=(e-t.length).toString(),w.setItem("sprig.pendingCount",C)},"Error initiating pending captures")},5e3)},jt=async(e,t,n,a,r)=>{const o=Math.min(e+r,n),s=await fe(()=>c.getEventsBetween(e,o),"sdk_replay_get_events_between_seconds");if(!(s!=null&&s.length))return u.debug("NoEventsFound"),{validStartFound:a,events:[]};if(!a){u.debug("ValidStartSearch");let d=-1;return s?.forEach((i,l)=>{if(!i.isValidStart)return;const g=i.timestamp<=t;(d<0||g)&&(d=l)}),d<0?(u.debug("ValidStartNotFound"),{validStartFound:a,events:[]}):{validStartFound:!0,events:s?.slice(d)}}return{validStartFound:a,events:s}},Vt=(e,t,n)=>{const a=e.length,r=t*1024*1024,o=Math.ceil(a/n),s=Math.max(r,o),d=[];let i=0;for(;i<a;)d.push(e.slice(i,i+s)),i+=s;return d},be=e=>Promise.all(e.map(async t=>{const n=await Me(t);return await c.updatePartial("chunkUploads",t.uuid,{data:null,etag:n,status:"UploadComplete"}),t.uploadId})),De=async e=>{const t=await c.getChunkUploadsByStatus({status:"UploadComplete",uploadId:e});if(!(t!=null&&t.length)){u.info("NoChunksForUpload",{uploadId:e});return}const n=t.reduce((o,s)=>(o.find(d=>d.chunkIndex===s.chunkIndex)||o.push(s),o),[]);n.sort((o,s)=>o.chunkIndex-s.chunkIndex);const a=n.map(o=>({ETag:o.etag,PartNumber:o.chunkIndex})).filter(o=>o.ETag!==null),r=n[0];await Z({apiUrl:r.apiUrl,surveyId:r.surveyId,uploadId:e,responseGroupUuid:r.responseGroupId,etags:a,headers:r.completeUploadHeaders,replayDuration:r.replayDuration}),await c.deleteChunkUploads("UploadComplete",e)},Kt=()=>{f(async()=>{const e=await c.getChunkUploadsByStatus({sessionId:y,status:"ReadyForUpload"});if(!(e!=null&&e.length))return;const t=await be(e);t!=null&&t.length&&await Promise.all(t.map(n=>{if(n)return De(n)}))},"Error uploading unfinished chunks")},Gt=async(e,t)=>{await be(t),await Promise.all(e.map(n=>De(n)))},Wt=async(e,t)=>{const n=new TextEncoder;let a=null;const r=new CompressionStream("gzip"),o=r.writable.getWriter();let s=!1,d=!1,[i,l]=[0,0];const g=e-T*1e3;let m=[];for(let b=g;b<t;b+=G){if({validStartFound:d,events:m}=await jt(b,e,t,d,G),!(m!=null&&m.length)){u.debug("NoEventsFound");continue}i===0&&(i=m[0].timestamp),l=m[m.length-1].timestamp;const E=m.map(Re=>Re.event);E.push(`{"timestamp":${t}}`);const Pe=`${s?",":"["}${E}`,xe=n.encode(Pe);ve(()=>{o.write(xe)},"sdk_replay_compression_seconds"),s=!0}if(l-i<he)return u.debug("ReplayTooShort"),null;const I=n.encode("]");return o.write(I),o.close(),a=new Uint8Array(await new Response(r.readable).arrayBuffer()),a},$t=async(e,t)=>{const n=t??Date.now(),a=n-e;return Wt(a,n)},Se=async e=>{const{surveyId:t,responseGroupId:n,visitorId:a,apiUrl:r,completeUploadHeaders:o,replayParams:s,triggerTimestamp:d}=e,i=await $t(s.replayDurationSeconds*1e3,d);if(!(i!=null&&i.length)){u.info("FileDataEmpty",{surveyId:t});return}const l=Vt(i,s.minimumChunkSizeMb,s.signedUrls.length),g=await Promise.all(l.map(async(m,I)=>{const b=P(),E={apiUrl:r,chunkIndex:I+1,completeUploadHeaders:o,etag:null,responseGroupId:n,status:"ReadyForUpload",surveyId:t,timestamp:d,totalChunks:l.length,data:m,uploadId:s.uploadId,uploadUrl:s.signedUrls[I].url,uuid:b,visitorId:a};return await(await c.openDB()).add("chunkUploads",{...E,sessionId:E.sessionId??y}),E}));await Gt([s.uploadId],g)},Ce=async(e,t)=>{if(v())return u.debug("ReplayDisabled-ScheduleOrCapture");const{isHeatmap:n,isStandalone:a,replayParams:r,triggerTimestamp:o,responseGroupId:s}=e,d=async()=>{setTimeout(()=>x.removeListener(_.QuestionAnswered,d),0),f(async()=>{r.replayDurationType==="before"?await Se(e):await c.markPendingCaptureToCanUpload(s)},"Error in schedule/capture callback")};f(async()=>{if(r.replayDurationType==="after"||r.replayDurationType==="beforeAndAfter"){!a&&!n&&x.on(_.QuestionAnswered,d),await ke(e);return}if(a||n||t)await Se(e),n&&qt();else{const i=T+r.replayDurationSeconds,l=o-i*1e3,g=o;await c.updateEventsExpiredAt(l,g,r.expirationTimeLimitMinutes),x.on(_.QuestionAnswered,d)}},"Error in scheduling/capturing replay")},qt=async()=>{parseInt(C??"0")||w.removeItem("sprig.isCapturingHeatmap"),w.getItem("sprig.teardownAfterCapture")&&(we(),Ee(),w.removeItem("sprig.teardownAfterCapture"))},Ee=async()=>v()?u.debug("ReplayDisabled-ClearData"):Promise.all([c.deleteBySessionId("events",y),c.deleteBySessionId("pendingCaptures",y)]).catch(e=>{U("Error clearing user replay data",e)}),ke=async e=>{if(v())return;const{isHeatmap:t,surveyId:n}=e,a=await c.getPendingCaptures(),r=a?.filter(d=>d.captureParams.surveyId===n);if(r!=null&&r.length){u.info("PendingCaptureExists",{surveyId:n});return}t&&(Rt(),w.setItem("sprig.isCapturingHeatmap","true"),W=Date.now(),p.inactivityInterval||(p.inactivityInterval=window.setInterval(()=>{mt(W)},1e3)));const o={...e,replayParams:{...e.replayParams}};e.replayParams.replayDurationType==="beforeAndAfter"&&(o.replayParams.replayDurationSeconds*=2),o.replayParams.replayDurationType="before";const s=e.triggerTimestamp+e.replayParams.replayDurationSeconds*1e3;o.triggerTimestamp=s,C=(parseInt(C??"0")+1).toString(),w.setItem("sprig.pendingCount",C),await(await c.openDB()).add("pendingCaptures",{canUpload:!1,captureParams:o,sessionId:y,targetTimestamp:s,timestamp:Date.now(),uuid:P()})},zt=Object.freeze(Object.defineProperty({__proto__:null,RecordEvent:ft,RecordPageView:wt,RecordSurveyShown:vt,_completeSessionReplay:Bt,checkPendingHeatmapsUrl:gt,clearUserReplayData:Ee,disableRecording:U,initializeReplay:Nt,isReplayRecording:Ct,scheduleCapture:ke,scheduleOrCaptureReplay:Ce,tryReplayAction:f},Symbol.toStringTag,{value:"Module"}));Ae(zt);